]> granicus.if.org Git - postgresql/commitdiff
Further GIN refactoring.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 20 Nov 2013 14:09:14 +0000 (16:09 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 20 Nov 2013 14:09:14 +0000 (16:09 +0200)
Merge some functions that were always called together. Makes the code
little bit more readable.

src/backend/access/gin/ginbtree.c
src/backend/access/gin/gindatapage.c
src/backend/access/gin/ginentrypage.c
src/backend/access/gin/ginget.c
src/backend/access/gin/gininsert.c
src/include/access/gin_private.h

index 010812dc6d3470321dfe5ba2ea91557728b26496..0d93c52e04326fdb1521a05f36d00fa3b06d9aaf 100644 (file)
@@ -52,52 +52,38 @@ ginTraverseLock(Buffer buffer, bool searchMode)
        return access;
 }
 
-GinBtreeStack *
-ginPrepareFindLeafPage(GinBtree btree, BlockNumber blkno)
-{
-       GinBtreeStack *stack = (GinBtreeStack *) palloc(sizeof(GinBtreeStack));
-
-       stack->blkno = blkno;
-       stack->buffer = ReadBuffer(btree->index, stack->blkno);
-       stack->parent = NULL;
-       stack->predictNumber = 1;
-
-       ginTraverseLock(stack->buffer, btree->searchMode);
-
-       return stack;
-}
-
 /*
- * Locates leaf page contained tuple
+ * Descends the tree to the leaf page that contains or would contain the
+ * key we're searching for. The key should already be filled in 'btree',
+ * in tree-type specific manner. If btree->fullScan is true, descends to the
+ * leftmost leaf page.
+ *
+ * If 'searchmode' is false, on return stack->buffer is exclusively locked,
+ * and the stack represents the full path to the root. Otherwise stack->buffer
+ * is share-locked, and stack->parent is NULL.
  */
 GinBtreeStack *
-ginFindLeafPage(GinBtree btree, GinBtreeStack *stack)
+ginFindLeafPage(GinBtree btree, BlockNumber rootBlkno, bool searchMode)
 {
-       bool            isfirst = TRUE;
-       BlockNumber rootBlkno;
+       GinBtreeStack *stack;
 
-       if (!stack)
-               stack = ginPrepareFindLeafPage(btree, GIN_ROOT_BLKNO);
-       rootBlkno = stack->blkno;
+       stack = (GinBtreeStack *) palloc(sizeof(GinBtreeStack));
+       stack->blkno = rootBlkno;
+       stack->buffer = ReadBuffer(btree->index, rootBlkno);
+       stack->parent = NULL;
+       stack->predictNumber = 1;
 
        for (;;)
        {
                Page            page;
                BlockNumber child;
-               int                     access = GIN_SHARE;
+               int                     access;
 
                stack->off = InvalidOffsetNumber;
 
                page = BufferGetPage(stack->buffer);
 
-               if (isfirst)
-               {
-                       if (GinPageIsLeaf(page) && !btree->searchMode)
-                               access = GIN_EXCLUSIVE;
-                       isfirst = FALSE;
-               }
-               else
-                       access = ginTraverseLock(stack->buffer, btree->searchMode);
+               access = ginTraverseLock(stack->buffer, searchMode);
 
                /*
                 * ok, page is correctly locked, we should check to move right ..,
@@ -127,7 +113,7 @@ ginFindLeafPage(GinBtree btree, GinBtreeStack *stack)
                Assert(child != InvalidBlockNumber);
                Assert(stack->blkno != child);
 
-               if (btree->searchMode)
+               if (searchMode)
                {
                        /* in search mode we may forget path to leaf */
                        stack->blkno = child;
@@ -251,7 +237,7 @@ ginFindParents(GinBtree btree, GinBtreeStack *stack,
                return;
        }
 
-       leftmostBlkno = blkno = btree->getLeftMostPage(btree, page);
+       leftmostBlkno = blkno = btree->getLeftMostChild(btree, page);
        LockBuffer(root->buffer, GIN_UNLOCK);
        Assert(blkno != InvalidBlockNumber);
 
@@ -263,7 +249,7 @@ ginFindParents(GinBtree btree, GinBtreeStack *stack,
                if (GinPageIsLeaf(page))
                        elog(ERROR, "Lost path");
 
-               leftmostBlkno = btree->getLeftMostPage(btree, page);
+               leftmostBlkno = btree->getLeftMostChild(btree, page);
 
                while ((offset = btree->findChildPtr(btree, page, stack->blkno, InvalidOffsetNumber)) == InvalidOffsetNumber)
                {
index c9506cc0de1f7b24bd5bc8ddfcbb15a1b4f4c2f7..67d748bd7112bf2bad04771407579f27f9c55fc0 100644 (file)
@@ -54,7 +54,7 @@ dataLocateItem(GinBtree btree, GinBtreeStack *stack)
        {
                stack->off = FirstOffsetNumber;
                stack->predictNumber *= GinPageGetOpaque(page)->maxoff;
-               return btree->getLeftMostPage(btree, page);
+               return btree->getLeftMostChild(btree, page);
        }
 
        low = FirstOffsetNumber;
@@ -680,17 +680,10 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
         */
        if (nitems > nrootitems)
        {
-               GinPostingTreeScan *gdi;
-
-               gdi = ginPrepareScanPostingTree(index, blkno, FALSE);
-               gdi->btree.isBuild = (buildStats != NULL);
-
-               ginInsertItemPointers(gdi,
+               ginInsertItemPointers(index, blkno,
                                                          items + nrootitems,
                                                          nitems - nrootitems,
                                                          buildStats);
-
-               pfree(gdi);
        }
 
        return blkno;
@@ -704,76 +697,69 @@ ginPrepareDataScan(GinBtree btree, Relation index)
        btree->index = index;
 
        btree->findChildPage = dataLocateItem;
+       btree->getLeftMostChild = dataGetLeftMostPage;
        btree->isMoveRight = dataIsMoveRight;
        btree->findItem = dataLocateLeafItem;
        btree->findChildPtr = dataFindChildPtr;
-       btree->getLeftMostPage = dataGetLeftMostPage;
        btree->placeToPage = dataPlaceToPage;
        btree->splitPage = dataSplitPage;
        btree->fillRoot = ginDataFillRoot;
 
        btree->isData = TRUE;
-       btree->searchMode = FALSE;
        btree->isDelete = FALSE;
        btree->fullScan = FALSE;
        btree->isBuild = FALSE;
 }
 
-GinPostingTreeScan *
-ginPrepareScanPostingTree(Relation index, BlockNumber rootBlkno, bool searchMode)
-{
-       GinPostingTreeScan *gdi = (GinPostingTreeScan *) palloc0(sizeof(GinPostingTreeScan));
-
-       ginPrepareDataScan(&gdi->btree, index);
-
-       gdi->btree.searchMode = searchMode;
-       gdi->btree.fullScan = searchMode;
-
-       gdi->stack = ginPrepareFindLeafPage(&gdi->btree, rootBlkno);
-
-       return gdi;
-}
-
 /*
  * Inserts array of item pointers, may execute several tree scan (very rare)
  */
 void
-ginInsertItemPointers(GinPostingTreeScan *gdi,
+ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
                                          ItemPointerData *items, uint32 nitem,
                                          GinStatsData *buildStats)
 {
-       BlockNumber rootBlkno = gdi->stack->blkno;
+       GinBtreeData btree;
+       GinBtreeStack *stack;
 
-       gdi->btree.items = items;
-       gdi->btree.nitem = nitem;
-       gdi->btree.curitem = 0;
+       ginPrepareDataScan(&btree, index);
+       btree.isBuild = (buildStats != NULL);
+       btree.items = items;
+       btree.nitem = nitem;
+       btree.curitem = 0;
 
-       while (gdi->btree.curitem < gdi->btree.nitem)
+       while (btree.curitem < btree.nitem)
        {
-               if (!gdi->stack)
-                       gdi->stack = ginPrepareFindLeafPage(&gdi->btree, rootBlkno);
-
-               gdi->stack = ginFindLeafPage(&gdi->btree, gdi->stack);
+               stack = ginFindLeafPage(&btree, rootBlkno, false);
 
-               if (gdi->btree.findItem(&(gdi->btree), gdi->stack))
+               if (btree.findItem(&btree, stack))
                {
                        /*
-                        * gdi->btree.items[gdi->btree.curitem] already exists in index
+                        * btree.items[btree.curitem] already exists in index
                         */
-                       gdi->btree.curitem++;
-                       LockBuffer(gdi->stack->buffer, GIN_UNLOCK);
-                       freeGinBtreeStack(gdi->stack);
+                       btree.curitem++;
+                       LockBuffer(stack->buffer, GIN_UNLOCK);
+                       freeGinBtreeStack(stack);
                }
                else
-                       ginInsertValue(&(gdi->btree), gdi->stack, buildStats);
-
-               gdi->stack = NULL;
+                       ginInsertValue(&btree, stack, buildStats);
        }
 }
 
-Buffer
-ginScanBeginPostingTree(GinPostingTreeScan *gdi)
+/*
+ * Starts a new scan on a posting tree.
+ */
+GinBtreeStack *
+ginScanBeginPostingTree(Relation index, BlockNumber rootBlkno)
 {
-       gdi->stack = ginFindLeafPage(&gdi->btree, gdi->stack);
-       return gdi->stack->buffer;
+       GinBtreeData btree;
+       GinBtreeStack *stack;
+
+       ginPrepareDataScan(&btree, index);
+
+       btree.fullScan = TRUE;
+
+       stack = ginFindLeafPage(&btree, rootBlkno, TRUE);
+
+       return stack;
 }
index 0ed0a3db7eb59880a578af0a9206f3b4e235327b..a22fd32d9dab502f307719f7bc36460aa3e39e35 100644 (file)
@@ -258,7 +258,7 @@ entryLocateEntry(GinBtree btree, GinBtreeStack *stack)
        {
                stack->off = FirstOffsetNumber;
                stack->predictNumber *= PageGetMaxOffsetNumber(page);
-               return btree->getLeftMostPage(btree, page);
+               return btree->getLeftMostChild(btree, page);
        }
 
        low = FirstOffsetNumber;
@@ -729,16 +729,15 @@ ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
        btree->ginstate = ginstate;
 
        btree->findChildPage = entryLocateEntry;
+       btree->getLeftMostChild = entryGetLeftMostPage;
        btree->isMoveRight = entryIsMoveRight;
        btree->findItem = entryLocateLeafEntry;
        btree->findChildPtr = entryFindChildPtr;
-       btree->getLeftMostPage = entryGetLeftMostPage;
        btree->placeToPage = entryPlaceToPage;
        btree->splitPage = entrySplitPage;
        btree->fillRoot = ginEntryFillRoot;
 
        btree->isData = FALSE;
-       btree->searchMode = FALSE;
        btree->fullScan = FALSE;
        btree->isBuild = FALSE;
 
index acbdc5fe7f268e749a82cac296de751c73ce7c92..2a3991f1d12725edb57c06acb422a35c3f162905 100644 (file)
@@ -124,18 +124,16 @@ static void
 scanPostingTree(Relation index, GinScanEntry scanEntry,
                                BlockNumber rootPostingTree)
 {
-       GinPostingTreeScan *gdi;
+       GinBtreeStack *stack;
        Buffer          buffer;
        Page            page;
 
        /* Descend to the leftmost leaf page */
-       gdi = ginPrepareScanPostingTree(index, rootPostingTree, TRUE);
-
-       buffer = ginScanBeginPostingTree(gdi);
+       stack = ginScanBeginPostingTree(index, rootPostingTree);
+       buffer = stack->buffer;
        IncrBufferRefCount(buffer); /* prevent unpin in freeGinBtreeStack */
 
-       freeGinBtreeStack(gdi->stack);
-       pfree(gdi);
+       freeGinBtreeStack(stack);
 
        /*
         * Loop iterates through all leaf pages of posting tree
@@ -376,8 +374,7 @@ restartScanEntry:
        ginPrepareEntryScan(&btreeEntry, entry->attnum,
                                                entry->queryKey, entry->queryCategory,
                                                ginstate);
-       btreeEntry.searchMode = TRUE;
-       stackEntry = ginFindLeafPage(&btreeEntry, NULL);
+       stackEntry = ginFindLeafPage(&btreeEntry, GIN_ROOT_BLKNO, true);
        page = BufferGetPage(stackEntry->buffer);
        needUnlock = TRUE;
 
@@ -427,7 +424,7 @@ restartScanEntry:
                if (GinIsPostingTree(itup))
                {
                        BlockNumber rootPostingTree = GinGetPostingTree(itup);
-                       GinPostingTreeScan *gdi;
+                       GinBtreeStack *stack;
                        Page            page;
 
                        /*
@@ -439,9 +436,9 @@ restartScanEntry:
                         */
                        LockBuffer(stackEntry->buffer, GIN_UNLOCK);
                        needUnlock = FALSE;
-                       gdi = ginPrepareScanPostingTree(ginstate->index, rootPostingTree, TRUE);
 
-                       entry->buffer = ginScanBeginPostingTree(gdi);
+                       stack = ginScanBeginPostingTree(ginstate->index, rootPostingTree);
+                       entry->buffer = stack->buffer;
 
                        /*
                         * We keep buffer pinned because we need to prevent deletion of
@@ -451,7 +448,7 @@ restartScanEntry:
                        IncrBufferRefCount(entry->buffer);
 
                        page = BufferGetPage(entry->buffer);
-                       entry->predictNumberResult = gdi->stack->predictNumber * GinPageGetOpaque(page)->maxoff;
+                       entry->predictNumberResult = stack->predictNumber * GinPageGetOpaque(page)->maxoff;
 
                        /*
                         * Keep page content in memory to prevent durable page locking
@@ -463,8 +460,7 @@ restartScanEntry:
                                   GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
 
                        LockBuffer(entry->buffer, GIN_UNLOCK);
-                       freeGinBtreeStack(gdi->stack);
-                       pfree(gdi);
+                       freeGinBtreeStack(stack);
                        entry->isFinished = FALSE;
                }
                else if (GinGetNPosting(itup) > 0)
index fb7b4ea1ac39ab1f3525713ffa98b56e3bc1972c..0a2883aae3d289064f05bf535139b84388c147a5 100644 (file)
@@ -81,7 +81,6 @@ addItemPointersToLeafTuple(GinState *ginstate,
        {
                /* posting list would be too big, convert to posting tree */
                BlockNumber postingRoot;
-               GinPostingTreeScan *gdi;
 
                /*
                 * Initialize posting tree with the old tuple's posting list.  It's
@@ -94,12 +93,9 @@ addItemPointersToLeafTuple(GinState *ginstate,
                                                                                buildStats);
 
                /* Now insert the TIDs-to-be-added into the posting tree */
-               gdi = ginPrepareScanPostingTree(ginstate->index, postingRoot, FALSE);
-               gdi->btree.isBuild = (buildStats != NULL);
-
-               ginInsertItemPointers(gdi, items, nitem, buildStats);
-
-               pfree(gdi);
+               ginInsertItemPointers(ginstate->index, postingRoot,
+                                                         items, nitem,
+                                                         buildStats);
 
                /* And build a new posting-tree-only result tuple */
                res = GinFormTuple(ginstate, attnum, key, category, NULL, 0, true);
@@ -177,7 +173,7 @@ ginEntryInsert(GinState *ginstate,
 
        ginPrepareEntryScan(&btree, attnum, key, category, ginstate);
 
-       stack = ginFindLeafPage(&btree, NULL);
+       stack = ginFindLeafPage(&btree, GIN_ROOT_BLKNO, false);
        page = BufferGetPage(stack->buffer);
 
        if (btree.findItem(&btree, stack))
@@ -189,18 +185,15 @@ ginEntryInsert(GinState *ginstate,
                {
                        /* add entries to existing posting tree */
                        BlockNumber rootPostingTree = GinGetPostingTree(itup);
-                       GinPostingTreeScan *gdi;
 
                        /* release all stack */
                        LockBuffer(stack->buffer, GIN_UNLOCK);
                        freeGinBtreeStack(stack);
 
                        /* insert into posting tree */
-                       gdi = ginPrepareScanPostingTree(ginstate->index, rootPostingTree, FALSE);
-                       gdi->btree.isBuild = (buildStats != NULL);
-                       ginInsertItemPointers(gdi, items, nitem, buildStats);
-                       pfree(gdi);
-
+                       ginInsertItemPointers(ginstate->index, rootPostingTree,
+                                                                 items, nitem,
+                                                                 buildStats);
                        return;
                }
 
index d22cc62dd69f7c97ba450775c0fffb8ce48b5541..7491d7cf0ca67c59ae8699552096e5280726a696 100644 (file)
@@ -479,18 +479,17 @@ typedef struct GinBtreeData
 {
        /* search methods */
        BlockNumber (*findChildPage) (GinBtree, GinBtreeStack *);
+       BlockNumber (*getLeftMostChild) (GinBtree, Page);
        bool            (*isMoveRight) (GinBtree, Page);
        bool            (*findItem) (GinBtree, GinBtreeStack *);
 
        /* insert methods */
        OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber);
-       BlockNumber (*getLeftMostPage) (GinBtree, Page);
        bool            (*placeToPage) (GinBtree, Buffer, OffsetNumber, XLogRecData **);
        Page            (*splitPage) (GinBtree, Buffer, Buffer, OffsetNumber, XLogRecData **);
        void            (*fillRoot) (GinBtree, Buffer, Buffer, Buffer);
 
        bool            isData;
-       bool            searchMode;
 
        Relation        index;
        GinState   *ginstate;           /* not valid in a data scan */
@@ -514,8 +513,7 @@ typedef struct GinBtreeData
        PostingItem pitem;
 } GinBtreeData;
 
-extern GinBtreeStack *ginPrepareFindLeafPage(GinBtree btree, BlockNumber blkno);
-extern GinBtreeStack *ginFindLeafPage(GinBtree btree, GinBtreeStack *stack);
+extern GinBtreeStack *ginFindLeafPage(GinBtree btree, BlockNumber rootBlkno, bool searchMode);
 extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode);
 extern void freeGinBtreeStack(GinBtreeStack *stack);
 extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack,
@@ -540,19 +538,10 @@ extern BlockNumber createPostingTree(Relation index,
 extern void GinDataPageAddItemPointer(Page page, ItemPointer data, OffsetNumber offset);
 extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset);
 extern void GinPageDeletePostingItem(Page page, OffsetNumber offset);
-
-typedef struct
-{
-       GinBtreeData btree;
-       GinBtreeStack *stack;
-} GinPostingTreeScan;
-
-extern GinPostingTreeScan *ginPrepareScanPostingTree(Relation index,
-                                                 BlockNumber rootBlkno, bool searchMode);
-extern void ginInsertItemPointers(GinPostingTreeScan *gdi,
+extern void ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
                                          ItemPointerData *items, uint32 nitem,
                                          GinStatsData *buildStats);
-extern Buffer ginScanBeginPostingTree(GinPostingTreeScan *gdi);
+extern GinBtreeStack *ginScanBeginPostingTree(Relation index, BlockNumber rootBlkno);
 extern void ginDataFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf);
 extern void ginPrepareDataScan(GinBtree btree, Relation index);