/* * Inserts array of item pointers, may execute several tree scan (very rare) */ void ginInsertItemPointers(Relation index, BlockNumber rootBlkno, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats) { GinBtreeData btree; GinBtreeDataLeafInsertData insertdata; GinBtreeStack *stack; ginPrepareDataScan(&btree, index, rootBlkno); btree.isBuild = (buildStats != NULL); insertdata.items = items; insertdata.nitem = nitem; insertdata.curitem = 0; while (insertdata.curitem < insertdata.nitem) { /* search for the leaf page where the first item should go to */ btree.itemptr = insertdata.items[insertdata.curitem]; stack = ginFindLeafPage(&btree, false); if (btree.findItem(&btree, stack)) { /* * Current item already exists in index. */ insertdata.curitem++; LockBuffer(stack->buffer, GIN_UNLOCK); freeGinBtreeStack(stack); } else ginInsertValue(&btree, stack, &insertdata, buildStats); } }
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; }
/* * Starts a new scan on a posting tree. */ GinBtreeStack * ginScanBeginPostingTree(Relation index, BlockNumber rootBlkno) { GinBtreeData btree; GinBtreeStack *stack; ginPrepareDataScan(&btree, index, rootBlkno); btree.fullScan = TRUE; stack = ginFindLeafPage(&btree, TRUE); return stack; }