Commit c389760c authored by Tom Lane's avatar Tom Lane

Remove the no-longer-useful BTItem/BTItemData level of structure, and

just refer to btree index entries as plain IndexTuples, which is what
they have been for a very long time.  This is mostly just an exercise
in removing extraneous notation, but it does save a palloc/pfree cycle
per index insertion.
parent 9b012311
This diff is collapsed.
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.91 2006/01/17 00:09:01 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtpage.c,v 1.92 2006/01/25 23:04:20 tgl Exp $
*
* NOTES
* Postgres btree pages look like ordinary relation pages. The opaque
......@@ -766,8 +766,8 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
uint32 targetlevel,
ilevel;
ItemId itemid;
BTItem targetkey,
btitem;
IndexTuple targetkey,
itup;
ScanKey itup_scankey;
BTStack stack;
Buffer lbuf,
......@@ -803,7 +803,7 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
targetlevel = opaque->btpo.level;
leftsib = opaque->btpo_prev;
itemid = PageGetItemId(page, P_HIKEY);
targetkey = CopyBTItem((BTItem) PageGetItem(page, itemid));
targetkey = CopyIndexTuple((IndexTuple) PageGetItem(page, itemid));
/*
* We need to get an approximate pointer to the page's parent page. Use
......@@ -814,7 +814,7 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
*/
_bt_relbuf(rel, buf);
/* we need an insertion scan key to do our search, so build one */
itup_scankey = _bt_mkscankey(rel, &(targetkey->bti_itup));
itup_scankey = _bt_mkscankey(rel, targetkey);
/* find the leftmost leaf page containing this key */
stack = _bt_search(rel, rel->rd_rel->relnatts, itup_scankey, false,
&lbuf, BT_READ);
......@@ -908,8 +908,7 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
* Next find and write-lock the current parent of the target page. This is
* essentially the same as the corresponding step of splitting.
*/
ItemPointerSet(&(stack->bts_btitem.bti_itup.t_tid),
target, P_HIKEY);
ItemPointerSet(&(stack->bts_btentry.t_tid), target, P_HIKEY);
pbuf = _bt_getstackbuf(rel, stack, BT_WRITE);
if (pbuf == InvalidBuffer)
elog(ERROR, "failed to re-find parent key in \"%s\"",
......@@ -1008,15 +1007,15 @@ _bt_pagedel(Relation rel, Buffer buf, bool vacuum_full)
OffsetNumber nextoffset;
itemid = PageGetItemId(page, poffset);
btitem = (BTItem) PageGetItem(page, itemid);
Assert(ItemPointerGetBlockNumber(&(btitem->bti_itup.t_tid)) == target);
ItemPointerSet(&(btitem->bti_itup.t_tid), rightsib, P_HIKEY);
itup = (IndexTuple) PageGetItem(page, itemid);
Assert(ItemPointerGetBlockNumber(&(itup->t_tid)) == target);
ItemPointerSet(&(itup->t_tid), rightsib, P_HIKEY);
nextoffset = OffsetNumberNext(poffset);
/* This part is just for double-checking */
itemid = PageGetItemId(page, nextoffset);
btitem = (BTItem) PageGetItem(page, itemid);
if (ItemPointerGetBlockNumber(&(btitem->bti_itup.t_tid)) != rightsib)
itup = (IndexTuple) PageGetItem(page, itemid);
if (ItemPointerGetBlockNumber(&(itup->t_tid)) != rightsib)
elog(PANIC, "right sibling is not next child in \"%s\"",
RelationGetRelationName(rel));
PageIndexTupleDelete(page, nextoffset);
......
......@@ -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.135 2005/12/07 19:37:53 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.136 2006/01/25 23:04:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -167,14 +167,11 @@ btbuildCallback(Relation index,
{
BTBuildState *buildstate = (BTBuildState *) state;
IndexTuple itup;
BTItem btitem;
/* form an index tuple and point it at the heap tuple */
itup = index_form_tuple(RelationGetDescr(index), values, isnull);
itup->t_tid = htup->t_self;
btitem = _bt_formitem(itup);
/*
* if we are doing bottom-up btree build, we insert the index into a spool
* file for subsequent processing. otherwise, we insert into the btree.
......@@ -182,23 +179,22 @@ btbuildCallback(Relation index,
if (buildstate->usefast)
{
if (tupleIsAlive || buildstate->spool2 == NULL)
_bt_spool(btitem, buildstate->spool);
_bt_spool(itup, buildstate->spool);
else
{
/* dead tuples are put into spool2 */
buildstate->haveDead = true;
_bt_spool(btitem, buildstate->spool2);
_bt_spool(itup, buildstate->spool2);
}
}
else
{
_bt_doinsert(index, btitem,
_bt_doinsert(index, itup,
buildstate->isUnique, buildstate->heapRel);
}
buildstate->indtuples += 1;
pfree(btitem);
pfree(itup);
}
......@@ -217,17 +213,14 @@ btinsert(PG_FUNCTION_ARGS)
ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3);
Relation heapRel = (Relation) PG_GETARG_POINTER(4);
bool checkUnique = PG_GETARG_BOOL(5);
BTItem btitem;
IndexTuple itup;
/* generate an index tuple */
itup = index_form_tuple(RelationGetDescr(rel), values, isnull);
itup->t_tid = *ht_ctid;
btitem = _bt_formitem(itup);
_bt_doinsert(rel, btitem, checkUnique, heapRel);
_bt_doinsert(rel, itup, checkUnique, heapRel);
pfree(btitem);
pfree(itup);
PG_RETURN_BOOL(true);
......@@ -616,12 +609,12 @@ btbulkdelete(PG_FUNCTION_ARGS)
offnum <= maxoff;
offnum = OffsetNumberNext(offnum))
{
BTItem btitem;
IndexTuple itup;
ItemPointer htup;
btitem = (BTItem) PageGetItem(page,
PageGetItemId(page, offnum));
htup = &(btitem->bti_itup.t_tid);
itup = (IndexTuple)
PageGetItem(page, PageGetItemId(page, offnum));
htup = &(itup->t_tid);
if (callback(htup, callback_state))
{
deletable[ndeletable++] = offnum;
......@@ -872,7 +865,7 @@ _bt_restscan(IndexScanDesc scan)
BTPageOpaque opaque;
Buffer nextbuf;
ItemPointer target = &(so->curHeapIptr);
BTItem item;
IndexTuple itup;
BlockNumber blkno;
/*
......@@ -909,8 +902,8 @@ _bt_restscan(IndexScanDesc scan)
offnum <= maxoff;
offnum = OffsetNumberNext(offnum))
{
item = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
if (BTTidSame(item->bti_itup.t_tid, *target))
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
if (BTTidSame(itup->t_tid, *target))
{
/* Found it */
current->ip_posid = offnum;
......
......@@ -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.102 2006/01/25 20:29:23 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.103 2006/01/25 23:04:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -65,7 +65,6 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey,
BTPageOpaque opaque;
OffsetNumber offnum;
ItemId itemid;
BTItem btitem;
IndexTuple itup;
BlockNumber blkno;
BlockNumber par_blkno;
......@@ -90,8 +89,7 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey,
*/
offnum = _bt_binsrch(rel, *bufP, keysz, scankey, nextkey);
itemid = PageGetItemId(page, offnum);
btitem = (BTItem) PageGetItem(page, itemid);
itup = &(btitem->bti_itup);
itup = (IndexTuple) PageGetItem(page, itemid);
blkno = ItemPointerGetBlockNumber(&(itup->t_tid));
par_blkno = BufferGetBlockNumber(*bufP);
......@@ -108,7 +106,7 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey,
new_stack = (BTStack) palloc(sizeof(BTStackData));
new_stack->bts_blkno = par_blkno;
new_stack->bts_offset = offnum;
memcpy(&new_stack->bts_btitem, btitem, sizeof(BTItemData));
memcpy(&new_stack->bts_btentry, itup, sizeof(IndexTupleData));
new_stack->bts_parent = stack_in;
/* drop the read lock on the parent page, acquire one on the child */
......@@ -338,7 +336,6 @@ _bt_compare(Relation rel,
{
TupleDesc itupdesc = RelationGetDescr(rel);
BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page);
BTItem btitem;
IndexTuple itup;
int i;
......@@ -349,8 +346,7 @@ _bt_compare(Relation rel,
if (!P_ISLEAF(opaque) && offnum == P_FIRSTDATAKEY(opaque))
return 1;
btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
itup = &(btitem->bti_itup);
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
/*
* The scan key is set up with the attribute number associated with each
......@@ -1189,7 +1185,6 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
BTPageOpaque opaque;
OffsetNumber offnum;
BlockNumber blkno;
BTItem btitem;
IndexTuple itup;
/*
......@@ -1243,8 +1238,7 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
else
offnum = P_FIRSTDATAKEY(opaque);
btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
itup = &(btitem->bti_itup);
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
blkno = ItemPointerGetBlockNumber(&(itup->t_tid));
buf = _bt_relandgetbuf(rel, buf, blkno, BT_READ);
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.70 2006/01/25 20:29:23 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.71 2006/01/25 23:04:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -139,30 +139,6 @@ _bt_freestack(BTStack stack)
}
}
/*
* Construct a BTItem from a plain IndexTuple.
*
* This is now useless code, since a BTItem *is* an index tuple with
* no extra stuff. We hang onto it for the moment to preserve the
* notational distinction, in case we want to add some extra stuff
* again someday.
*/
BTItem
_bt_formitem(IndexTuple itup)
{
int nbytes_btitem;
BTItem btitem;
Size tuplen;
/* make a copy of the index tuple with room for extra stuff */
tuplen = IndexTupleSize(itup);
nbytes_btitem = tuplen + (sizeof(BTItemData) - sizeof(IndexTupleData));
btitem = (BTItem) palloc(nbytes_btitem);
memcpy((char *) &(btitem->bti_itup), (char *) itup, tuplen);
return btitem;
}
/*----------
* _bt_preprocess_keys() -- Preprocess scan keys
......@@ -589,7 +565,6 @@ _bt_checkkeys(IndexScanDesc scan,
{
ItemId iid = PageGetItemId(page, offnum);
bool tuple_valid;
BTItem btitem;
IndexTuple tuple;
TupleDesc tupdesc;
BTScanOpaque so;
......@@ -631,8 +606,7 @@ _bt_checkkeys(IndexScanDesc scan,
else
tuple_valid = true;
btitem = (BTItem) PageGetItem(page, iid);
tuple = &btitem->bti_itup;
tuple = (IndexTuple) PageGetItem(page, iid);
IncrIndexProcessed();
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.24 2005/10/18 01:06:23 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.25 2006/01/25 23:04:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -57,7 +57,7 @@ forget_matching_split(Relation reln, RelFileNode node,
{
Buffer buffer;
Page page;
BTItem btitem;
IndexTuple itup;
BlockNumber rightblk;
ListCell *l;
......@@ -66,9 +66,9 @@ forget_matching_split(Relation reln, RelFileNode node,
if (!BufferIsValid(buffer))
elog(PANIC, "forget_matching_split: block unfound");
page = (Page) BufferGetPage(buffer);
btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offnum));
rightblk = ItemPointerGetBlockNumber(&(btitem->bti_itup.t_tid));
Assert(ItemPointerGetOffsetNumber(&(btitem->bti_itup.t_tid)) == P_HIKEY);
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
rightblk = ItemPointerGetBlockNumber(&(itup->t_tid));
Assert(ItemPointerGetOffsetNumber(&(itup->t_tid)) == P_HIKEY);
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
ReleaseBuffer(buffer);
......@@ -90,15 +90,15 @@ forget_matching_split(Relation reln, RelFileNode node,
static void
_bt_restore_page(Page page, char *from, int len)
{
BTItemData btdata;
IndexTupleData itupdata;
Size itemsz;
char *end = from + len;
for (; from < end;)
{
memcpy(&btdata, from, sizeof(BTItemData));
itemsz = IndexTupleDSize(btdata.bti_itup) +
(sizeof(BTItemData) - sizeof(IndexTupleData));
/* Need to copy tuple header due to alignment considerations */
memcpy(&itupdata, from, sizeof(IndexTupleData));
itemsz = IndexTupleDSize(itupdata);
itemsz = MAXALIGN(itemsz);
if (PageAddItem(page, (Item) from, itemsz,
FirstOffsetNumber, LP_USED) == InvalidOffsetNumber)
......@@ -431,12 +431,12 @@ btree_xlog_delete_page(bool ismeta,
else
{
ItemId itemid;
BTItem btitem;
IndexTuple itup;
OffsetNumber nextoffset;
itemid = PageGetItemId(page, poffset);
btitem = (BTItem) PageGetItem(page, itemid);
ItemPointerSet(&(btitem->bti_itup.t_tid), rightsib, P_HIKEY);
itup = (IndexTuple) PageGetItem(page, itemid);
ItemPointerSet(&(itup->t_tid), rightsib, P_HIKEY);
nextoffset = OffsetNumberNext(poffset);
PageIndexTupleDelete(page, nextoffset);
}
......
......@@ -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.90 2006/01/23 22:31:41 tgl Exp $
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.91 2006/01/25 23:04:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -91,9 +91,7 @@ typedef struct BTMetaPageData
MAXALIGN(sizeof(BTPageOpaqueData))) / 3 - sizeof(ItemIdData))
/*
* BTItems are what we store in the btree. Each item is an index tuple,
* including key and pointer values. (In some cases either the key or the
* pointer may go unused, see backend/access/nbtree/README for details.)
* Test whether two btree entries are "the same".
*
* Old comments:
* In addition, we must guarantee that all tuples in the index are unique,
......@@ -106,33 +104,16 @@ typedef struct BTMetaPageData
*
* New comments:
* actually, we must guarantee that all tuples in A LEVEL
* are unique, not in ALL INDEX. So, we can use bti_itup->t_tid
* are unique, not in ALL INDEX. So, we can use the t_tid
* as unique identifier for a given index tuple (logical position
* within a level). - vadim 04/09/97
*/
typedef struct BTItemData
{
IndexTupleData bti_itup;
} BTItemData;
typedef BTItemData *BTItem;
#define CopyBTItem(btitem) ((BTItem) CopyIndexTuple((IndexTuple) (btitem)))
/*
* For XLOG: size without alignment. Sizeof works as long as
* IndexTupleData has exactly 8 bytes.
*/
#define SizeOfBTItem sizeof(BTItemData)
/* Test whether items are the "same" per the above notes */
#define BTTidSame(i1, i2) \
( (i1).ip_blkid.bi_hi == (i2).ip_blkid.bi_hi && \
(i1).ip_blkid.bi_lo == (i2).ip_blkid.bi_lo && \
(i1).ip_posid == (i2).ip_posid )
#define BTItemSame(i1, i2) \
BTTidSame((i1)->bti_itup.t_tid, (i2)->bti_itup.t_tid)
#define BTEntrySame(i1, i2) \
BTTidSame((i1)->t_tid, (i2)->t_tid)
/*
......@@ -184,16 +165,16 @@ typedef BTItemData *BTItem;
* XLOG allows to store some information in high 4 bits of log
* record xl_info field
*/
#define XLOG_BTREE_INSERT_LEAF 0x00 /* add btitem without split */
#define XLOG_BTREE_INSERT_LEAF 0x00 /* add index tuple without split */
#define XLOG_BTREE_INSERT_UPPER 0x10 /* same, on a non-leaf page */
#define XLOG_BTREE_INSERT_META 0x20 /* same, plus update metapage */
#define XLOG_BTREE_SPLIT_L 0x30 /* add btitem with split */
#define XLOG_BTREE_SPLIT_L 0x30 /* add index tuple with split */
#define XLOG_BTREE_SPLIT_R 0x40 /* as above, new item on right */
#define XLOG_BTREE_SPLIT_L_ROOT 0x50 /* add btitem with split of root */
#define XLOG_BTREE_SPLIT_L_ROOT 0x50 /* add tuple with split of root */
#define XLOG_BTREE_SPLIT_R_ROOT 0x60 /* as above, new item on right */
#define XLOG_BTREE_DELETE 0x70 /* delete leaf btitem */
#define XLOG_BTREE_DELETE 0x70 /* delete leaf index tuple */
#define XLOG_BTREE_DELETE_PAGE 0x80 /* delete an entire page */
#define XLOG_BTREE_DELETE_PAGE_META 0x90 /* same, plus update metapage */
#define XLOG_BTREE_DELETE_PAGE_META 0x90 /* same, plus update metapage */
#define XLOG_BTREE_NEWROOT 0xA0 /* new root page */
#define XLOG_BTREE_NEWMETA 0xB0 /* update metadata page */
......@@ -227,7 +208,7 @@ typedef struct xl_btree_insert
{
xl_btreetid target; /* inserted tuple id */
/* xl_btree_metadata FOLLOWS IF XLOG_BTREE_INSERT_META */
/* BTITEM FOLLOWS AT END OF STRUCT */
/* INDEX TUPLE FOLLOWS AT END OF STRUCT */
} xl_btree_insert;
#define SizeOfBtreeInsert (offsetof(xl_btreetid, tid) + SizeOfIptrData)
......@@ -240,7 +221,7 @@ typedef struct xl_btree_insert
* whole page image.
*
* Note: the four XLOG_BTREE_SPLIT xl_info codes all use this data record.
* The _L and _R variants indicate whether the inserted btitem went into the
* The _L and _R variants indicate whether the inserted tuple went into the
* left or right split page (and thus, whether otherblk is the right or left
* page of the split pair). The _ROOT variants indicate that we are splitting
* the root page, and thus that a newroot record rather than an insert or
......@@ -262,8 +243,8 @@ typedef struct xl_btree_split
#define SizeOfBtreeSplit (offsetof(xl_btree_split, leftlen) + sizeof(uint16))
/*
* This is what we need to know about delete of individual leaf btitems.
* The WAL record can represent deletion of any number of btitems on a
* This is what we need to know about delete of individual leaf index tuples.
* The WAL record can represent deletion of any number of index tuples on a
* single index page.
*/
typedef struct xl_btree_delete
......@@ -294,7 +275,7 @@ typedef struct xl_btree_delete_page
#define SizeOfBtreeDeletePage (offsetof(xl_btree_delete_page, rightblk) + sizeof(BlockNumber))
/*
* New root log record. There are zero btitems if this is to establish an
* New root log record. There are zero tuples if this is to establish an
* empty root, or two if it is the result of splitting an old root.
*
* Note that although this implies rewriting the metadata page, we don't need
......@@ -305,7 +286,7 @@ typedef struct xl_btree_newroot
RelFileNode node;
BlockNumber rootblk; /* location of new root */
uint32 level; /* its tree level */
/* 0 or 2 BTITEMS FOLLOW AT END OF STRUCT */
/* 0 or 2 INDEX TUPLES FOLLOW AT END OF STRUCT */
} xl_btree_newroot;
#define SizeOfBtreeNewroot (offsetof(xl_btree_newroot, level) + sizeof(uint32))
......@@ -360,7 +341,7 @@ typedef struct BTStackData
{
BlockNumber bts_blkno;
OffsetNumber bts_offset;
BTItemData bts_btitem;
IndexTupleData bts_btentry;
struct BTStackData *bts_parent;
} BTStackData;
......@@ -420,7 +401,7 @@ extern Datum btvacuumcleanup(PG_FUNCTION_ARGS);
/*
* prototypes for functions in nbtinsert.c
*/
extern void _bt_doinsert(Relation rel, BTItem btitem,
extern void _bt_doinsert(Relation rel, IndexTuple itup,
bool index_is_unique, Relation heapRel);
extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access);
extern void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf,
......@@ -474,7 +455,6 @@ extern void _bt_preprocess_keys(IndexScanDesc scan);
extern bool _bt_checkkeys(IndexScanDesc scan,
Page page, OffsetNumber offnum,
ScanDirection dir, bool *continuescan);
extern BTItem _bt_formitem(IndexTuple itup);
/*
* prototypes for functions in nbtsort.c
......@@ -483,7 +463,7 @@ typedef struct BTSpool BTSpool; /* opaque type known only within nbtsort.c */
extern BTSpool *_bt_spoolinit(Relation index, bool isunique, bool isdead);
extern void _bt_spooldestroy(BTSpool *btspool);
extern void _bt_spool(BTItem btitem, BTSpool *btspool);
extern void _bt_spool(IndexTuple itup, BTSpool *btspool);
extern void _bt_leafbuild(BTSpool *btspool, BTSpool *spool2);
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment