]> granicus.if.org Git - postgresql/commitdiff
Optimize SP-GiST insertions.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 29 Aug 2012 06:14:08 +0000 (09:14 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 29 Aug 2012 06:21:20 +0000 (09:21 +0300)
This includes two micro-optimizations to the tight inner loop in descending
the SP-GiST tree: 1. avoid an extra function call to index_getprocinfo when
calling user-defined choose function, and 2. avoid a useless palloc+pfree
when node labels are not used.

src/backend/access/spgist/spgdoinsert.c
src/backend/access/spgist/spgutils.c

index b3f8f6a231372fb1f4b6e2c1d42f124b2ca215cb..36d05703629b3221ea7a357d81e7d71149048e68 100644 (file)
@@ -1861,6 +1861,14 @@ spgdoinsert(Relation index, SpGistState *state,
        int                     leafSize;
        SPPageDesc      current,
                                parent;
+       FmgrInfo   *procinfo = NULL;
+
+       /*
+        * Look up FmgrInfo of the user-defined choose function once, to save
+        * cycles in the loop below.
+        */
+       if (!isnull)
+               procinfo = index_getprocinfo(index, 1, SPGIST_CHOOSE_PROC);
 
        /*
         * Since we don't use index_form_tuple in this AM, we have to make sure
@@ -2007,7 +2015,6 @@ spgdoinsert(Relation index, SpGistState *state,
                        SpGistInnerTuple innerTuple;
                        spgChooseIn in;
                        spgChooseOut out;
-                       FmgrInfo   *procinfo;
 
                        /*
                         * spgAddNode and spgSplitTuple cases will loop back to here to
@@ -2035,7 +2042,6 @@ spgdoinsert(Relation index, SpGistState *state,
                        if (!isnull)
                        {
                                /* use user-defined choose method */
-                               procinfo = index_getprocinfo(index, 1, SPGIST_CHOOSE_PROC);
                                FunctionCall2Coll(procinfo,
                                                                  index->rd_indcollation[0],
                                                                  PointerGetDatum(&in),
index 72aae02b4506b7855848715caab2f66054757d07..675c80eb39bfce52cdf386927f215723fd84f024 100644 (file)
@@ -743,27 +743,32 @@ Datum *
 spgExtractNodeLabels(SpGistState *state, SpGistInnerTuple innerTuple)
 {
        Datum      *nodeLabels;
-       int                     nullcount = 0;
        int                     i;
        SpGistNodeTuple node;
 
-       nodeLabels = (Datum *) palloc(sizeof(Datum) * innerTuple->nNodes);
-       SGITITERATE(innerTuple, i, node)
-       {
-               if (IndexTupleHasNulls(node))
-                       nullcount++;
-               else
-                       nodeLabels[i] = SGNTDATUM(node, state);
-       }
-       if (nullcount == innerTuple->nNodes)
+       /* Either all the labels must be NULL, or none. */
+       node = SGITNODEPTR(innerTuple);
+       if (IndexTupleHasNulls(node))
        {
+               SGITITERATE(innerTuple, i, node)
+               {
+                       if (!IndexTupleHasNulls(node))
+                               elog(ERROR, "some but not all node labels are null in SPGiST inner tuple");
+               }
                /* They're all null, so just return NULL */
-               pfree(nodeLabels);
                return NULL;
        }
-       if (nullcount != 0)
-               elog(ERROR, "some but not all node labels are null in SPGiST inner tuple");
-       return nodeLabels;
+       else
+       {
+               nodeLabels = (Datum *) palloc(sizeof(Datum) * innerTuple->nNodes);
+               SGITITERATE(innerTuple, i, node)
+               {
+                       if (IndexTupleHasNulls(node))
+                               elog(ERROR, "some but not all node labels are null in SPGiST inner tuple");
+                       nodeLabels[i] = SGNTDATUM(node, state);
+               }
+               return nodeLabels;
+       }
 }
 
 /*