mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
First steps towards index scans with heap access decoupled from index
access: define new index access method functions 'amgetmulti' that can fetch multiple TIDs per call. (The functions exist but are totally untested as yet.) Since I was modifying pg_am anyway, remove the no-longer-needed 'rel' parameter from amcostestimate functions, and also remove the vestigial amowner column that was creating useless work for Alvaro's shared-object-dependencies project. Initdb forced due to changes in pg_am.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.77 2005/03/21 01:23:57 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/hash/hash.c,v 1.78 2005/03/27 23:52:57 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* This file contains only the public interface routines.
|
||||
@@ -264,6 +264,75 @@ hashgettuple(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hashgetmulti() -- get multiple tuples at once
|
||||
*
|
||||
* This is a somewhat generic implementation: it avoids lock reacquisition
|
||||
* overhead, but there's no smarts about picking especially good stopping
|
||||
* points such as index page boundaries.
|
||||
*/
|
||||
Datum
|
||||
hashgetmulti(PG_FUNCTION_ARGS)
|
||||
{
|
||||
IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
|
||||
ItemPointer tids = (ItemPointer) PG_GETARG_POINTER(1);
|
||||
int32 max_tids = PG_GETARG_INT32(2);
|
||||
int32 *returned_tids = (int32 *) PG_GETARG_POINTER(3);
|
||||
HashScanOpaque so = (HashScanOpaque) scan->opaque;
|
||||
Relation rel = scan->indexRelation;
|
||||
bool res = true;
|
||||
int32 ntids = 0;
|
||||
|
||||
/*
|
||||
* We hold pin but not lock on current buffer while outside the hash
|
||||
* AM. Reacquire the read lock here.
|
||||
*/
|
||||
if (BufferIsValid(so->hashso_curbuf))
|
||||
_hash_chgbufaccess(rel, so->hashso_curbuf, HASH_NOLOCK, HASH_READ);
|
||||
|
||||
while (ntids < max_tids)
|
||||
{
|
||||
/*
|
||||
* Start scan, or advance to next tuple.
|
||||
*/
|
||||
if (ItemPointerIsValid(&(scan->currentItemData)))
|
||||
res = _hash_next(scan, ForwardScanDirection);
|
||||
else
|
||||
res = _hash_first(scan, ForwardScanDirection);
|
||||
/*
|
||||
* Skip killed tuples if asked to.
|
||||
*/
|
||||
if (scan->ignore_killed_tuples)
|
||||
{
|
||||
while (res)
|
||||
{
|
||||
Page page;
|
||||
OffsetNumber offnum;
|
||||
|
||||
offnum = ItemPointerGetOffsetNumber(&(scan->currentItemData));
|
||||
page = BufferGetPage(so->hashso_curbuf);
|
||||
if (!ItemIdDeleted(PageGetItemId(page, offnum)))
|
||||
break;
|
||||
res = _hash_next(scan, ForwardScanDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (!res)
|
||||
break;
|
||||
/* Save tuple ID, and continue scanning */
|
||||
tids[ntids] = scan->xs_ctup.t_self;
|
||||
ntids++;
|
||||
}
|
||||
|
||||
/* Release read lock on current buffer, but keep it pinned */
|
||||
if (BufferIsValid(so->hashso_curbuf))
|
||||
_hash_chgbufaccess(rel, so->hashso_curbuf, HASH_READ, HASH_NOLOCK);
|
||||
|
||||
*returned_tids = ntids;
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hashbeginscan() -- start a scan on a hash index
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user