Further GIN refactoring.
Merge some functions that were always called together. Makes the code little bit more readable.
This commit is contained in:
parent
b21de4e7b3
commit
04965ad40e
@ -52,52 +52,38 @@ ginTraverseLock(Buffer buffer, bool searchMode)
|
|||||||
return access;
|
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 *
|
GinBtreeStack *
|
||||||
ginFindLeafPage(GinBtree btree, GinBtreeStack *stack)
|
ginFindLeafPage(GinBtree btree, BlockNumber rootBlkno, bool searchMode)
|
||||||
{
|
{
|
||||||
bool isfirst = TRUE;
|
GinBtreeStack *stack;
|
||||||
BlockNumber rootBlkno;
|
|
||||||
|
|
||||||
if (!stack)
|
stack = (GinBtreeStack *) palloc(sizeof(GinBtreeStack));
|
||||||
stack = ginPrepareFindLeafPage(btree, GIN_ROOT_BLKNO);
|
stack->blkno = rootBlkno;
|
||||||
rootBlkno = stack->blkno;
|
stack->buffer = ReadBuffer(btree->index, rootBlkno);
|
||||||
|
stack->parent = NULL;
|
||||||
|
stack->predictNumber = 1;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Page page;
|
Page page;
|
||||||
BlockNumber child;
|
BlockNumber child;
|
||||||
int access = GIN_SHARE;
|
int access;
|
||||||
|
|
||||||
stack->off = InvalidOffsetNumber;
|
stack->off = InvalidOffsetNumber;
|
||||||
|
|
||||||
page = BufferGetPage(stack->buffer);
|
page = BufferGetPage(stack->buffer);
|
||||||
|
|
||||||
if (isfirst)
|
access = ginTraverseLock(stack->buffer, searchMode);
|
||||||
{
|
|
||||||
if (GinPageIsLeaf(page) && !btree->searchMode)
|
|
||||||
access = GIN_EXCLUSIVE;
|
|
||||||
isfirst = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
access = ginTraverseLock(stack->buffer, btree->searchMode);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ok, page is correctly locked, we should check to move right ..,
|
* ok, page is correctly locked, we should check to move right ..,
|
||||||
@ -127,7 +113,7 @@ ginFindLeafPage(GinBtree btree, GinBtreeStack *stack)
|
|||||||
Assert(child != InvalidBlockNumber);
|
Assert(child != InvalidBlockNumber);
|
||||||
Assert(stack->blkno != child);
|
Assert(stack->blkno != child);
|
||||||
|
|
||||||
if (btree->searchMode)
|
if (searchMode)
|
||||||
{
|
{
|
||||||
/* in search mode we may forget path to leaf */
|
/* in search mode we may forget path to leaf */
|
||||||
stack->blkno = child;
|
stack->blkno = child;
|
||||||
@ -251,7 +237,7 @@ ginFindParents(GinBtree btree, GinBtreeStack *stack,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
leftmostBlkno = blkno = btree->getLeftMostPage(btree, page);
|
leftmostBlkno = blkno = btree->getLeftMostChild(btree, page);
|
||||||
LockBuffer(root->buffer, GIN_UNLOCK);
|
LockBuffer(root->buffer, GIN_UNLOCK);
|
||||||
Assert(blkno != InvalidBlockNumber);
|
Assert(blkno != InvalidBlockNumber);
|
||||||
|
|
||||||
@ -263,7 +249,7 @@ ginFindParents(GinBtree btree, GinBtreeStack *stack,
|
|||||||
if (GinPageIsLeaf(page))
|
if (GinPageIsLeaf(page))
|
||||||
elog(ERROR, "Lost path");
|
elog(ERROR, "Lost path");
|
||||||
|
|
||||||
leftmostBlkno = btree->getLeftMostPage(btree, page);
|
leftmostBlkno = btree->getLeftMostChild(btree, page);
|
||||||
|
|
||||||
while ((offset = btree->findChildPtr(btree, page, stack->blkno, InvalidOffsetNumber)) == InvalidOffsetNumber)
|
while ((offset = btree->findChildPtr(btree, page, stack->blkno, InvalidOffsetNumber)) == InvalidOffsetNumber)
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@ dataLocateItem(GinBtree btree, GinBtreeStack *stack)
|
|||||||
{
|
{
|
||||||
stack->off = FirstOffsetNumber;
|
stack->off = FirstOffsetNumber;
|
||||||
stack->predictNumber *= GinPageGetOpaque(page)->maxoff;
|
stack->predictNumber *= GinPageGetOpaque(page)->maxoff;
|
||||||
return btree->getLeftMostPage(btree, page);
|
return btree->getLeftMostChild(btree, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
low = FirstOffsetNumber;
|
low = FirstOffsetNumber;
|
||||||
@ -680,17 +680,10 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
|
|||||||
*/
|
*/
|
||||||
if (nitems > nrootitems)
|
if (nitems > nrootitems)
|
||||||
{
|
{
|
||||||
GinPostingTreeScan *gdi;
|
ginInsertItemPointers(index, blkno,
|
||||||
|
|
||||||
gdi = ginPrepareScanPostingTree(index, blkno, FALSE);
|
|
||||||
gdi->btree.isBuild = (buildStats != NULL);
|
|
||||||
|
|
||||||
ginInsertItemPointers(gdi,
|
|
||||||
items + nrootitems,
|
items + nrootitems,
|
||||||
nitems - nrootitems,
|
nitems - nrootitems,
|
||||||
buildStats);
|
buildStats);
|
||||||
|
|
||||||
pfree(gdi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return blkno;
|
return blkno;
|
||||||
@ -704,76 +697,69 @@ ginPrepareDataScan(GinBtree btree, Relation index)
|
|||||||
btree->index = index;
|
btree->index = index;
|
||||||
|
|
||||||
btree->findChildPage = dataLocateItem;
|
btree->findChildPage = dataLocateItem;
|
||||||
|
btree->getLeftMostChild = dataGetLeftMostPage;
|
||||||
btree->isMoveRight = dataIsMoveRight;
|
btree->isMoveRight = dataIsMoveRight;
|
||||||
btree->findItem = dataLocateLeafItem;
|
btree->findItem = dataLocateLeafItem;
|
||||||
btree->findChildPtr = dataFindChildPtr;
|
btree->findChildPtr = dataFindChildPtr;
|
||||||
btree->getLeftMostPage = dataGetLeftMostPage;
|
|
||||||
btree->placeToPage = dataPlaceToPage;
|
btree->placeToPage = dataPlaceToPage;
|
||||||
btree->splitPage = dataSplitPage;
|
btree->splitPage = dataSplitPage;
|
||||||
btree->fillRoot = ginDataFillRoot;
|
btree->fillRoot = ginDataFillRoot;
|
||||||
|
|
||||||
btree->isData = TRUE;
|
btree->isData = TRUE;
|
||||||
btree->searchMode = FALSE;
|
|
||||||
btree->isDelete = FALSE;
|
btree->isDelete = FALSE;
|
||||||
btree->fullScan = FALSE;
|
btree->fullScan = FALSE;
|
||||||
btree->isBuild = 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)
|
* Inserts array of item pointers, may execute several tree scan (very rare)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ginInsertItemPointers(GinPostingTreeScan *gdi,
|
ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
|
||||||
ItemPointerData *items, uint32 nitem,
|
ItemPointerData *items, uint32 nitem,
|
||||||
GinStatsData *buildStats)
|
GinStatsData *buildStats)
|
||||||
{
|
{
|
||||||
BlockNumber rootBlkno = gdi->stack->blkno;
|
GinBtreeData btree;
|
||||||
|
GinBtreeStack *stack;
|
||||||
|
|
||||||
gdi->btree.items = items;
|
ginPrepareDataScan(&btree, index);
|
||||||
gdi->btree.nitem = nitem;
|
btree.isBuild = (buildStats != NULL);
|
||||||
gdi->btree.curitem = 0;
|
btree.items = items;
|
||||||
|
btree.nitem = nitem;
|
||||||
|
btree.curitem = 0;
|
||||||
|
|
||||||
while (gdi->btree.curitem < gdi->btree.nitem)
|
while (btree.curitem < btree.nitem)
|
||||||
{
|
{
|
||||||
if (!gdi->stack)
|
stack = ginFindLeafPage(&btree, rootBlkno, false);
|
||||||
gdi->stack = ginPrepareFindLeafPage(&gdi->btree, rootBlkno);
|
|
||||||
|
|
||||||
gdi->stack = ginFindLeafPage(&gdi->btree, gdi->stack);
|
if (btree.findItem(&btree, stack))
|
||||||
|
|
||||||
if (gdi->btree.findItem(&(gdi->btree), gdi->stack))
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* gdi->btree.items[gdi->btree.curitem] already exists in index
|
* btree.items[btree.curitem] already exists in index
|
||||||
*/
|
*/
|
||||||
gdi->btree.curitem++;
|
btree.curitem++;
|
||||||
LockBuffer(gdi->stack->buffer, GIN_UNLOCK);
|
LockBuffer(stack->buffer, GIN_UNLOCK);
|
||||||
freeGinBtreeStack(gdi->stack);
|
freeGinBtreeStack(stack);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ginInsertValue(&(gdi->btree), gdi->stack, buildStats);
|
ginInsertValue(&btree, stack, buildStats);
|
||||||
|
|
||||||
gdi->stack = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
GinBtreeData btree;
|
||||||
return gdi->stack->buffer;
|
GinBtreeStack *stack;
|
||||||
|
|
||||||
|
ginPrepareDataScan(&btree, index);
|
||||||
|
|
||||||
|
btree.fullScan = TRUE;
|
||||||
|
|
||||||
|
stack = ginFindLeafPage(&btree, rootBlkno, TRUE);
|
||||||
|
|
||||||
|
return stack;
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ entryLocateEntry(GinBtree btree, GinBtreeStack *stack)
|
|||||||
{
|
{
|
||||||
stack->off = FirstOffsetNumber;
|
stack->off = FirstOffsetNumber;
|
||||||
stack->predictNumber *= PageGetMaxOffsetNumber(page);
|
stack->predictNumber *= PageGetMaxOffsetNumber(page);
|
||||||
return btree->getLeftMostPage(btree, page);
|
return btree->getLeftMostChild(btree, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
low = FirstOffsetNumber;
|
low = FirstOffsetNumber;
|
||||||
@ -729,16 +729,15 @@ ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
|
|||||||
btree->ginstate = ginstate;
|
btree->ginstate = ginstate;
|
||||||
|
|
||||||
btree->findChildPage = entryLocateEntry;
|
btree->findChildPage = entryLocateEntry;
|
||||||
|
btree->getLeftMostChild = entryGetLeftMostPage;
|
||||||
btree->isMoveRight = entryIsMoveRight;
|
btree->isMoveRight = entryIsMoveRight;
|
||||||
btree->findItem = entryLocateLeafEntry;
|
btree->findItem = entryLocateLeafEntry;
|
||||||
btree->findChildPtr = entryFindChildPtr;
|
btree->findChildPtr = entryFindChildPtr;
|
||||||
btree->getLeftMostPage = entryGetLeftMostPage;
|
|
||||||
btree->placeToPage = entryPlaceToPage;
|
btree->placeToPage = entryPlaceToPage;
|
||||||
btree->splitPage = entrySplitPage;
|
btree->splitPage = entrySplitPage;
|
||||||
btree->fillRoot = ginEntryFillRoot;
|
btree->fillRoot = ginEntryFillRoot;
|
||||||
|
|
||||||
btree->isData = FALSE;
|
btree->isData = FALSE;
|
||||||
btree->searchMode = FALSE;
|
|
||||||
btree->fullScan = FALSE;
|
btree->fullScan = FALSE;
|
||||||
btree->isBuild = FALSE;
|
btree->isBuild = FALSE;
|
||||||
|
|
||||||
|
@ -124,18 +124,16 @@ static void
|
|||||||
scanPostingTree(Relation index, GinScanEntry scanEntry,
|
scanPostingTree(Relation index, GinScanEntry scanEntry,
|
||||||
BlockNumber rootPostingTree)
|
BlockNumber rootPostingTree)
|
||||||
{
|
{
|
||||||
GinPostingTreeScan *gdi;
|
GinBtreeStack *stack;
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
Page page;
|
Page page;
|
||||||
|
|
||||||
/* Descend to the leftmost leaf page */
|
/* Descend to the leftmost leaf page */
|
||||||
gdi = ginPrepareScanPostingTree(index, rootPostingTree, TRUE);
|
stack = ginScanBeginPostingTree(index, rootPostingTree);
|
||||||
|
buffer = stack->buffer;
|
||||||
buffer = ginScanBeginPostingTree(gdi);
|
|
||||||
IncrBufferRefCount(buffer); /* prevent unpin in freeGinBtreeStack */
|
IncrBufferRefCount(buffer); /* prevent unpin in freeGinBtreeStack */
|
||||||
|
|
||||||
freeGinBtreeStack(gdi->stack);
|
freeGinBtreeStack(stack);
|
||||||
pfree(gdi);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop iterates through all leaf pages of posting tree
|
* Loop iterates through all leaf pages of posting tree
|
||||||
@ -376,8 +374,7 @@ restartScanEntry:
|
|||||||
ginPrepareEntryScan(&btreeEntry, entry->attnum,
|
ginPrepareEntryScan(&btreeEntry, entry->attnum,
|
||||||
entry->queryKey, entry->queryCategory,
|
entry->queryKey, entry->queryCategory,
|
||||||
ginstate);
|
ginstate);
|
||||||
btreeEntry.searchMode = TRUE;
|
stackEntry = ginFindLeafPage(&btreeEntry, GIN_ROOT_BLKNO, true);
|
||||||
stackEntry = ginFindLeafPage(&btreeEntry, NULL);
|
|
||||||
page = BufferGetPage(stackEntry->buffer);
|
page = BufferGetPage(stackEntry->buffer);
|
||||||
needUnlock = TRUE;
|
needUnlock = TRUE;
|
||||||
|
|
||||||
@ -427,7 +424,7 @@ restartScanEntry:
|
|||||||
if (GinIsPostingTree(itup))
|
if (GinIsPostingTree(itup))
|
||||||
{
|
{
|
||||||
BlockNumber rootPostingTree = GinGetPostingTree(itup);
|
BlockNumber rootPostingTree = GinGetPostingTree(itup);
|
||||||
GinPostingTreeScan *gdi;
|
GinBtreeStack *stack;
|
||||||
Page page;
|
Page page;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -439,9 +436,9 @@ restartScanEntry:
|
|||||||
*/
|
*/
|
||||||
LockBuffer(stackEntry->buffer, GIN_UNLOCK);
|
LockBuffer(stackEntry->buffer, GIN_UNLOCK);
|
||||||
needUnlock = FALSE;
|
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
|
* We keep buffer pinned because we need to prevent deletion of
|
||||||
@ -451,7 +448,7 @@ restartScanEntry:
|
|||||||
IncrBufferRefCount(entry->buffer);
|
IncrBufferRefCount(entry->buffer);
|
||||||
|
|
||||||
page = BufferGetPage(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
|
* Keep page content in memory to prevent durable page locking
|
||||||
@ -463,8 +460,7 @@ restartScanEntry:
|
|||||||
GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
|
GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
|
||||||
|
|
||||||
LockBuffer(entry->buffer, GIN_UNLOCK);
|
LockBuffer(entry->buffer, GIN_UNLOCK);
|
||||||
freeGinBtreeStack(gdi->stack);
|
freeGinBtreeStack(stack);
|
||||||
pfree(gdi);
|
|
||||||
entry->isFinished = FALSE;
|
entry->isFinished = FALSE;
|
||||||
}
|
}
|
||||||
else if (GinGetNPosting(itup) > 0)
|
else if (GinGetNPosting(itup) > 0)
|
||||||
|
@ -81,7 +81,6 @@ addItemPointersToLeafTuple(GinState *ginstate,
|
|||||||
{
|
{
|
||||||
/* posting list would be too big, convert to posting tree */
|
/* posting list would be too big, convert to posting tree */
|
||||||
BlockNumber postingRoot;
|
BlockNumber postingRoot;
|
||||||
GinPostingTreeScan *gdi;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize posting tree with the old tuple's posting list. It's
|
* Initialize posting tree with the old tuple's posting list. It's
|
||||||
@ -94,12 +93,9 @@ addItemPointersToLeafTuple(GinState *ginstate,
|
|||||||
buildStats);
|
buildStats);
|
||||||
|
|
||||||
/* Now insert the TIDs-to-be-added into the posting tree */
|
/* Now insert the TIDs-to-be-added into the posting tree */
|
||||||
gdi = ginPrepareScanPostingTree(ginstate->index, postingRoot, FALSE);
|
ginInsertItemPointers(ginstate->index, postingRoot,
|
||||||
gdi->btree.isBuild = (buildStats != NULL);
|
items, nitem,
|
||||||
|
buildStats);
|
||||||
ginInsertItemPointers(gdi, items, nitem, buildStats);
|
|
||||||
|
|
||||||
pfree(gdi);
|
|
||||||
|
|
||||||
/* And build a new posting-tree-only result tuple */
|
/* And build a new posting-tree-only result tuple */
|
||||||
res = GinFormTuple(ginstate, attnum, key, category, NULL, 0, true);
|
res = GinFormTuple(ginstate, attnum, key, category, NULL, 0, true);
|
||||||
@ -177,7 +173,7 @@ ginEntryInsert(GinState *ginstate,
|
|||||||
|
|
||||||
ginPrepareEntryScan(&btree, attnum, key, category, ginstate);
|
ginPrepareEntryScan(&btree, attnum, key, category, ginstate);
|
||||||
|
|
||||||
stack = ginFindLeafPage(&btree, NULL);
|
stack = ginFindLeafPage(&btree, GIN_ROOT_BLKNO, false);
|
||||||
page = BufferGetPage(stack->buffer);
|
page = BufferGetPage(stack->buffer);
|
||||||
|
|
||||||
if (btree.findItem(&btree, stack))
|
if (btree.findItem(&btree, stack))
|
||||||
@ -189,18 +185,15 @@ ginEntryInsert(GinState *ginstate,
|
|||||||
{
|
{
|
||||||
/* add entries to existing posting tree */
|
/* add entries to existing posting tree */
|
||||||
BlockNumber rootPostingTree = GinGetPostingTree(itup);
|
BlockNumber rootPostingTree = GinGetPostingTree(itup);
|
||||||
GinPostingTreeScan *gdi;
|
|
||||||
|
|
||||||
/* release all stack */
|
/* release all stack */
|
||||||
LockBuffer(stack->buffer, GIN_UNLOCK);
|
LockBuffer(stack->buffer, GIN_UNLOCK);
|
||||||
freeGinBtreeStack(stack);
|
freeGinBtreeStack(stack);
|
||||||
|
|
||||||
/* insert into posting tree */
|
/* insert into posting tree */
|
||||||
gdi = ginPrepareScanPostingTree(ginstate->index, rootPostingTree, FALSE);
|
ginInsertItemPointers(ginstate->index, rootPostingTree,
|
||||||
gdi->btree.isBuild = (buildStats != NULL);
|
items, nitem,
|
||||||
ginInsertItemPointers(gdi, items, nitem, buildStats);
|
buildStats);
|
||||||
pfree(gdi);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,18 +479,17 @@ typedef struct GinBtreeData
|
|||||||
{
|
{
|
||||||
/* search methods */
|
/* search methods */
|
||||||
BlockNumber (*findChildPage) (GinBtree, GinBtreeStack *);
|
BlockNumber (*findChildPage) (GinBtree, GinBtreeStack *);
|
||||||
|
BlockNumber (*getLeftMostChild) (GinBtree, Page);
|
||||||
bool (*isMoveRight) (GinBtree, Page);
|
bool (*isMoveRight) (GinBtree, Page);
|
||||||
bool (*findItem) (GinBtree, GinBtreeStack *);
|
bool (*findItem) (GinBtree, GinBtreeStack *);
|
||||||
|
|
||||||
/* insert methods */
|
/* insert methods */
|
||||||
OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber);
|
OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber);
|
||||||
BlockNumber (*getLeftMostPage) (GinBtree, Page);
|
|
||||||
bool (*placeToPage) (GinBtree, Buffer, OffsetNumber, XLogRecData **);
|
bool (*placeToPage) (GinBtree, Buffer, OffsetNumber, XLogRecData **);
|
||||||
Page (*splitPage) (GinBtree, Buffer, Buffer, OffsetNumber, XLogRecData **);
|
Page (*splitPage) (GinBtree, Buffer, Buffer, OffsetNumber, XLogRecData **);
|
||||||
void (*fillRoot) (GinBtree, Buffer, Buffer, Buffer);
|
void (*fillRoot) (GinBtree, Buffer, Buffer, Buffer);
|
||||||
|
|
||||||
bool isData;
|
bool isData;
|
||||||
bool searchMode;
|
|
||||||
|
|
||||||
Relation index;
|
Relation index;
|
||||||
GinState *ginstate; /* not valid in a data scan */
|
GinState *ginstate; /* not valid in a data scan */
|
||||||
@ -514,8 +513,7 @@ typedef struct GinBtreeData
|
|||||||
PostingItem pitem;
|
PostingItem pitem;
|
||||||
} GinBtreeData;
|
} GinBtreeData;
|
||||||
|
|
||||||
extern GinBtreeStack *ginPrepareFindLeafPage(GinBtree btree, BlockNumber blkno);
|
extern GinBtreeStack *ginFindLeafPage(GinBtree btree, BlockNumber rootBlkno, bool searchMode);
|
||||||
extern GinBtreeStack *ginFindLeafPage(GinBtree btree, GinBtreeStack *stack);
|
|
||||||
extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode);
|
extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode);
|
||||||
extern void freeGinBtreeStack(GinBtreeStack *stack);
|
extern void freeGinBtreeStack(GinBtreeStack *stack);
|
||||||
extern void ginInsertValue(GinBtree btree, 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 GinDataPageAddItemPointer(Page page, ItemPointer data, OffsetNumber offset);
|
||||||
extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset);
|
extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset);
|
||||||
extern void GinPageDeletePostingItem(Page page, OffsetNumber offset);
|
extern void GinPageDeletePostingItem(Page page, OffsetNumber offset);
|
||||||
|
extern void ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GinBtreeData btree;
|
|
||||||
GinBtreeStack *stack;
|
|
||||||
} GinPostingTreeScan;
|
|
||||||
|
|
||||||
extern GinPostingTreeScan *ginPrepareScanPostingTree(Relation index,
|
|
||||||
BlockNumber rootBlkno, bool searchMode);
|
|
||||||
extern void ginInsertItemPointers(GinPostingTreeScan *gdi,
|
|
||||||
ItemPointerData *items, uint32 nitem,
|
ItemPointerData *items, uint32 nitem,
|
||||||
GinStatsData *buildStats);
|
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 ginDataFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf);
|
||||||
extern void ginPrepareDataScan(GinBtree btree, Relation index);
|
extern void ginPrepareDataScan(GinBtree btree, Relation index);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user