30#ifdef USE_ASSERT_CHECKING
31static bool _bt_posting_valid(
IndexTuple posting);
70 bool singlevalstrat =
false;
86 state->deduplicate =
true;
92 state->basetupsize = 0;
98 state->phystupsize = 0;
100 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)
573 elog(
ERROR,
"deduplication failed to add tuple to page");
584 Assert(tuplesz <= state->maxpostingsize);
592 elog(
ERROR,
"deduplication failed to add tuple to page");
598 Assert(spacesaving > 0 && spacesaving < BLCKSZ);
604 state->phystupsize = 0;
649 bool dupinterval = (
state->nitems > 1);
655 for (
int i = 0;
i <
state->nitems;
i++)
689 bool firstpromising =
false;
690 bool lastpromising =
false;
692 Assert(_bt_posting_valid(itup));
715 firstpromising = (minblocklist == midblocklist);
716 lastpromising = (!firstpromising &&
717 midblocklist == maxblocklist);
720 for (
int p = 0; p < nitem; p++)
724 ideltid->
tid = *htid;
729 if ((firstpromising && p == 0) ||
730 (lastpromising && p == nitem - 1))
750 state->phystupsize = 0;
836 if (
state->maxpostingsize > reduction)
837 state->maxpostingsize -= reduction;
839 state->maxpostingsize = 0;
889 memcpy(itup, base, keysize);
890 itup->
t_info &= ~INDEX_SIZE_MASK;
898 Assert(_bt_posting_valid(itup));
903 itup->
t_info &= ~INDEX_ALT_TID_MASK;
935 Assert(_bt_posting_valid(origtuple));
957 memcpy(itup, origtuple, keysize);
958 itup->
t_info &= ~INDEX_SIZE_MASK;
970 itup->
t_info &= ~INDEX_ALT_TID_MASK;
971 htids = &itup->
t_tid;
978 if (d < vacposting->ndeletedtids && vacposting->
deletetids[d] ==
i)
987 Assert(nhtids == 1 || _bt_posting_valid(itup));
991 vacposting->
itup = itup;
1024 char *replaceposright;
1029 Assert(_bt_posting_valid(oposting));
1040 if (!(postingoff > 0 && postingoff < nhtids))
1041 elog(
ERROR,
"posting list tuple with %d items cannot be split at offset %d",
1042 nhtids, postingoff);
1054 memmove(replaceposright, replacepos, nmovebytes);
1065 Assert(_bt_posting_valid(nposting));
1074#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 void * 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
Assert(PointerIsAligned(start, uint64))
IndexTuple CopyIndexTuple(IndexTuple source)
#define ItemIdGetLength(itemId)
struct ItemIdData ItemIdData
#define ItemIdIsDead(itemId)
int32 ItemPointerCompare(const ItemPointerData *arg1, const ItemPointerData *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, const ItemPointerData *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)
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]
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBufData(uint8 block_id, const void *data, uint32 len)
void XLogRegisterData(const void *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)