Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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;
+   }
 }
 
 /*