Use PageIndexTupleOverwrite() within nbtree.

Use the PageIndexTupleOverwrite() bufpage.c routine within nbtree
instead of deleting a tuple and re-inserting its replacement.  This
makes the intent of affected code slightly clearer.  It also makes
CREATE INDEX slightly faster, since there is no longer a need to shift
every leaf page's line pointer array back and forth during index builds.

Author: Peter Geoghegan, Anastasia Lubennikova
Reviewed-By: Anastasia Lubennikova
Discussion: https://postgr.es/m/CAH2-Wz=Zk=B9+Vwm376WuO7YTjFc2SSskifQm4Nme3RRRPtOSQ@mail.gmail.com
This commit is contained in:
Peter Geoghegan 2019-08-13 11:54:26 -07:00
parent 815ef2f568
commit af0ba49809
2 changed files with 10 additions and 20 deletions

View File

@ -1653,8 +1653,7 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
opaque = (BTPageOpaque) PageGetSpecialPointer(page); opaque = (BTPageOpaque) PageGetSpecialPointer(page);
opaque->btpo_flags |= BTP_HALF_DEAD; opaque->btpo_flags |= BTP_HALF_DEAD;
PageIndexTupleDelete(page, P_HIKEY); Assert(PageGetMaxOffsetNumber(page) == P_HIKEY);
Assert(PageGetMaxOffsetNumber(page) == 0);
MemSet(&trunctuple, 0, sizeof(IndexTupleData)); MemSet(&trunctuple, 0, sizeof(IndexTupleData));
trunctuple.t_info = sizeof(IndexTupleData); trunctuple.t_info = sizeof(IndexTupleData);
if (target != leafblkno) if (target != leafblkno)
@ -1662,9 +1661,9 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
else else
BTreeTupleSetTopParent(&trunctuple, InvalidBlockNumber); BTreeTupleSetTopParent(&trunctuple, InvalidBlockNumber);
if (PageAddItem(page, (Item) &trunctuple, sizeof(IndexTupleData), P_HIKEY, if (!PageIndexTupleOverwrite(page, P_HIKEY, (Item) &trunctuple,
false, false) == InvalidOffsetNumber) IndexTupleSize(&trunctuple)))
elog(ERROR, "could not add dummy high key to half-dead page"); elog(ERROR, "could not overwrite high key in half-dead page");
/* Must mark buffers dirty before XLogInsert */ /* Must mark buffers dirty before XLogInsert */
MarkBufferDirty(topparent); MarkBufferDirty(topparent);

View File

@ -943,7 +943,6 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
{ {
IndexTuple lastleft; IndexTuple lastleft;
IndexTuple truncated; IndexTuple truncated;
Size truncsz;
/* /*
* Truncate away any unneeded attributes from high key on leaf * Truncate away any unneeded attributes from high key on leaf
@ -961,26 +960,18 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
* choosing a split point here for a benefit that is bound to be * choosing a split point here for a benefit that is bound to be
* much smaller. * much smaller.
* *
* Since the truncated tuple is often smaller than the original * Overwrite the old item with new truncated high key directly.
* tuple, it cannot just be copied in place (besides, we want to * oitup is already located at the physical beginning of tuple
* actually save space on the leaf page). We delete the original * space, so this should directly reuse the existing tuple space.
* high key, and add our own truncated high key at the same
* offset.
*
* Note that the page layout won't be changed very much. oitup is
* already located at the physical beginning of tuple space, so we
* only shift the line pointer array back and forth, and overwrite
* the tuple space previously occupied by oitup. This is fairly
* cheap.
*/ */
ii = PageGetItemId(opage, OffsetNumberPrev(last_off)); ii = PageGetItemId(opage, OffsetNumberPrev(last_off));
lastleft = (IndexTuple) PageGetItem(opage, ii); lastleft = (IndexTuple) PageGetItem(opage, ii);
truncated = _bt_truncate(wstate->index, lastleft, oitup, truncated = _bt_truncate(wstate->index, lastleft, oitup,
wstate->inskey); wstate->inskey);
truncsz = IndexTupleSize(truncated); if (!PageIndexTupleOverwrite(opage, P_HIKEY, (Item) truncated,
PageIndexTupleDelete(opage, P_HIKEY); IndexTupleSize(truncated)))
_bt_sortaddtup(opage, truncsz, truncated, P_HIKEY); elog(ERROR, "failed to add high key to the index page");
pfree(truncated); pfree(truncated);
/* oitup should continue to point to the page's high key */ /* oitup should continue to point to the page's high key */