aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/gin/gininsert.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/gin/gininsert.c')
-rw-r--r--src/backend/access/gin/gininsert.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 640d3acde9f..263e447ca41 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -27,6 +27,7 @@ typedef struct
{
GinState ginstate;
double indtuples;
+ GinStatsData buildStats;
MemoryContext tmpCtx;
MemoryContext funcCtx;
BuildAccumulator accum;
@@ -97,8 +98,10 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems)
* GinFormTuple().
*/
static IndexTuple
-addItemPointersToTuple(Relation index, GinState *ginstate, GinBtreeStack *stack,
- IndexTuple old, ItemPointerData *items, uint32 nitem, bool isBuild)
+addItemPointersToTuple(Relation index, GinState *ginstate,
+ GinBtreeStack *stack, IndexTuple old,
+ ItemPointerData *items, uint32 nitem,
+ GinStatsData *buildStats)
{
Datum key = gin_index_getattr(ginstate, old);
OffsetNumber attnum = gintuple_get_attrnum(ginstate, old);
@@ -128,11 +131,15 @@ addItemPointersToTuple(Relation index, GinState *ginstate, GinBtreeStack *stack,
GinSetPostingTree(res, postingRoot);
gdi = prepareScanPostingTree(index, postingRoot, FALSE);
- gdi->btree.isBuild = isBuild;
+ gdi->btree.isBuild = (buildStats != NULL);
- insertItemPointer(gdi, items, nitem);
+ ginInsertItemPointer(gdi, items, nitem, buildStats);
pfree(gdi);
+
+ /* During index build, count the newly-added data page */
+ if (buildStats)
+ buildStats->nDataPages++;
}
return res;
@@ -140,18 +147,25 @@ addItemPointersToTuple(Relation index, GinState *ginstate, GinBtreeStack *stack,
/*
* Inserts only one entry to the index, but it can add more than 1 ItemPointer.
+ *
+ * During an index build, buildStats is non-null and the counters
+ * it contains should be incremented as needed.
*/
void
ginEntryInsert(Relation index, GinState *ginstate,
OffsetNumber attnum, Datum value,
ItemPointerData *items, uint32 nitem,
- bool isBuild)
+ GinStatsData *buildStats)
{
GinBtreeData btree;
GinBtreeStack *stack;
IndexTuple itup;
Page page;
+ /* During index build, count the to-be-inserted entry */
+ if (buildStats)
+ buildStats->nEntries++;
+
prepareEntryScan(&btree, index, attnum, value, ginstate);
stack = ginFindLeafPage(&btree, NULL);
@@ -174,14 +188,15 @@ ginEntryInsert(Relation index, GinState *ginstate,
/* insert into posting tree */
gdi = prepareScanPostingTree(index, rootPostingTree, FALSE);
- gdi->btree.isBuild = isBuild;
- insertItemPointer(gdi, items, nitem);
+ gdi->btree.isBuild = (buildStats != NULL);
+ ginInsertItemPointer(gdi, items, nitem, buildStats);
pfree(gdi);
return;
}
- itup = addItemPointersToTuple(index, ginstate, stack, itup, items, nitem, isBuild);
+ itup = addItemPointersToTuple(index, ginstate, stack, itup,
+ items, nitem, buildStats);
btree.isDelete = TRUE;
}
@@ -195,13 +210,14 @@ ginEntryInsert(Relation index, GinState *ginstate,
/* Add the rest, making a posting tree if necessary */
IndexTuple previtup = itup;
- itup = addItemPointersToTuple(index, ginstate, stack, previtup, items + 1, nitem - 1, isBuild);
+ itup = addItemPointersToTuple(index, ginstate, stack, previtup,
+ items + 1, nitem - 1, buildStats);
pfree(previtup);
}
}
btree.entry = itup;
- ginInsertValue(&btree, stack);
+ ginInsertValue(&btree, stack, buildStats);
pfree(itup);
}
@@ -260,7 +276,8 @@ ginBuildCallback(Relation index, HeapTuple htup, Datum *values,
{
/* there could be many entries, so be willing to abort here */
CHECK_FOR_INTERRUPTS();
- ginEntryInsert(index, &buildstate->ginstate, attnum, entry, list, nlist, TRUE);
+ ginEntryInsert(index, &buildstate->ginstate, attnum, entry,
+ list, nlist, &buildstate->buildStats);
}
MemoryContextReset(buildstate->tmpCtx);
@@ -292,6 +309,8 @@ ginbuild(PG_FUNCTION_ARGS)
RelationGetRelationName(index));
initGinState(&buildstate.ginstate, index);
+ buildstate.indtuples = 0;
+ memset(&buildstate.buildStats, 0, sizeof(GinStatsData));
/* initialize the meta page */
MetaBuffer = GinNewBuffer(index);
@@ -331,8 +350,8 @@ ginbuild(PG_FUNCTION_ARGS)
UnlockReleaseBuffer(RootBuffer);
END_CRIT_SECTION();
- /* build the index */
- buildstate.indtuples = 0;
+ /* count the root as first entry page */
+ buildstate.buildStats.nEntryPages++;
/*
* create a temporary memory context that is reset once for each tuple
@@ -367,13 +386,20 @@ ginbuild(PG_FUNCTION_ARGS)
{
/* there could be many entries, so be willing to abort here */
CHECK_FOR_INTERRUPTS();
- ginEntryInsert(index, &buildstate.ginstate, attnum, entry, list, nlist, TRUE);
+ ginEntryInsert(index, &buildstate.ginstate, attnum, entry,
+ list, nlist, &buildstate.buildStats);
}
MemoryContextSwitchTo(oldCtx);
MemoryContextDelete(buildstate.tmpCtx);
/*
+ * Update metapage stats
+ */
+ buildstate.buildStats.nTotalPages = RelationGetNumberOfBlocks(index);
+ ginUpdateStats(index, &buildstate.buildStats);
+
+ /*
* Return statistics
*/
result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult));
@@ -401,7 +427,7 @@ ginHeapTupleInsert(Relation index, GinState *ginstate, OffsetNumber attnum, Datu
return 0;
for (i = 0; i < nentries; i++)
- ginEntryInsert(index, ginstate, attnum, entries[i], item, 1, FALSE);
+ ginEntryInsert(index, ginstate, attnum, entries[i], item, 1, NULL);
return nentries;
}