]> granicus.if.org Git - postgresql/commitdiff
Use PageIndexTupleOverwrite() within nbtree.
authorPeter Geoghegan <pg@bowt.ie>
Tue, 13 Aug 2019 18:54:26 +0000 (11:54 -0700)
committerPeter Geoghegan <pg@bowt.ie>
Tue, 13 Aug 2019 18:54:26 +0000 (11:54 -0700)
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

src/backend/access/nbtree/nbtpage.c
src/backend/access/nbtree/nbtsort.c

index 9c1f7de60f11171103cba028f2bd31943d2b1c6f..7c0e6d13a94f1f6c448b6d231208224701012eb1 100644 (file)
@@ -1653,8 +1653,7 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
        opaque = (BTPageOpaque) PageGetSpecialPointer(page);
        opaque->btpo_flags |= BTP_HALF_DEAD;
 
-       PageIndexTupleDelete(page, P_HIKEY);
-       Assert(PageGetMaxOffsetNumber(page) == 0);
+       Assert(PageGetMaxOffsetNumber(page) == P_HIKEY);
        MemSet(&trunctuple, 0, sizeof(IndexTupleData));
        trunctuple.t_info = sizeof(IndexTupleData);
        if (target != leafblkno)
@@ -1662,9 +1661,9 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack)
        else
                BTreeTupleSetTopParent(&trunctuple, InvalidBlockNumber);
 
-       if (PageAddItem(page, (Item) &trunctuple, sizeof(IndexTupleData), P_HIKEY,
-                                       false, false) == InvalidOffsetNumber)
-               elog(ERROR, "could not add dummy high key to half-dead page");
+       if (!PageIndexTupleOverwrite(page, P_HIKEY, (Item) &trunctuple,
+                                                                IndexTupleSize(&trunctuple)))
+               elog(ERROR, "could not overwrite high key in half-dead page");
 
        /* Must mark buffers dirty before XLogInsert */
        MarkBufferDirty(topparent);
index b30cf9e9898aca3608192cc4d81f7c122da7ef87..e678690b18ead7fc5b56c43f771e41e1a5a022df 100644 (file)
@@ -943,7 +943,6 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup)
                {
                        IndexTuple      lastleft;
                        IndexTuple      truncated;
-                       Size            truncsz;
 
                        /*
                         * 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
                         * much smaller.
                         *
-                        * Since the truncated tuple is often smaller than the original
-                        * tuple, it cannot just be copied in place (besides, we want to
-                        * actually save space on the leaf page).  We delete the original
-                        * 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.
+                        * Overwrite the old item with new truncated high key directly.
+                        * oitup is already located at the physical beginning of tuple
+                        * space, so this should directly reuse the existing tuple space.
                         */
                        ii = PageGetItemId(opage, OffsetNumberPrev(last_off));
                        lastleft = (IndexTuple) PageGetItem(opage, ii);
 
                        truncated = _bt_truncate(wstate->index, lastleft, oitup,
                                                                         wstate->inskey);
-                       truncsz = IndexTupleSize(truncated);
-                       PageIndexTupleDelete(opage, P_HIKEY);
-                       _bt_sortaddtup(opage, truncsz, truncated, P_HIKEY);
+                       if (!PageIndexTupleOverwrite(opage, P_HIKEY, (Item) truncated,
+                                                                                IndexTupleSize(truncated)))
+                               elog(ERROR, "failed to add high key to the index page");
                        pfree(truncated);
 
                        /* oitup should continue to point to the page's high key */