Add caching of query to GIN/GiST consistent function.
authorTeodor Sigaev <teodor@sigaev.ru>
Fri, 11 Jul 2008 11:56:48 +0000 (11:56 +0000)
committerTeodor Sigaev <teodor@sigaev.ru>
Fri, 11 Jul 2008 11:56:48 +0000 (11:56 +0000)
Per performance gripe from nomao.com

contrib/pg_trgm/trgm_gin.c
contrib/pg_trgm/trgm_gist.c

index 82ac2b41c1c96fdb5fbe851f27cd3dc1e8c7a835..7f8bda7207b61d3378fd24affc0a3fc831166aea 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/pg_trgm/trgm_gin.c,v 1.4 2008/05/17 01:28:21 adunstan Exp $ 
+ * $PostgreSQL: pgsql/contrib/pg_trgm/trgm_gin.c,v 1.5 2008/07/11 11:56:48 teodor Exp $ 
  */
 #include "trgm.h"
 
@@ -52,6 +52,16 @@ gin_extract_trgm(PG_FUNCTION_ARGS)
    PG_RETURN_POINTER(entries);
 }
 
+/*
+ * Per call strage for consistent functions to
+ * cache computed value from query
+ */
+typedef struct PerCallConsistentStorage {
+   int     trglen;
+   text    data[1]; /* query */
+} PerCallConsistentStorage;
+#define PCCSHDR_SZ  offsetof(PerCallConsistentStorage, data)
+
 Datum
 gin_trgm_consistent(PG_FUNCTION_ARGS)
 {
@@ -60,16 +70,30 @@ gin_trgm_consistent(PG_FUNCTION_ARGS)
    text       *query = PG_GETARG_TEXT_P(2);
    bool       *recheck = (bool *) PG_GETARG_POINTER(3);
    bool        res = FALSE;
-   TRGM       *trg;
    int4        i,
                trglen,
                ntrue = 0;
+   PerCallConsistentStorage  *pccs = (PerCallConsistentStorage*) fcinfo->flinfo->fn_extra;
 
    /* All cases served by this function are inexact */
    *recheck = true;
 
-   trg = generate_trgm(VARDATA(query), VARSIZE(query) - VARHDRSZ);
-   trglen = ARRNELEM(trg);
+   if ( pccs == NULL || VARSIZE(pccs->data) != VARSIZE(query) || memcmp( pccs->data, query, VARSIZE(query) ) !=0  )
+   {
+       TRGM       *trg = generate_trgm(VARDATA(query), VARSIZE(query) - VARHDRSZ);
+
+       if ( pccs )
+           pfree(pccs);
+
+       fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, 
+                                   VARSIZE(query) + PCCSHDR_SZ);
+       pccs = (PerCallConsistentStorage*) fcinfo->flinfo->fn_extra;
+
+       pccs->trglen = ARRNELEM(trg);
+       memcpy( pccs->data, query, VARSIZE(query) );
+   }
+
+   trglen = pccs->trglen;
 
    for (i = 0; i < trglen; i++)
        if (check[i])
index 7baf4fd6978095fda20da8b04a991c0d9cc4167e..2720d7fb707a7af989de04421f2673dda55b9002 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/pg_trgm/trgm_gist.c,v 1.14 2008/05/17 01:28:21 adunstan Exp $ 
+ * $PostgreSQL: pgsql/contrib/pg_trgm/trgm_gist.c,v 1.15 2008/07/11 11:56:48 teodor Exp $ 
  */
 #include "trgm.h"
 
@@ -168,12 +168,30 @@ gtrgm_consistent(PG_FUNCTION_ARGS)
    /* Oid      subtype = PG_GETARG_OID(3); */
    bool       *recheck = (bool *) PG_GETARG_POINTER(4);
    TRGM       *key = (TRGM *) DatumGetPointer(entry->key);
-   TRGM       *qtrg = generate_trgm(VARDATA(query), VARSIZE(query) - VARHDRSZ);
+   TRGM       *qtrg;
    bool        res = false;
+   char        *cache  = (char*) fcinfo->flinfo->fn_extra;
 
    /* All cases served by this function are exact */
    *recheck = false;
 
+   if ( cache == NULL || VARSIZE(cache) != VARSIZE(query) || memcmp( cache, query, VARSIZE(query) ) !=0  )
+   {
+       qtrg = generate_trgm(VARDATA(query), VARSIZE(query) - VARHDRSZ);    
+
+       if (cache)
+           pfree(cache);
+
+       fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
+                           MAXALIGN(VARSIZE(query)) + VARSIZE(qtrg) );
+       cache = (char*) fcinfo->flinfo->fn_extra;
+
+       memcpy( cache, query, VARSIZE(query) );
+       memcpy( cache + MAXALIGN(VARSIZE(query)), qtrg, VARSIZE(qtrg) );
+   }
+
+   qtrg = (TRGM*)( cache + MAXALIGN(VARSIZE(query)) );
+
    if (GIST_LEAF(entry))
    {                           /* all leafs contains orig trgm */
        float4      tmpsml = cnt_sml(key, qtrg);