Skip to content

Commit 04965ad

Browse files
committed
Further GIN refactoring.
Merge some functions that were always called together. Makes the code little bit more readable.
1 parent b21de4e commit 04965ad

File tree

6 files changed

+77
-128
lines changed

6 files changed

+77
-128
lines changed

src/backend/access/gin/ginbtree.c

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -52,52 +52,38 @@ ginTraverseLock(Buffer buffer, bool searchMode)
5252
return access;
5353
}
5454

55-
GinBtreeStack *
56-
ginPrepareFindLeafPage(GinBtree btree, BlockNumber blkno)
57-
{
58-
GinBtreeStack *stack = (GinBtreeStack *) palloc(sizeof(GinBtreeStack));
59-
60-
stack->blkno = blkno;
61-
stack->buffer = ReadBuffer(btree->index, stack->blkno);
62-
stack->parent = NULL;
63-
stack->predictNumber = 1;
64-
65-
ginTraverseLock(stack->buffer, btree->searchMode);
66-
67-
return stack;
68-
}
69-
7055
/*
71-
* Locates leaf page contained tuple
56+
* Descends the tree to the leaf page that contains or would contain the
57+
* key we're searching for. The key should already be filled in 'btree',
58+
* in tree-type specific manner. If btree->fullScan is true, descends to the
59+
* leftmost leaf page.
60+
*
61+
* If 'searchmode' is false, on return stack->buffer is exclusively locked,
62+
* and the stack represents the full path to the root. Otherwise stack->buffer
63+
* is share-locked, and stack->parent is NULL.
7264
*/
7365
GinBtreeStack *
74-
ginFindLeafPage(GinBtree btree, GinBtreeStack *stack)
66+
ginFindLeafPage(GinBtree btree, BlockNumber rootBlkno, bool searchMode)
7567
{
76-
bool isfirst = TRUE;
77-
BlockNumber rootBlkno;
68+
GinBtreeStack *stack;
7869

79-
if (!stack)
80-
stack = ginPrepareFindLeafPage(btree, GIN_ROOT_BLKNO);
81-
rootBlkno = stack->blkno;
70+
stack = (GinBtreeStack *) palloc(sizeof(GinBtreeStack));
71+
stack->blkno = rootBlkno;
72+
stack->buffer = ReadBuffer(btree->index, rootBlkno);
73+
stack->parent = NULL;
74+
stack->predictNumber = 1;
8275

8376
for (;;)
8477
{
8578
Page page;
8679
BlockNumber child;
87-
int access = GIN_SHARE;
80+
int access;
8881

8982
stack->off = InvalidOffsetNumber;
9083

9184
page = BufferGetPage(stack->buffer);
9285

93-
if (isfirst)
94-
{
95-
if (GinPageIsLeaf(page) && !btree->searchMode)
96-
access = GIN_EXCLUSIVE;
97-
isfirst = FALSE;
98-
}
99-
else
100-
access = ginTraverseLock(stack->buffer, btree->searchMode);
86+
access = ginTraverseLock(stack->buffer, searchMode);
10187

10288
/*
10389
* ok, page is correctly locked, we should check to move right ..,
@@ -127,7 +113,7 @@ ginFindLeafPage(GinBtree btree, GinBtreeStack *stack)
127113
Assert(child != InvalidBlockNumber);
128114
Assert(stack->blkno != child);
129115

130-
if (btree->searchMode)
116+
if (searchMode)
131117
{
132118
/* in search mode we may forget path to leaf */
133119
stack->blkno = child;
@@ -251,7 +237,7 @@ ginFindParents(GinBtree btree, GinBtreeStack *stack,
251237
return;
252238
}
253239

254-
leftmostBlkno = blkno = btree->getLeftMostPage(btree, page);
240+
leftmostBlkno = blkno = btree->getLeftMostChild(btree, page);
255241
LockBuffer(root->buffer, GIN_UNLOCK);
256242
Assert(blkno != InvalidBlockNumber);
257243

@@ -263,7 +249,7 @@ ginFindParents(GinBtree btree, GinBtreeStack *stack,
263249
if (GinPageIsLeaf(page))
264250
elog(ERROR, "Lost path");
265251

266-
leftmostBlkno = btree->getLeftMostPage(btree, page);
252+
leftmostBlkno = btree->getLeftMostChild(btree, page);
267253

268254
while ((offset = btree->findChildPtr(btree, page, stack->blkno, InvalidOffsetNumber)) == InvalidOffsetNumber)
269255
{

src/backend/access/gin/gindatapage.c

Lines changed: 34 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ dataLocateItem(GinBtree btree, GinBtreeStack *stack)
5454
{
5555
stack->off = FirstOffsetNumber;
5656
stack->predictNumber *= GinPageGetOpaque(page)->maxoff;
57-
return btree->getLeftMostPage(btree, page);
57+
return btree->getLeftMostChild(btree, page);
5858
}
5959

6060
low = FirstOffsetNumber;
@@ -680,17 +680,10 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
680680
*/
681681
if (nitems > nrootitems)
682682
{
683-
GinPostingTreeScan *gdi;
684-
685-
gdi = ginPrepareScanPostingTree(index, blkno, FALSE);
686-
gdi->btree.isBuild = (buildStats != NULL);
687-
688-
ginInsertItemPointers(gdi,
683+
ginInsertItemPointers(index, blkno,
689684
items + nrootitems,
690685
nitems - nrootitems,
691686
buildStats);
692-
693-
pfree(gdi);
694687
}
695688

696689
return blkno;
@@ -704,76 +697,69 @@ ginPrepareDataScan(GinBtree btree, Relation index)
704697
btree->index = index;
705698

706699
btree->findChildPage = dataLocateItem;
700+
btree->getLeftMostChild = dataGetLeftMostPage;
707701
btree->isMoveRight = dataIsMoveRight;
708702
btree->findItem = dataLocateLeafItem;
709703
btree->findChildPtr = dataFindChildPtr;
710-
btree->getLeftMostPage = dataGetLeftMostPage;
711704
btree->placeToPage = dataPlaceToPage;
712705
btree->splitPage = dataSplitPage;
713706
btree->fillRoot = ginDataFillRoot;
714707

715708
btree->isData = TRUE;
716-
btree->searchMode = FALSE;
717709
btree->isDelete = FALSE;
718710
btree->fullScan = FALSE;
719711
btree->isBuild = FALSE;
720712
}
721713

722-
GinPostingTreeScan *
723-
ginPrepareScanPostingTree(Relation index, BlockNumber rootBlkno, bool searchMode)
724-
{
725-
GinPostingTreeScan *gdi = (GinPostingTreeScan *) palloc0(sizeof(GinPostingTreeScan));
726-
727-
ginPrepareDataScan(&gdi->btree, index);
728-
729-
gdi->btree.searchMode = searchMode;
730-
gdi->btree.fullScan = searchMode;
731-
732-
gdi->stack = ginPrepareFindLeafPage(&gdi->btree, rootBlkno);
733-
734-
return gdi;
735-
}
736-
737714
/*
738715
* Inserts array of item pointers, may execute several tree scan (very rare)
739716
*/
740717
void
741-
ginInsertItemPointers(GinPostingTreeScan *gdi,
718+
ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
742719
ItemPointerData *items, uint32 nitem,
743720
GinStatsData *buildStats)
744721
{
745-
BlockNumber rootBlkno = gdi->stack->blkno;
722+
GinBtreeData btree;
723+
GinBtreeStack *stack;
746724

747-
gdi->btree.items = items;
748-
gdi->btree.nitem = nitem;
749-
gdi->btree.curitem = 0;
725+
ginPrepareDataScan(&btree, index);
726+
btree.isBuild = (buildStats != NULL);
727+
btree.items = items;
728+
btree.nitem = nitem;
729+
btree.curitem = 0;
750730

751-
while (gdi->btree.curitem < gdi->btree.nitem)
731+
while (btree.curitem < btree.nitem)
752732
{
753-
if (!gdi->stack)
754-
gdi->stack = ginPrepareFindLeafPage(&gdi->btree, rootBlkno);
755-
756-
gdi->stack = ginFindLeafPage(&gdi->btree, gdi->stack);
733+
stack = ginFindLeafPage(&btree, rootBlkno, false);
757734

758-
if (gdi->btree.findItem(&(gdi->btree), gdi->stack))
735+
if (btree.findItem(&btree, stack))
759736
{
760737
/*
761-
* gdi->btree.items[gdi->btree.curitem] already exists in index
738+
* btree.items[btree.curitem] already exists in index
762739
*/
763-
gdi->btree.curitem++;
764-
LockBuffer(gdi->stack->buffer, GIN_UNLOCK);
765-
freeGinBtreeStack(gdi->stack);
740+
btree.curitem++;
741+
LockBuffer(stack->buffer, GIN_UNLOCK);
742+
freeGinBtreeStack(stack);
766743
}
767744
else
768-
ginInsertValue(&(gdi->btree), gdi->stack, buildStats);
769-
770-
gdi->stack = NULL;
745+
ginInsertValue(&btree, stack, buildStats);
771746
}
772747
}
773748

774-
Buffer
775-
ginScanBeginPostingTree(GinPostingTreeScan *gdi)
749+
/*
750+
* Starts a new scan on a posting tree.
751+
*/
752+
GinBtreeStack *
753+
ginScanBeginPostingTree(Relation index, BlockNumber rootBlkno)
776754
{
777-
gdi->stack = ginFindLeafPage(&gdi->btree, gdi->stack);
778-
return gdi->stack->buffer;
755+
GinBtreeData btree;
756+
GinBtreeStack *stack;
757+
758+
ginPrepareDataScan(&btree, index);
759+
760+
btree.fullScan = TRUE;
761+
762+
stack = ginFindLeafPage(&btree, rootBlkno, TRUE);
763+
764+
return stack;
779765
}

src/backend/access/gin/ginentrypage.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ entryLocateEntry(GinBtree btree, GinBtreeStack *stack)
258258
{
259259
stack->off = FirstOffsetNumber;
260260
stack->predictNumber *= PageGetMaxOffsetNumber(page);
261-
return btree->getLeftMostPage(btree, page);
261+
return btree->getLeftMostChild(btree, page);
262262
}
263263

264264
low = FirstOffsetNumber;
@@ -729,16 +729,15 @@ ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
729729
btree->ginstate = ginstate;
730730

731731
btree->findChildPage = entryLocateEntry;
732+
btree->getLeftMostChild = entryGetLeftMostPage;
732733
btree->isMoveRight = entryIsMoveRight;
733734
btree->findItem = entryLocateLeafEntry;
734735
btree->findChildPtr = entryFindChildPtr;
735-
btree->getLeftMostPage = entryGetLeftMostPage;
736736
btree->placeToPage = entryPlaceToPage;
737737
btree->splitPage = entrySplitPage;
738738
btree->fillRoot = ginEntryFillRoot;
739739

740740
btree->isData = FALSE;
741-
btree->searchMode = FALSE;
742741
btree->fullScan = FALSE;
743742
btree->isBuild = FALSE;
744743

src/backend/access/gin/ginget.c

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,16 @@ static void
124124
scanPostingTree(Relation index, GinScanEntry scanEntry,
125125
BlockNumber rootPostingTree)
126126
{
127-
GinPostingTreeScan *gdi;
127+
GinBtreeStack *stack;
128128
Buffer buffer;
129129
Page page;
130130

131131
/* Descend to the leftmost leaf page */
132-
gdi = ginPrepareScanPostingTree(index, rootPostingTree, TRUE);
133-
134-
buffer = ginScanBeginPostingTree(gdi);
132+
stack = ginScanBeginPostingTree(index, rootPostingTree);
133+
buffer = stack->buffer;
135134
IncrBufferRefCount(buffer); /* prevent unpin in freeGinBtreeStack */
136135

137-
freeGinBtreeStack(gdi->stack);
138-
pfree(gdi);
136+
freeGinBtreeStack(stack);
139137

140138
/*
141139
* Loop iterates through all leaf pages of posting tree
@@ -376,8 +374,7 @@ startScanEntry(GinState *ginstate, GinScanEntry entry)
376374
ginPrepareEntryScan(&btreeEntry, entry->attnum,
377375
entry->queryKey, entry->queryCategory,
378376
ginstate);
379-
btreeEntry.searchMode = TRUE;
380-
stackEntry = ginFindLeafPage(&btreeEntry, NULL);
377+
stackEntry = ginFindLeafPage(&btreeEntry, GIN_ROOT_BLKNO, true);
381378
page = BufferGetPage(stackEntry->buffer);
382379
needUnlock = TRUE;
383380

@@ -427,7 +424,7 @@ startScanEntry(GinState *ginstate, GinScanEntry entry)
427424
if (GinIsPostingTree(itup))
428425
{
429426
BlockNumber rootPostingTree = GinGetPostingTree(itup);
430-
GinPostingTreeScan *gdi;
427+
GinBtreeStack *stack;
431428
Page page;
432429

433430
/*
@@ -439,9 +436,9 @@ startScanEntry(GinState *ginstate, GinScanEntry entry)
439436
*/
440437
LockBuffer(stackEntry->buffer, GIN_UNLOCK);
441438
needUnlock = FALSE;
442-
gdi = ginPrepareScanPostingTree(ginstate->index, rootPostingTree, TRUE);
443439

444-
entry->buffer = ginScanBeginPostingTree(gdi);
440+
stack = ginScanBeginPostingTree(ginstate->index, rootPostingTree);
441+
entry->buffer = stack->buffer;
445442

446443
/*
447444
* We keep buffer pinned because we need to prevent deletion of
@@ -451,7 +448,7 @@ startScanEntry(GinState *ginstate, GinScanEntry entry)
451448
IncrBufferRefCount(entry->buffer);
452449

453450
page = BufferGetPage(entry->buffer);
454-
entry->predictNumberResult = gdi->stack->predictNumber * GinPageGetOpaque(page)->maxoff;
451+
entry->predictNumberResult = stack->predictNumber * GinPageGetOpaque(page)->maxoff;
455452

456453
/*
457454
* Keep page content in memory to prevent durable page locking
@@ -463,8 +460,7 @@ startScanEntry(GinState *ginstate, GinScanEntry entry)
463460
GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
464461

465462
LockBuffer(entry->buffer, GIN_UNLOCK);
466-
freeGinBtreeStack(gdi->stack);
467-
pfree(gdi);
463+
freeGinBtreeStack(stack);
468464
entry->isFinished = FALSE;
469465
}
470466
else if (GinGetNPosting(itup) > 0)

src/backend/access/gin/gininsert.c

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ addItemPointersToLeafTuple(GinState *ginstate,
8181
{
8282
/* posting list would be too big, convert to posting tree */
8383
BlockNumber postingRoot;
84-
GinPostingTreeScan *gdi;
8584

8685
/*
8786
* Initialize posting tree with the old tuple's posting list. It's
@@ -94,12 +93,9 @@ addItemPointersToLeafTuple(GinState *ginstate,
9493
buildStats);
9594

9695
/* Now insert the TIDs-to-be-added into the posting tree */
97-
gdi = ginPrepareScanPostingTree(ginstate->index, postingRoot, FALSE);
98-
gdi->btree.isBuild = (buildStats != NULL);
99-
100-
ginInsertItemPointers(gdi, items, nitem, buildStats);
101-
102-
pfree(gdi);
96+
ginInsertItemPointers(ginstate->index, postingRoot,
97+
items, nitem,
98+
buildStats);
10399

104100
/* And build a new posting-tree-only result tuple */
105101
res = GinFormTuple(ginstate, attnum, key, category, NULL, 0, true);
@@ -177,7 +173,7 @@ ginEntryInsert(GinState *ginstate,
177173

178174
ginPrepareEntryScan(&btree, attnum, key, category, ginstate);
179175

180-
stack = ginFindLeafPage(&btree, NULL);
176+
stack = ginFindLeafPage(&btree, GIN_ROOT_BLKNO, false);
181177
page = BufferGetPage(stack->buffer);
182178

183179
if (btree.findItem(&btree, stack))
@@ -189,18 +185,15 @@ ginEntryInsert(GinState *ginstate,
189185
{
190186
/* add entries to existing posting tree */
191187
BlockNumber rootPostingTree = GinGetPostingTree(itup);
192-
GinPostingTreeScan *gdi;
193188

194189
/* release all stack */
195190
LockBuffer(stack->buffer, GIN_UNLOCK);
196191
freeGinBtreeStack(stack);
197192

198193
/* insert into posting tree */
199-
gdi = ginPrepareScanPostingTree(ginstate->index, rootPostingTree, FALSE);
200-
gdi->btree.isBuild = (buildStats != NULL);
201-
ginInsertItemPointers(gdi, items, nitem, buildStats);
202-
pfree(gdi);
203-
194+
ginInsertItemPointers(ginstate->index, rootPostingTree,
195+
items, nitem,
196+
buildStats);
204197
return;
205198
}
206199

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy