29#ifdef USE_ASSERT_CHECKING
30static bool _bt_posting_valid(
IndexTuple posting);
69 bool singlevalstrat =
false;
85 state->deduplicate =
true;
91 state->basetupsize = 0;
97 state->phystupsize = 0;
99 state->nintervals = 0;
130 elog(
ERROR,
"deduplication failed to add highkey");
133 for (offnum = minoff;
142 if (offnum == minoff)
150 else if (
state->deduplicate &&
190 if (
state->nmaxitems == 5)
192 else if (
state->nmaxitems == 6)
194 state->deduplicate =
false;
195 singlevalstrat =
false;
217 if (
state->nintervals == 0)
325 state->deduplicate =
true;
326 state->nmaxitems = 0;
327 state->maxpostingsize = BLCKSZ;
330 state->basetupsize = 0;
334 state->phystupsize = 0;
335 state->nintervals = 0;
363 for (offnum = minoff;
372 if (offnum == minoff)
403 if (
state->nintervals == 0)
457 state->nhtids = nposting;
471 state->baseoff = baseoff;
495 htids = &itup->
t_tid;
513 if (mergedtupsz >
state->maxpostingsize)
527 if (
state->nhtids > 50)
540 state->nhtids += nhtids;
566 if (
state->nitems == 1)
574 elog(
ERROR,
"deduplication failed to add tuple to page");
585 Assert(tuplesz <= state->maxpostingsize);
594 elog(
ERROR,
"deduplication failed to add tuple to page");
600 Assert(spacesaving > 0 && spacesaving < BLCKSZ);
606 state->phystupsize = 0;
651 bool dupinterval = (
state->nitems > 1);
657 for (
int i = 0;
i <
state->nitems;
i++)
691 bool firstpromising =
false;
692 bool lastpromising =
false;
694 Assert(_bt_posting_valid(itup));
717 firstpromising = (minblocklist == midblocklist);
718 lastpromising = (!firstpromising &&
719 midblocklist == maxblocklist);
722 for (
int p = 0; p < nitem; p++)
726 ideltid->
tid = *htid;
731 if ((firstpromising && p == 0) ||
732 (lastpromising && p == nitem - 1))
752 state->phystupsize = 0;
838 if (
state->maxpostingsize > reduction)
839 state->maxpostingsize -= reduction;
841 state->maxpostingsize = 0;
891 memcpy(itup, base, keysize);
892 itup->
t_info &= ~INDEX_SIZE_MASK;
900 Assert(_bt_posting_valid(itup));
905 itup->
t_info &= ~INDEX_ALT_TID_MASK;
937 Assert(_bt_posting_valid(origtuple));
959 memcpy(itup, origtuple, keysize);
960 itup->
t_info &= ~INDEX_SIZE_MASK;
972 itup->
t_info &= ~INDEX_ALT_TID_MASK;
973 htids = &itup->
t_tid;
980 if (d < vacposting->ndeletedtids && vacposting->
deletetids[d] ==
i)
989 Assert(nhtids == 1 || _bt_posting_valid(itup));
993 vacposting->
itup = itup;
1026 char *replaceposright;
1031 Assert(_bt_posting_valid(oposting));
1042 if (!(postingoff > 0 && postingoff < nhtids))
1043 elog(
ERROR,
"posting list tuple with %d items cannot be split at offset %d",
1044 nhtids, postingoff);
1056 memmove(replaceposright, replacepos, nmovebytes);
1067 Assert(_bt_posting_valid(nposting));
1076#ifdef USE_ASSERT_CHECKING
BlockNumber BufferGetBlockNumber(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
static Page BufferGetPage(Buffer buffer)
void PageRestoreTempPage(Page tempPage, Page oldPage)
Size PageGetExactFreeSpace(const PageData *page)
Page PageGetTempPageCopySpecial(const PageData *page)
static Size PageGetPageSize(const PageData *page)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
#define SizeOfPageHeaderData
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static XLogRecPtr PageGetLSN(const PageData *page)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
#define PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
IndexTuple CopyIndexTuple(IndexTuple source)
#define ItemIdGetLength(itemId)
struct ItemIdData ItemIdData
#define ItemIdIsDead(itemId)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
struct ItemPointerData ItemPointerData
static void ItemPointerCopy(const ItemPointerData *fromPointer, ItemPointerData *toPointer)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
IndexTupleData * IndexTuple
static Size IndexTupleSize(const IndexTupleData *itup)
void pfree(void *pointer)
void * palloc0(Size size)
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
IndexTuple _bt_swap_posting(IndexTuple newitem, IndexTuple oposting, int postingoff)
void _bt_dedup_pass(Relation rel, Buffer buf, IndexTuple newitem, Size newitemsz, bool bottomupdedup)
void _bt_update_posting(BTVacuumPosting vacposting)
bool _bt_bottomupdel_pass(Relation rel, Buffer buf, Relation heapRel, Size newitemsz)
bool _bt_dedup_save_htid(BTDedupState state, IndexTuple itup)
void _bt_dedup_start_pending(BTDedupState state, IndexTuple base, OffsetNumber baseoff)
static bool _bt_do_singleval(Relation rel, Page page, BTDedupState state, OffsetNumber minoff, IndexTuple newitem)
IndexTuple _bt_form_posting(IndexTuple base, ItemPointer htids, int nhtids)
static void _bt_bottomupdel_finish_pending(Page page, BTDedupState state, TM_IndexDeleteOp *delstate)
Size _bt_dedup_finish_pending(Page newpage, BTDedupState state)
static void _bt_singleval_fillfactor(Page page, BTDedupState state, Size newitemsz)
void _bt_delitems_delete_check(Relation rel, Buffer buf, Relation heapRel, TM_IndexDeleteOp *delstate)
static uint16 BTreeTupleGetNPosting(IndexTuple posting)
static bool BTreeTupleIsPivot(IndexTuple itup)
#define BTREE_SINGLEVAL_FILLFACTOR
#define P_HAS_GARBAGE(opaque)
static void BTreeTupleSetPosting(IndexTuple itup, uint16 nhtids, int postingoffset)
#define BTPageGetOpaque(page)
static ItemPointer BTreeTupleGetPosting(IndexTuple posting)
#define MaxTIDsPerBTreePage
#define P_FIRSTDATAKEY(opaque)
static uint32 BTreeTupleGetPostingOffset(IndexTuple posting)
#define P_RIGHTMOST(opaque)
#define BTMaxItemSize(page)
static ItemPointer BTreeTupleGetPostingN(IndexTuple posting, int n)
static ItemPointer BTreeTupleGetMaxHeapTID(IndexTuple itup)
static bool BTreeTupleIsPosting(IndexTuple itup)
BTDedupStateData * BTDedupState
static ItemPointer BTreeTupleGetHeapTID(IndexTuple itup)
int _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
#define InvalidOffsetNumber
#define OffsetNumberNext(offsetNumber)
#define RelationNeedsWAL(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
uint16 deletetids[FLEXIBLE_ARRAY_MEMBER]
void XLogRegisterBufData(uint8 block_id, const char *data, uint32 len)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterData(const char *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)