コード例 #1
0
/*
 * Inserts array of item pointers, may execute several tree scan (very rare)
 */
void
ginInsertItemPointers(GinPostingTreeScan *gdi,
                      ItemPointerData *items, uint32 nitem,
                      GinStatsData *buildStats)
{
    BlockNumber rootBlkno = gdi->stack->blkno;

    gdi->btree.items = items;
    gdi->btree.nitem = nitem;
    gdi->btree.curitem = 0;

    while (gdi->btree.curitem < gdi->btree.nitem)
    {
        if (!gdi->stack)
            gdi->stack = ginPrepareFindLeafPage(&gdi->btree, rootBlkno);

        gdi->stack = ginFindLeafPage(&gdi->btree, gdi->stack);

        if (gdi->btree.findItem(&(gdi->btree), gdi->stack))
        {
            /*
             * gdi->btree.items[gdi->btree.curitem] already exists in index
             */
            gdi->btree.curitem++;
            LockBuffer(gdi->stack->buffer, GIN_UNLOCK);
            freeGinBtreeStack(gdi->stack);
        }
        else
            ginInsertValue(&(gdi->btree), gdi->stack, buildStats);

        gdi->stack = NULL;
    }
}
コード例 #2
0
/*
 * Inserts array of item pointers, may execute several tree scan (very rare)
 */
void
insertItemPointer(GinPostingTreeScan *gdi, ItemPointerData *items, uint32 nitem)
{
	BlockNumber rootBlkno = gdi->stack->blkno;

	gdi->btree.items = items;
	gdi->btree.nitem = nitem;
	gdi->btree.curitem = 0;

	while (gdi->btree.curitem < gdi->btree.nitem)
	{
		if (!gdi->stack)
			gdi->stack = ginPrepareFindLeafPage(&gdi->btree, rootBlkno);

		gdi->stack = ginFindLeafPage(&gdi->btree, gdi->stack);

		if (gdi->btree.findItem(&(gdi->btree), gdi->stack))
			elog(ERROR, "item pointer (%u,%d) already exists",
			ItemPointerGetBlockNumber(gdi->btree.items + gdi->btree.curitem),
				 ItemPointerGetOffsetNumber(gdi->btree.items + gdi->btree.curitem));

		ginInsertValue(&(gdi->btree), gdi->stack);

		gdi->stack = NULL;
	}
}
コード例 #3
0
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;
}
コード例 #4
0
ファイル: ginbtree.c プロジェクト: Epictetus/postgres
/*
 * Locates leaf page contained tuple
 */
GinBtreeStack *
ginFindLeafPage(GinBtree btree, GinBtreeStack *stack)
{
	bool		isfirst = TRUE;
	BlockNumber rootBlkno;

	if (!stack)
		stack = ginPrepareFindLeafPage(btree, GIN_ROOT_BLKNO);
	rootBlkno = stack->blkno;

	for (;;)
	{
		Page		page;
		BlockNumber child;
		int			access = GIN_SHARE;

		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);

		/*
		 * ok, page is correctly locked, we should check to move right ..,
		 * root never has a right link, so small optimization
		 */
		while (btree->fullScan == FALSE && stack->blkno != rootBlkno &&
			   btree->isMoveRight(btree, page))
		{
			BlockNumber rightlink = GinPageGetOpaque(page)->rightlink;

			if (rightlink == InvalidBlockNumber)
				/* rightmost page */
				break;

			stack->blkno = rightlink;
			LockBuffer(stack->buffer, GIN_UNLOCK);
			stack->buffer = ReleaseAndReadBuffer(stack->buffer, btree->index, stack->blkno);
			LockBuffer(stack->buffer, access);
			page = BufferGetPage(stack->buffer);
		}

		if (GinPageIsLeaf(page))	/* we found, return locked page */
			return stack;

		/* now we have correct buffer, try to find child */
		child = btree->findChildPage(btree, stack);

		LockBuffer(stack->buffer, GIN_UNLOCK);
		Assert(child != InvalidBlockNumber);
		Assert(stack->blkno != child);

		if (btree->searchMode)
		{
			/* in search mode we may forget path to leaf */
			stack->blkno = child;
			stack->buffer = ReleaseAndReadBuffer(stack->buffer, btree->index, stack->blkno);
		}
		else
		{
			GinBtreeStack *ptr = (GinBtreeStack *) palloc(sizeof(GinBtreeStack));

			ptr->parent = stack;
			stack = ptr;
			stack->blkno = child;
			stack->buffer = ReadBuffer(btree->index, stack->blkno);
			stack->predictNumber = 1;
		}
	}

	/* keep compiler happy */
	return NULL;
}