aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-12-07 19:37:53 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-12-07 19:37:53 +0000
commitcefcbbf1fd43c80201e8e6fd36ac6fb00bd10825 (patch)
tree2e4e5c7996d69fa79f59844ae1144892e14fa90e /src
parentf1b059af12673abf93ba13594799732bac83ed01 (diff)
downloadpostgresql-cefcbbf1fd43c80201e8e6fd36ac6fb00bd10825.tar.gz
postgresql-cefcbbf1fd43c80201e8e6fd36ac6fb00bd10825.zip
Push the responsibility for handling ignore_killed_tuples down into
_bt_checkkeys(), instead of checking it in the top-level nbtree.c routines as formerly. This saves a little bit of loop overhead, but more importantly it lets us skip performing the index key comparisons for dead tuples.
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/nbtree/nbtree.c41
-rw-r--r--src/backend/access/nbtree/nbtsearch.c24
-rw-r--r--src/backend/access/nbtree/nbtutils.c72
-rw-r--r--src/include/access/nbtree.h7
4 files changed, 72 insertions, 72 deletions
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 70aca882e6c..589a49a2cea 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.134 2005/11/22 18:17:06 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.135 2005/12/07 19:37:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -289,21 +289,6 @@ btgettuple(PG_FUNCTION_ARGS)
res = _bt_first(scan, dir);
/*
- * Skip killed tuples if asked to.
- */
- if (scan->ignore_killed_tuples)
- {
- while (res)
- {
- offnum = ItemPointerGetOffsetNumber(&(scan->currentItemData));
- page = BufferGetPage(so->btso_curbuf);
- if (!ItemIdDeleted(PageGetItemId(page, offnum)))
- break;
- res = _bt_next(scan, dir);
- }
- }
-
- /*
* Save heap TID to use it in _bt_restscan. Then release the read lock on
* the buffer so that we aren't blocking other backends.
*
@@ -353,25 +338,6 @@ btgetmulti(PG_FUNCTION_ARGS)
res = _bt_next(scan, ForwardScanDirection);
else
res = _bt_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->btso_curbuf);
- if (!ItemIdDeleted(PageGetItemId(page, offnum)))
- break;
- res = _bt_next(scan, ForwardScanDirection);
- }
- }
-
if (!res)
break;
/* Save tuple ID, and continue scanning */
@@ -385,9 +351,8 @@ btgetmulti(PG_FUNCTION_ARGS)
*/
if (res)
{
- ((BTScanOpaque) scan->opaque)->curHeapIptr = scan->xs_ctup.t_self;
- LockBuffer(((BTScanOpaque) scan->opaque)->btso_curbuf,
- BUFFER_LOCK_UNLOCK);
+ so->curHeapIptr = scan->xs_ctup.t_self;
+ LockBuffer(so->btso_curbuf, BUFFER_LOCK_UNLOCK);
}
*returned_tids = ntids;
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index dd4f500842b..4cd79997292 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.98 2005/12/07 18:03:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.99 2005/12/07 19:37:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -423,8 +423,6 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
Page page;
OffsetNumber offnum;
ItemPointer current;
- BTItem btitem;
- IndexTuple itup;
BTScanOpaque so;
bool continuescan;
@@ -445,13 +443,10 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
/* current is the next candidate tuple to return */
offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf);
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &btitem->bti_itup;
- if (_bt_checkkeys(scan, itup, dir, &continuescan))
+ if (_bt_checkkeys(scan, page, offnum, dir, &continuescan))
{
/* tuple passes all scan key conditions, so return it */
- scan->xs_ctup.t_self = itup->t_tid;
return true;
}
@@ -485,8 +480,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
Page page;
BTStack stack;
OffsetNumber offnum;
- BTItem btitem;
- IndexTuple itup;
ItemPointer current;
BlockNumber blkno;
StrategyNumber strat;
@@ -848,14 +841,11 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
/* okay, current item pointer for the scan is right */
offnum = ItemPointerGetOffsetNumber(current);
page = BufferGetPage(buf);
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
- itup = &btitem->bti_itup;
/* is the first item actually acceptable? */
- if (_bt_checkkeys(scan, itup, dir, &continuescan))
+ if (_bt_checkkeys(scan, page, offnum, dir, &continuescan))
{
/* yes, return it */
- scan->xs_ctup.t_self = itup->t_tid;
res = true;
}
else if (continuescan)
@@ -1215,8 +1205,6 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
OffsetNumber maxoff;
OffsetNumber start;
BlockNumber blkno;
- BTItem btitem;
- IndexTuple itup;
BTScanOpaque so;
bool res;
bool continuescan;
@@ -1284,16 +1272,12 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
page = BufferGetPage(buf);
}
- btitem = (BTItem) PageGetItem(page, PageGetItemId(page, start));
- itup = &(btitem->bti_itup);
-
/*
* Okay, we are on the first or last tuple. Does it pass all the quals?
*/
- if (_bt_checkkeys(scan, itup, dir, &continuescan))
+ if (_bt_checkkeys(scan, page, start, dir, &continuescan))
{
/* yes, return it */
- scan->xs_ctup.t_self = itup->t_tid;
res = true;
}
else if (continuescan)
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index f4c2243943b..7a18fcf0abb 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.66 2005/11/22 18:17:06 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.67 2005/12/07 19:37:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -477,30 +477,77 @@ _bt_preprocess_keys(IndexScanDesc scan)
/*
* Test whether an indextuple satisfies all the scankey conditions.
*
+ * If so, copy its TID into scan->xs_ctup.t_self, and return TRUE.
+ * If not, return FALSE (xs_ctup is not changed).
+ *
* If the tuple fails to pass the qual, we also determine whether there's
* any need to continue the scan beyond this tuple, and set *continuescan
* accordingly. See comments for _bt_preprocess_keys(), above, about how
* this is done.
+ *
+ * scan: index scan descriptor
+ * page: buffer page containing index tuple
+ * offnum: offset number of index tuple (must be a valid item!)
+ * dir: direction we are scanning in
+ * continuescan: output parameter (will be set correctly in all cases)
*/
bool
-_bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
+_bt_checkkeys(IndexScanDesc scan,
+ Page page, OffsetNumber offnum,
ScanDirection dir, bool *continuescan)
{
- BTScanOpaque so = (BTScanOpaque) scan->opaque;
- int keysz = so->numberOfKeys;
- int ikey;
+ ItemId iid = PageGetItemId(page, offnum);
+ bool tuple_valid;
+ BTItem btitem;
+ IndexTuple tuple;
TupleDesc tupdesc;
+ BTScanOpaque so;
+ int keysz;
+ int ikey;
ScanKey key;
- *continuescan = true;
+ *continuescan = true; /* default assumption */
+
+ /*
+ * If the scan specifies not to return killed tuples, then we treat
+ * a killed tuple as not passing the qual. Most of the time, it's a
+ * win to not bother examining the tuple's index keys, but just return
+ * immediately with continuescan = true to proceed to the next tuple.
+ * However, if this is the last tuple on the page, we should check
+ * the index keys to prevent uselessly advancing to the next page.
+ */
+ if (scan->ignore_killed_tuples && ItemIdDeleted(iid))
+ {
+ /* return immediately if there are more tuples on the page */
+ if (ScanDirectionIsForward(dir))
+ {
+ if (offnum < PageGetMaxOffsetNumber(page))
+ return false;
+ }
+ else
+ {
+ BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page);
+
+ if (offnum > P_FIRSTDATAKEY(opaque))
+ return false;
+ }
+ /*
+ * OK, we want to check the keys, but we'll return FALSE even
+ * if the tuple passes the key tests.
+ */
+ tuple_valid = false;
+ }
+ else
+ tuple_valid = true;
- /* If no keys, always scan the whole index */
- if (keysz == 0)
- return true;
+ btitem = (BTItem) PageGetItem(page, iid);
+ tuple = &btitem->bti_itup;
IncrIndexProcessed();
tupdesc = RelationGetDescr(scan->indexRelation);
+ so = (BTScanOpaque) scan->opaque;
+ keysz = so->numberOfKeys;
for (key = so->keyData, ikey = 0; ikey < keysz; key++, ikey++)
{
@@ -592,6 +639,9 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
}
}
- /* If we get here, the tuple passes all quals. */
- return true;
+ /* If we get here, the tuple passes all index quals. */
+ if (tuple_valid)
+ scan->xs_ctup.t_self = tuple->t_tid;
+
+ return tuple_valid;
}
diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h
index 9cd00d554da..5a3ec5f1efe 100644
--- a/src/include/access/nbtree.h
+++ b/src/include/access/nbtree.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.88 2005/11/06 19:29:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.89 2005/12/07 19:37:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -467,8 +467,9 @@ extern ScanKey _bt_mkscankey_nodata(Relation rel);
extern void _bt_freeskey(ScanKey skey);
extern void _bt_freestack(BTStack stack);
extern void _bt_preprocess_keys(IndexScanDesc scan);
-extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
- ScanDirection dir, bool *continuescan);
+extern bool _bt_checkkeys(IndexScanDesc scan,
+ Page page, OffsetNumber offnum,
+ ScanDirection dir, bool *continuescan);
extern BTItem _bt_formitem(IndexTuple itup);
/*