diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-11-06 10:31:38 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-11-06 10:32:09 +0200 |
commit | ecaa4708e5dde5e9f72cdb066780acb4b12ee0ec (patch) | |
tree | 71da25393149a4b62a385d822f010d75891f9cd4 /src/backend/access/gin/gininsert.c | |
parent | 920c8261d58c10de7e68d99c8dd21a9650928d59 (diff) | |
download | postgresql-ecaa4708e5dde5e9f72cdb066780acb4b12ee0ec.tar.gz |
Misc GIN refactoring.
Merge the isEnoughSpace and placeToPage functions in the b-tree interface
into one function that tries to put a tuple on page, and returns false if
it doesn't fit.
Move createPostingTree function to gindatapage.c, and change its contract
so that it can be passed more items than fit on the root page. It's in a
better position than the callers to know how many items fit.
Move ginMergeItemPointers out of gindatapage.c, into a separate file.
These changes make no difference now, but reduce the footprint of Alexander
Korotkov's upcoming patch to pack item pointers more tightly.
Diffstat (limited to 'src/backend/access/gin/gininsert.c')
-rw-r--r-- | src/backend/access/gin/gininsert.c | 94 |
1 files changed, 5 insertions, 89 deletions
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index beaa65317f..125f3fb12d 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -35,64 +35,6 @@ typedef struct BuildAccumulator accum; } GinBuildState; -/* - * Creates new posting tree with one page, containing the given TIDs. - * Returns the page number (which will be the root of this posting tree). - * - * items[] must be in sorted order with no duplicates. - */ -static BlockNumber -createPostingTree(Relation index, ItemPointerData *items, uint32 nitems) -{ - BlockNumber blkno; - Buffer buffer = GinNewBuffer(index); - Page page; - - /* Assert that the items[] array will fit on one page */ - Assert(nitems <= GinMaxLeafDataItems); - - START_CRIT_SECTION(); - - GinInitBuffer(buffer, GIN_DATA | GIN_LEAF); - page = BufferGetPage(buffer); - blkno = BufferGetBlockNumber(buffer); - - memcpy(GinDataPageGetData(page), items, sizeof(ItemPointerData) * nitems); - GinPageGetOpaque(page)->maxoff = nitems; - - MarkBufferDirty(buffer); - - if (RelationNeedsWAL(index)) - { - XLogRecPtr recptr; - XLogRecData rdata[2]; - ginxlogCreatePostingTree data; - - data.node = index->rd_node; - data.blkno = blkno; - data.nitem = nitems; - - rdata[0].buffer = InvalidBuffer; - rdata[0].data = (char *) &data; - rdata[0].len = sizeof(ginxlogCreatePostingTree); - rdata[0].next = &rdata[1]; - - rdata[1].buffer = InvalidBuffer; - rdata[1].data = (char *) items; - rdata[1].len = sizeof(ItemPointerData) * nitems; - rdata[1].next = NULL; - - recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_CREATE_PTREE, rdata); - PageSetLSN(page, recptr); - } - - UnlockReleaseBuffer(buffer); - - END_CRIT_SECTION(); - - return blkno; -} - /* * Adds array of item pointers to tuple's posting list, or @@ -148,11 +90,8 @@ addItemPointersToLeafTuple(GinState *ginstate, */ postingRoot = createPostingTree(ginstate->index, GinGetPosting(old), - GinGetNPosting(old)); - - /* During index build, count the newly-added data page */ - if (buildStats) - buildStats->nDataPages++; + GinGetNPosting(old), + buildStats); /* Now insert the TIDs-to-be-added into the posting tree */ gdi = ginPrepareScanPostingTree(ginstate->index, postingRoot, FALSE); @@ -186,7 +125,7 @@ buildFreshLeafTuple(GinState *ginstate, { IndexTuple res; - /* try to build tuple with room for all the items */ + /* try to build a posting list tuple with all the items */ res = GinFormTuple(ginstate, attnum, key, category, items, nitem, false); @@ -202,32 +141,9 @@ buildFreshLeafTuple(GinState *ginstate, res = GinFormTuple(ginstate, attnum, key, category, NULL, 0, true); /* - * Initialize posting tree with as many TIDs as will fit on the first - * page. + * Initialize a new posting tree with the TIDs. */ - postingRoot = createPostingTree(ginstate->index, - items, - Min(nitem, GinMaxLeafDataItems)); - - /* During index build, count the newly-added data page */ - if (buildStats) - buildStats->nDataPages++; - - /* Add any remaining TIDs to the posting tree */ - if (nitem > GinMaxLeafDataItems) - { - GinPostingTreeScan *gdi; - - gdi = ginPrepareScanPostingTree(ginstate->index, postingRoot, FALSE); - gdi->btree.isBuild = (buildStats != NULL); - - ginInsertItemPointers(gdi, - items + GinMaxLeafDataItems, - nitem - GinMaxLeafDataItems, - buildStats); - - pfree(gdi); - } + postingRoot = createPostingTree(ginstate->index, items, nitem); /* And save the root link in the result tuple */ GinSetPostingTree(res, postingRoot); |