Example #1
0
/*
 * gistgetbitmap() -- Get a bitmap of all heap tuple locations
 */
Datum
gistgetbitmap(PG_FUNCTION_ARGS)
{
	IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
	Node	   *n = (Node *) PG_GETARG_POINTER(1);
	TIDBitmap  *tbm;
	GISTScanOpaque so = (GISTScanOpaque) scan->opaque;
	int64		ntids = 0;
	GISTSearchItem fakeItem;

	if (n == NULL)
		tbm = tbm_create(work_mem * 1024L);
	else if (!IsA(n, TIDBitmap))
		elog(ERROR, "non hash bitmap");
	else
		tbm = (TIDBitmap *) n;

	if (!so->qual_ok)
		PG_RETURN_POINTER(tbm);

	pgstat_count_index_scan(scan->indexRelation);

	/* Begin the scan by processing the root page */
	so->curTreeItem = NULL;
	so->curPageData = so->nPageData = 0;

	fakeItem.blkno = GIST_ROOT_BLKNO;
	memset(&fakeItem.data.parentlsn, 0, sizeof(GistNSN));
	gistScanPage(scan, &fakeItem, NULL, tbm, &ntids);

	/*
	 * While scanning a leaf page, ItemPointers of matching heap tuples will
	 * be stored directly into tbm, so we don't need to deal with them here.
	 */
	for (;;)
	{
		GISTSearchItem *item = getNextGISTSearchItem(so);

		if (!item)
			break;

		CHECK_FOR_INTERRUPTS();

		gistScanPage(scan, item, so->curTreeItem->distances, tbm, &ntids);

		pfree(item);
	}

	PG_RETURN_POINTER(tbm);
}
Example #2
0
File: gistget.c Project: 50wu/gpdb
Datum
gistgetmulti(PG_FUNCTION_ARGS)
{
	IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
	Node		   *n = (Node *) PG_GETARG_POINTER(1);
	HashBitmap	   *hashBitmap;
	ItemPointer tids;
	int ntids;

	if (n == NULL)
		hashBitmap = tbm_create(work_mem * 1024L);
	else if (!IsA(n, HashBitmap))
		elog(ERROR, "non hash bitmap");
	else
		hashBitmap = (HashBitmap *)n;

#define MAX_TIDS 1024
	tids = (ItemPointer)palloc0(MAX_TIDS * sizeof(ItemPointerData));

	while ((ntids = gistnext(scan, ForwardScanDirection, tids, MAX_TIDS, false)) > 0)
		tbm_add_tuples(hashBitmap, tids, ntids);

	PG_RETURN_POINTER(hashBitmap);
}
Example #3
0
/* ----------------------------------------------------------------
 *		MultiExecBitmapIndexScan(node)
 * ----------------------------------------------------------------
 */
Node *
MultiExecBitmapIndexScan(BitmapIndexScanState *node)
{
	TIDBitmap  *tbm;
	IndexScanDesc scandesc;
	double		nTuples = 0;
	bool		doscan;

	/* must provide our own instrumentation support */
	if (node->ss.ps.instrument)
		InstrStartNode(node->ss.ps.instrument);

	/*
	 * extract necessary information from index scan node
	 */
	scandesc = node->biss_ScanDesc;

	/*
	 * If we have runtime keys and they've not already been set up, do it now.
	 * Array keys are also treated as runtime keys; note that if ExecReScan
	 * returns with biss_RuntimeKeysReady still false, then there is an empty
	 * array key so we should do nothing.
	 */
	if (!node->biss_RuntimeKeysReady &&
		(node->biss_NumRuntimeKeys != 0 || node->biss_NumArrayKeys != 0))
	{
		ExecReScan((PlanState *) node);
		doscan = node->biss_RuntimeKeysReady;
	}
	else
		doscan = true;

	/*
	 * Prepare the result bitmap.  Normally we just create a new one to pass
	 * back; however, our parent node is allowed to store a pre-made one into
	 * node->biss_result, in which case we just OR our tuple IDs into the
	 * existing bitmap.  (This saves needing explicit UNION steps.)
	 */
	if (node->biss_result)
	{
		tbm = node->biss_result;
		node->biss_result = NULL;		/* reset for next time */
	}
	else
	{
		/* XXX should we use less than work_mem for this? */
		tbm = tbm_create(work_mem * 1024L);
	}

	/*
	 * Get TIDs from index and insert into bitmap
	 */
	while (doscan)
	{
		nTuples += (double) index_getbitmap(scandesc, tbm);

		CHECK_FOR_INTERRUPTS();

		doscan = ExecIndexAdvanceArrayKeys(node->biss_ArrayKeys,
										   node->biss_NumArrayKeys);
		if (doscan)				/* reset index scan */
			index_rescan(node->biss_ScanDesc,
						 node->biss_ScanKeys, node->biss_NumScanKeys,
						 NULL, 0);
	}

	/* must provide our own instrumentation support */
	if (node->ss.ps.instrument)
		InstrStopNode(node->ss.ps.instrument, nTuples);

	return (Node *) tbm;
}
Example #4
0
File: nbtree.c Project: LJoNe/gpdb
/*
 * btgetmulti() -- construct a HashBitmap.
 */
Datum
btgetmulti(PG_FUNCTION_ARGS)
{
	MIRROREDLOCK_BUFMGR_VERIFY_NO_LOCK_LEAK_DECLARE;

	IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
	Node *n = (Node *)PG_GETARG_POINTER(1);
	HashBitmap	*hashBitmap;

	BTScanOpaque so = (BTScanOpaque) scan->opaque;
	bool		res = true;

	MIRROREDLOCK_BUFMGR_VERIFY_NO_LOCK_LEAK_ENTER;

	if (n == NULL || IsA(n, StreamBitmap))
	{
		/* XXX should we use less than work_mem for this? */
		hashBitmap = tbm_create(work_mem * 1024L);
	}
	else
	{
		hashBitmap = (HashBitmap *)n;
	}
	/* If we haven't started the scan yet, fetch the first page & tuple. */
	if (!BTScanPosIsValid(so->currPos))
	{
		res = _bt_first(scan, ForwardScanDirection);
		if (res)
		{
			/* Save tuple ID, and continue scanning */
			tbm_add_tuples(hashBitmap, &(scan->xs_ctup.t_self), 1);
		}
	}

	while (res)
	{
		/*
		 * Advance to next tuple within page.  This is the same as the
		 * easy case in _bt_next().
		 */
		if (++so->currPos.itemIndex > so->currPos.lastItem)
		{
			/* let _bt_next do the heavy lifting */
			res = _bt_next(scan, ForwardScanDirection);
			if (!res)
				break;
		}

		/* Save tuple ID, and continue scanning */
		tbm_add_tuples(hashBitmap,
					   &(so->currPos.items[so->currPos.itemIndex].heapTid),
					   1);
	}

	if(n && IsA(n, StreamBitmap))
	{
		stream_add_node((StreamBitmap *)n,
			tbm_create_stream_node(hashBitmap), BMS_OR);
		PG_RETURN_POINTER(n);
	}

	MIRROREDLOCK_BUFMGR_VERIFY_NO_LOCK_LEAK_EXIT;

	PG_RETURN_POINTER(hashBitmap);
}
Example #5
0
/* ----------------------------------------------------------------
 *		MultiExecBitmapIndexScan(node)
 * ----------------------------------------------------------------
 */
Node *
MultiExecBitmapIndexScan(BitmapIndexScanState *node)
{
#define MAX_TIDS	1024
	TIDBitmap  *tbm = NULL;
	IndexScanDesc scandesc;
	IndexScanDesc odScanDesc;
	ItemPointerData tids[MAX_TIDS];
	int32		ntids;
	double		nTuples = 0;

	OnDiskBitmapWords *odbm = NULL;
	bool	inmem = false;

	/* must provide our own instrumentation support */
	if (node->ss.ps.instrument)
		InstrStartNode(node->ss.ps.instrument);

	/*
	 * extract necessary information from index scan node
	 */
	scandesc = node->biss_ScanDesc;
	odScanDesc = node->odbiss_ScanDesc;

	/*
	 * If we have runtime keys and they've not already been set up, do it
	 * now.
	 */
	if (node->biss_RuntimeKeyInfo && !node->biss_RuntimeKeysReady)
		ExecReScan((PlanState *) node, NULL);

	inmem = ((BitmapIndexScan*)((PlanState*)node)->plan)->inmem;

	if (inmem) {

		node->odbiss_result = NULL;

		/*
		 * Prepare the result bitmap.  Normally we just create a new one to pass
		 * back; however, our parent node is allowed to store a pre-made one
		 * into node->biss_result, in which case we just OR our tuple IDs into
		 * the existing bitmap.  (This saves needing explicit UNION steps.)
		 */
		if (node->biss_result)
		{
			tbm = node->biss_result;
			node->biss_result = NULL;		/* reset for next time */
		}
		else
		{
			/* XXX should we use less than work_mem for this? */
			tbm = tbm_create(work_mem * 1024L);
		}

		/*
	 	* Get TIDs from index and insert into bitmap
	 	*/
		for (;;)
		{
			bool	more = index_getmulti(scandesc, tids, MAX_TIDS, &ntids);

			if (ntids > 0)
			{
				tbm_add_tuples(tbm, tids, ntids);
				nTuples += ntids;
			}

			if (!more)
				break;

			CHECK_FOR_INTERRUPTS();
		}
	}

	else {
		node->biss_result = NULL;

		if (node->odbiss_result == NULL)
			node->odbiss_result = odbm_create(ODBM_MAX_WORDS);

		odbm = node->odbiss_result;

		index_getbitmapwords(odScanDesc, odbm->maxNumOfWords,
							&(odbm->numOfWords), 
							odbm->bitmapHeaderWords,
							odbm->bitmapContentWords);
	}

	/* must provide our own instrumentation support */
	if (node->ss.ps.instrument)
		InstrStopNodeMulti(node->ss.ps.instrument, nTuples);

	if (tbm != NULL)
		return (Node *) tbm;
	else
		return (Node *) odbm;
}