Skip to content

Commit c82dedb

Browse files
committed
Optimize SP-GiST insertions.
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.
1 parent 9df55c8 commit c82dedb

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

src/backend/access/spgist/spgdoinsert.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,14 @@ spgdoinsert(Relation index, SpGistState *state,
18611861
int leafSize;
18621862
SPPageDesc current,
18631863
parent;
1864+
FmgrInfo *procinfo = NULL;
1865+
1866+
/*
1867+
* Look up FmgrInfo of the user-defined choose function once, to save
1868+
* cycles in the loop below.
1869+
*/
1870+
if (!isnull)
1871+
procinfo = index_getprocinfo(index, 1, SPGIST_CHOOSE_PROC);
18641872

18651873
/*
18661874
* 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,
20072015
SpGistInnerTuple innerTuple;
20082016
spgChooseIn in;
20092017
spgChooseOut out;
2010-
FmgrInfo *procinfo;
20112018

20122019
/*
20132020
* spgAddNode and spgSplitTuple cases will loop back to here to
@@ -2035,7 +2042,6 @@ spgdoinsert(Relation index, SpGistState *state,
20352042
if (!isnull)
20362043
{
20372044
/* use user-defined choose method */
2038-
procinfo = index_getprocinfo(index, 1, SPGIST_CHOOSE_PROC);
20392045
FunctionCall2Coll(procinfo,
20402046
index->rd_indcollation[0],
20412047
PointerGetDatum(&in),

src/backend/access/spgist/spgutils.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -743,27 +743,32 @@ Datum *
743743
spgExtractNodeLabels(SpGistState *state, SpGistInnerTuple innerTuple)
744744
{
745745
Datum *nodeLabels;
746-
int nullcount = 0;
747746
int i;
748747
SpGistNodeTuple node;
749748

750-
nodeLabels = (Datum *) palloc(sizeof(Datum) * innerTuple->nNodes);
751-
SGITITERATE(innerTuple, i, node)
752-
{
753-
if (IndexTupleHasNulls(node))
754-
nullcount++;
755-
else
756-
nodeLabels[i] = SGNTDATUM(node, state);
757-
}
758-
if (nullcount == innerTuple->nNodes)
749+
/* Either all the labels must be NULL, or none. */
750+
node = SGITNODEPTR(innerTuple);
751+
if (IndexTupleHasNulls(node))
759752
{
753+
SGITITERATE(innerTuple, i, node)
754+
{
755+
if (!IndexTupleHasNulls(node))
756+
elog(ERROR, "some but not all node labels are null in SPGiST inner tuple");
757+
}
760758
/* They're all null, so just return NULL */
761-
pfree(nodeLabels);
762759
return NULL;
763760
}
764-
if (nullcount != 0)
765-
elog(ERROR, "some but not all node labels are null in SPGiST inner tuple");
766-
return nodeLabels;
761+
else
762+
{
763+
nodeLabels = (Datum *) palloc(sizeof(Datum) * innerTuple->nNodes);
764+
SGITITERATE(innerTuple, i, node)
765+
{
766+
if (IndexTupleHasNulls(node))
767+
elog(ERROR, "some but not all node labels are null in SPGiST inner tuple");
768+
nodeLabels[i] = SGNTDATUM(node, state);
769+
}
770+
return nodeLabels;
771+
}
767772
}
768773

769774
/*

0 commit comments

Comments
 (0)