]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
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);