aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/gin/gininsert.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2009-03-24 20:17:18 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2009-03-24 20:17:18 +0000
commitff301d6e690bb5581502ea3d8591a1600fd87acc (patch)
tree9fd8b2fa00cf35f8b2e66b0960e7e9ca90dfaa66 /src/backend/access/gin/gininsert.c
parent9987f66001ef7f59dd8f8c92295732dba5507c4f (diff)
downloadpostgresql-ff301d6e690bb5581502ea3d8591a1600fd87acc.tar.gz
postgresql-ff301d6e690bb5581502ea3d8591a1600fd87acc.zip
Implement "fastupdate" support for GIN indexes, in which we try to accumulate
multiple index entries in a holding area before adding them to the main index structure. This helps because bulk insert is (usually) significantly faster than retail insert for GIN. This patch also removes GIN support for amgettuple-style index scans. The API defined for amgettuple is difficult to support with fastupdate, and the previously committed partial-match feature didn't really work with it either. We might eventually figure a way to put back amgettuple support, but it won't happen for 8.4. catversion bumped because of change in GIN's pg_am entry, and because the format of GIN indexes changed on-disk (there's a metapage now, and possibly a pending list). Teodor Sigaev
Diffstat (limited to 'src/backend/access/gin/gininsert.c')
-rw-r--r--src/backend/access/gin/gininsert.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 2ab1105423c..d05882cdb94 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.18 2009/01/01 17:23:34 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.19 2009/03/24 20:17:11 tgl Exp $
*-------------------------------------------------------------------------
*/
@@ -138,9 +138,11 @@ addItemPointersToTuple(Relation index, GinState *ginstate, GinBtreeStack *stack,
/*
* Inserts only one entry to the index, but it can add more than 1 ItemPointer.
*/
-static void
-ginEntryInsert(Relation index, GinState *ginstate, OffsetNumber attnum, Datum value,
- ItemPointerData *items, uint32 nitem, bool isBuild)
+void
+ginEntryInsert(Relation index, GinState *ginstate,
+ OffsetNumber attnum, Datum value,
+ ItemPointerData *items, uint32 nitem,
+ bool isBuild)
{
GinBtreeData btree;
GinBtreeStack *stack;
@@ -273,7 +275,7 @@ ginbuild(PG_FUNCTION_ARGS)
IndexBuildResult *result;
double reltuples;
GinBuildState buildstate;
- Buffer buffer;
+ Buffer RootBuffer, MetaBuffer;
ItemPointerData *list;
Datum entry;
uint32 nlist;
@@ -286,11 +288,17 @@ ginbuild(PG_FUNCTION_ARGS)
initGinState(&buildstate.ginstate, index);
+ /* initialize the meta page */
+ MetaBuffer = GinNewBuffer(index);
+
/* initialize the root page */
- buffer = GinNewBuffer(index);
+ RootBuffer = GinNewBuffer(index);
+
START_CRIT_SECTION();
- GinInitBuffer(buffer, GIN_LEAF);
- MarkBufferDirty(buffer);
+ GinInitMetabuffer(MetaBuffer);
+ MarkBufferDirty(MetaBuffer);
+ GinInitBuffer(RootBuffer, GIN_LEAF);
+ MarkBufferDirty(RootBuffer);
if (!index->rd_istemp)
{
@@ -303,16 +311,19 @@ ginbuild(PG_FUNCTION_ARGS)
rdata.len = sizeof(RelFileNode);
rdata.next = NULL;
- page = BufferGetPage(buffer);
-
-
recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_CREATE_INDEX, &rdata);
+
+ page = BufferGetPage(RootBuffer);
PageSetLSN(page, recptr);
PageSetTLI(page, ThisTimeLineID);
+ page = BufferGetPage(MetaBuffer);
+ PageSetLSN(page, recptr);
+ PageSetTLI(page, ThisTimeLineID);
}
- UnlockReleaseBuffer(buffer);
+ UnlockReleaseBuffer(MetaBuffer);
+ UnlockReleaseBuffer(RootBuffer);
END_CRIT_SECTION();
/* build the index */
@@ -417,9 +428,26 @@ gininsert(PG_FUNCTION_ARGS)
initGinState(&ginstate, index);
- for(i=0; i<ginstate.origTupdesc->natts;i++)
- if ( !isnull[i] )
- res += ginHeapTupleInsert(index, &ginstate, (OffsetNumber)(i+1), values[i], ht_ctid);
+ if ( GinGetUseFastUpdate(index) )
+ {
+ GinTupleCollector collector;
+
+ memset(&collector, 0, sizeof(GinTupleCollector));
+ for(i=0; i<ginstate.origTupdesc->natts;i++)
+ if ( !isnull[i] )
+ res += ginHeapTupleFastCollect(index, &ginstate, &collector,
+ (OffsetNumber)(i+1), values[i], ht_ctid);
+
+ ginHeapTupleFastInsert(index, &ginstate, &collector);
+ }
+ else
+ {
+ for(i=0; i<ginstate.origTupdesc->natts;i++)
+ if ( !isnull[i] )
+ res += ginHeapTupleInsert(index, &ginstate,
+ (OffsetNumber)(i+1), values[i], ht_ctid);
+
+ }
MemoryContextSwitchTo(oldCtx);
MemoryContextDelete(insertCtx);