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(Page page)
static Size PageGetPageSize(Page page)
static void PageSetLSN(Page page, XLogRecPtr lsn)
#define Assert(condition)
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
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)
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)