34#define GinPostingListSegmentMaxSize 384
35#define GinPostingListSegmentTargetSize 256
36#define GinPostingListSegmentMinSize 128
43#define MinTuplesPerSegment ((GinPostingListSegmentMaxSize - 2) / 6)
339 for (
i = storedOff + 1;
i <= maxoff;
i++)
346 maxoff = storedOff - 1;
395 if (offset != maxoff + 1)
424 if (offset != maxoff)
450 void **ptp_workspace,
476 for (
i = 0;
i < maxitems;
i++)
503 if (!lastleftinfo->
items)
506 maxOldItem = lastleftinfo->
items[lastleftinfo->
nitems - 1];
561 items->curitem += maxitems;
580 elog(
ERROR,
"could not split GIN page; all old items didn't fit");
583 for (
i = 0;
i < maxitems;
i++)
589 elog(
ERROR,
"could not split GIN page; no new items fit");
606 *ptp_workspace = leaf;
609 elog(
DEBUG2,
"appended %d new items to block %u; %d bytes (%d to go)",
613 elog(
DEBUG2,
"inserted %d new items to block %u; %d bytes (%d to go)",
654 if ((leaf->
lsize - segsize) - (leaf->
rsize + segsize) < 0)
658 if ((leaf->
lsize - segsize) < (BLCKSZ * 3) / 4)
662 leaf->
lsize -= segsize;
663 leaf->
rsize += segsize;
676 if (!lastleftinfo->
items)
679 lbound = lastleftinfo->
items[lastleftinfo->
nitems - 1];
684 *newlpage =
palloc(BLCKSZ);
685 *newrpage =
palloc(BLCKSZ);
688 *newlpage, *newrpage);
695 elog(
DEBUG2,
"appended %d items to block %u; split %d/%d (%d to go)",
699 elog(
DEBUG2,
"inserted %d items to block %u; split %d/%d (%d to go)",
704 items->curitem += maxitems;
717 void *insertdata,
void *ptp_workspace)
742 bool removedsomething =
false;
768 seginfo->
items = NULL;
781 if (npacked != ncleaned)
782 elog(
ERROR,
"could not fit vacuumed posting list");
788 seginfo->
items = NULL;
791 seginfo->
nitems = ncleaned;
793 removedsomething =
true;
814 if (removedsomething)
836 memcpy(tmp, seginfo->
seg, segsize);
896 walbufend = walbufbegin;
901 recompress_xlog->
nactions = nmodified;
932 *((
uint8 *) (walbufend++)) = segno;
945 datalen +=
sizeof(
uint16);
951 memcpy(walbufend, seginfo->
seg, segsize);
957 walbufend += datalen;
983 bool modified =
false;
1014 memcpy(ptr, seginfo->
seg, segsize);
1068 memcpy(ptr, seginfo->
seg, segsize);
1080 for (node = firstright;
1089 memcpy(ptr, seginfo->
seg, segsize);
1121 void **ptp_workspace,
1130 newlpage, newrpage);
1147 void *ptp_workspace)
1173 data.newitem = *pitem;
1203 void **ptp_workspace,
1213 newlpage, newrpage);
1216 insertdata, updateblkno,
1218 newlpage, newrpage);
1233 void *ptp_workspace)
1242 updateblkno, ptp_workspace);
1282 allitems[off - 1] = *((
PostingItem *) insertdata);
1388 while ((
Pointer) seg < segend)
1394 seginfo->
items = NULL;
1415 if (nuncompressed > 0)
1420 seginfo->
seg = NULL;
1423 seginfo->
nitems = nuncompressed;
1448 int newleft = nNewItems;
1449 bool modified =
false;
1460 newseg->
items = newItems;
1461 newseg->
nitems = nNewItems;
1487 next_first =
next->items[0];
1491 next_first =
next->seg->first;
1517 newseg->
items = nextnew;
1528 if (ntmpitems !=
cur->nitems)
1536 if (ntmpitems == nthis +
cur->nitems &&
1540 cur->modifieditems = nextnew;
1541 cur->nmodifieditems = nthis;
1546 cur->items = tmpitems;
1547 cur->nitems = ntmpitems;
1574 bool needsplit =
false;
1591 cur_node = next_node)
1604 if (seginfo->
seg == NULL)
1615 if (npacked != seginfo->
nitems)
1634 nextseg->
seg = NULL;
1637 next_node = &nextseg->
node;
1651 if (seginfo->
items == NULL)
1654 if (nextseg->
items == NULL)
1662 nextseg->
nitems = nmerged;
1663 nextseg->
seg = NULL;
1677 seginfo->
seg = NULL;
1681 seginfo->
items = NULL;
1701 leaf->
lsize = pgused;
1727 leaf->
lsize = pgused;
1731 leaf->
rsize = pgused;
1757 memcpy(tmp, seginfo->
seg, segsize);
1785 bool is_build = (buildStats != NULL);
1799 while (nrootitems <
nitems)
1813 memcpy(ptr, segment, segsize);
1815 rootsize += segsize;
1816 nrootitems += npacked;
1844 data.size = rootsize;
1865 elog(
DEBUG2,
"created GIN posting tree with %d items", nrootitems);
1917 btree.
isBuild = (buildStats != NULL);
1919 insertdata.
nitem = nitem;
#define InvalidBlockNumber
BlockNumber BufferGetBlockNumber(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
static Page BufferGetPage(Buffer buffer)
void PageRestoreTempPage(Page tempPage, Page oldPage)
Page PageGetTempPage(const PageData *page)
static Size PageGetPageSize(const PageData *page)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static int ginCompareItemPointers(ItemPointer a, ItemPointer b)
#define GinDataLeafPageGetFreeSpace(page)
#define GinPageGetOpaque(page)
#define SizeOfGinPostingList(plist)
#define GinDataLeafPageGetPostingListSize(page)
#define GinDataPageSetDataSize(page, size)
#define GinDataPageMaxDataSize
#define GinDataPageGetRightBound(page)
#define GinPageSetCompressed(page)
#define GinNextPostingListSegment(cur)
#define GinNonLeafDataPageGetFreeSpace(page)
#define GinPageIsData(page)
#define GinPageRightMost(page)
#define ItemPointerSetMin(p)
#define GinDataPageGetPostingItem(page, i)
#define PostingItemGetBlockNumber(pointer)
#define GinDataPageGetData(page)
#define PostingItemSetBlockNumber(pointer, blockNumber)
#define GinPageIsDeleted(page)
#define GinPageIsCompressed(page)
#define GinPageIsLeaf(page)
#define GinDataLeafPageGetPostingList(page)
void ginInsertValue(GinBtree btree, GinBtreeStack *stack, void *insertdata, GinStatsData *buildStats)
GinBtreeStack * ginFindLeafPage(GinBtree btree, bool searchMode, bool rootConflictCheck)
static OffsetNumber dataFindChildPtr(GinBtree btree, Page page, BlockNumber blkno, OffsetNumber storedOff)
static void dataSplitPageInternal(GinBtree btree, Buffer origbuf, GinBtreeStack *stack, void *insertdata, BlockNumber updateblkno, Page *newlpage, Page *newrpage)
#define MinTuplesPerSegment
static bool addItemsToLeaf(disassembledLeaf *leaf, ItemPointer newItems, int nNewItems)
static bool leafRepackItems(disassembledLeaf *leaf, ItemPointer remaining)
#define GinPostingListSegmentTargetSize
static BlockNumber dataGetLeftMostPage(GinBtree btree, Page page)
static void * dataPrepareDownlink(GinBtree btree, Buffer lbuf)
BlockNumber createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, GinStatsData *buildStats, Buffer entrybuffer)
GinBtreeStack * ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno)
void GinPageDeletePostingItem(Page page, OffsetNumber offset)
static GinPlaceToPageRC dataBeginPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack, void *insertdata, void **ptp_workspace, Page *newlpage, Page *newrpage)
static GinPlaceToPageRC dataBeginPlaceToPageInternal(GinBtree btree, Buffer buf, GinBtreeStack *stack, void *insertdata, BlockNumber updateblkno, void **ptp_workspace, Page *newlpage, Page *newrpage)
static void dataExecPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack, void *insertdata, void *ptp_workspace)
static void dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf)
int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm)
void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset)
#define GinPostingListSegmentMaxSize
void ginInsertItemPointers(Relation index, BlockNumber rootBlkno, ItemPointerData *items, uint32 nitem, GinStatsData *buildStats)
static GinPlaceToPageRC dataBeginPlaceToPage(GinBtree btree, Buffer buf, GinBtreeStack *stack, void *insertdata, BlockNumber updateblkno, void **ptp_workspace, Page *newlpage, Page *newrpage)
static void dataExecPlaceToPage(GinBtree btree, Buffer buf, GinBtreeStack *stack, void *insertdata, BlockNumber updateblkno, void *ptp_workspace)
static bool dataIsMoveRight(GinBtree btree, Page page)
static void dataPlaceToPageLeafSplit(disassembledLeaf *leaf, ItemPointerData lbound, ItemPointerData rbound, Page lpage, Page rpage)
static void dataExecPlaceToPageInternal(GinBtree btree, Buffer buf, GinBtreeStack *stack, void *insertdata, BlockNumber updateblkno, void *ptp_workspace)
static void ginPrepareDataScan(GinBtree btree, Relation index, BlockNumber rootBlkno)
static BlockNumber dataLocateItem(GinBtree btree, GinBtreeStack *stack)
static void computeLeafRecompressWALData(disassembledLeaf *leaf)
void ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer, GinVacuumState *gvs)
static ItemPointer dataLeafPageGetUncompressed(Page page, int *nitems)
void ginDataFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage)
#define GinPostingListSegmentMinSize
static disassembledLeaf * disassembleLeaf(Page page)
ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast)
ItemPointer ginPostingListDecodeAllSegments(GinPostingList *segment, int len, int *ndecoded_out)
int ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int len, TIDBitmap *tbm)
ItemPointer ginPostingListDecode(GinPostingList *plist, int *ndecoded_out)
GinPostingList * ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, int *nwritten)
ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na, ItemPointerData *b, uint32 nb, int *nmerged)
void GinInitPage(Page page, uint32 f, Size pageSize)
Buffer GinNewBuffer(Relation index)
ItemPointer ginVacuumItemPointers(GinVacuumState *gvs, ItemPointerData *items, int nitem, int *nremaining)
#define GIN_SEGMENT_ADDITEMS
#define GIN_SEGMENT_DELETE
#define XLOG_GIN_CREATE_PTREE
#define XLOG_GIN_VACUUM_DATA_LEAF_PAGE
#define GIN_SEGMENT_UNMODIFIED
#define GIN_SEGMENT_INSERT
#define GIN_SEGMENT_REPLACE
Assert(PointerIsAligned(start, uint64))
static void dlist_insert_after(dlist_node *after, dlist_node *node)
#define dlist_foreach(iter, lhead)
static void dlist_init(dlist_head *head)
static bool dlist_has_next(const dlist_head *head, const dlist_node *node)
static bool dlist_has_prev(const dlist_head *head, const dlist_node *node)
static dlist_node * dlist_prev_node(dlist_head *head, dlist_node *node)
static dlist_node * dlist_next_node(dlist_head *head, dlist_node *node)
static void dlist_delete(dlist_node *node)
static dlist_node * dlist_head_node(dlist_head *head)
static bool dlist_is_empty(const dlist_head *head)
static void dlist_push_tail(dlist_head *head, dlist_node *node)
static dlist_node * dlist_tail_node(dlist_head *head)
#define dlist_container(type, membername, ptr)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
static void ItemPointerSetInvalid(ItemPointerData *pointer)
ItemPointerData * ItemPointer
struct ItemPointerData ItemPointerData
static bool ItemPointerIsValid(const ItemPointerData *pointer)
void pfree(void *pointer)
void * palloc0(Size size)
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
#define InvalidOffsetNumber
#define FirstOffsetNumber
void PredicateLockPageSplit(Relation relation, BlockNumber oldblkno, BlockNumber newblkno)
#define RelationNeedsWAL(relation)
BlockNumber(* findChildPage)(GinBtree, GinBtreeStack *)
void(* execPlaceToPage)(GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void *)
BlockNumber(* getLeftMostChild)(GinBtree, Page)
bool(* findItem)(GinBtree, GinBtreeStack *)
void *(* prepareDownlink)(GinBtree, Buffer)
bool(* isMoveRight)(GinBtree, Page)
GinPlaceToPageRC(* beginPlaceToPage)(GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void **, Page *, Page *)
OffsetNumber(* findChildPtr)(GinBtree, Page, BlockNumber, OffsetNumber)
void(* fillRoot)(GinBtree, Page, BlockNumber, Page, BlockNumber, Page)
ItemPointerData * modifieditems
void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, bool recheck)
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)