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];
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)",
717 void *insertdata,
void *ptp_workspace)
739 bool removedsomething =
false;
765 seginfo->
items = NULL;
778 if (npacked != ncleaned)
779 elog(
ERROR,
"could not fit vacuumed posting list");
785 seginfo->
items = NULL;
788 seginfo->
nitems = ncleaned;
790 removedsomething =
true;
811 if (removedsomething)
833 memcpy(tmp, seginfo->
seg, segsize);
893 walbufend = walbufbegin;
898 recompress_xlog->
nactions = nmodified;
929 *((
uint8 *) (walbufend++)) = segno;
942 datalen +=
sizeof(
uint16);
948 memcpy(walbufend, seginfo->
seg, segsize);
954 walbufend += datalen;
980 bool modified =
false;
1011 memcpy(ptr, seginfo->
seg, segsize);
1065 memcpy(ptr, seginfo->
seg, segsize);
1077 for (node = firstright;
1086 memcpy(ptr, seginfo->
seg, segsize);
1118 void **ptp_workspace,
1127 newlpage, newrpage);
1144 void *ptp_workspace)
1168 data.newitem = *pitem;
1197 void **ptp_workspace,
1207 newlpage, newrpage);
1210 insertdata, updateblkno,
1212 newlpage, newrpage);
1227 void *ptp_workspace)
1236 updateblkno, ptp_workspace);
1276 allitems[off - 1] = *((
PostingItem *) insertdata);
1382 while ((
Pointer) seg < segend)
1388 seginfo->
items = NULL;
1409 if (nuncompressed > 0)
1414 seginfo->
seg = NULL;
1417 seginfo->
nitems = nuncompressed;
1442 int newleft = nNewItems;
1443 bool modified =
false;
1454 newseg->
items = newItems;
1455 newseg->
nitems = nNewItems;
1481 next_first =
next->items[0];
1485 next_first =
next->seg->first;
1511 newseg->
items = nextnew;
1522 if (ntmpitems !=
cur->nitems)
1530 if (ntmpitems == nthis +
cur->nitems &&
1534 cur->modifieditems = nextnew;
1535 cur->nmodifieditems = nthis;
1540 cur->items = tmpitems;
1541 cur->nitems = ntmpitems;
1568 bool needsplit =
false;
1585 cur_node = next_node)
1598 if (seginfo->
seg == NULL)
1609 if (npacked != seginfo->
nitems)
1628 nextseg->
seg = NULL;
1631 next_node = &nextseg->
node;
1645 if (seginfo->
items == NULL)
1648 if (nextseg->
items == NULL)
1656 nextseg->
nitems = nmerged;
1657 nextseg->
seg = NULL;
1671 seginfo->
seg = NULL;
1675 seginfo->
items = NULL;
1695 leaf->
lsize = pgused;
1721 leaf->
lsize = pgused;
1725 leaf->
rsize = pgused;
1751 memcpy(tmp, seginfo->
seg, segsize);
1779 bool is_build = (buildStats != NULL);
1793 while (nrootitems < nitems)
1800 nitems - nrootitems,
1807 memcpy(ptr, segment, segsize);
1809 rootsize += segsize;
1810 nrootitems += npacked;
1838 data.size = rootsize;
1859 elog(
DEBUG2,
"created GIN posting tree with %d items", nrootitems);
1864 if (nitems > nrootitems)
1868 nitems - nrootitems,
1911 btree.
isBuild = (buildStats != NULL);
1912 insertdata.
items = items;
1913 insertdata.
nitem = nitem;
#define InvalidBlockNumber
BlockNumber BufferGetBlockNumber(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
#define BufferGetPage(buffer)
void PageRestoreTempPage(Page tempPage, Page oldPage)
Page PageGetTempPage(Page page)
#define PageSetLSN(page, lsn)
#define PageGetPageSize(page)
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, Snapshot snapshot)
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)
BlockNumber createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, GinStatsData *buildStats, Buffer entrybuffer)
GinBtreeStack * ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno, Snapshot snapshot)
static void * dataPrepareDownlink(GinBtree btree, Buffer lbuf)
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)
GinPostingList * ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, int *nwritten)
int ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int len, TIDBitmap *tbm)
ItemPointer ginPostingListDecode(GinPostingList *plist, int *ndecoded)
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 dlist_node * dlist_prev_node(dlist_head *head, dlist_node *node)
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_is_empty(dlist_head *head)
static void dlist_delete(dlist_node *node)
static dlist_node * dlist_next_node(dlist_head *head, dlist_node *node)
static bool dlist_has_next(dlist_head *head, dlist_node *node)
static void dlist_push_tail(dlist_head *head, dlist_node *node)
static bool dlist_has_prev(dlist_head *head, dlist_node *node)
static dlist_node * dlist_head_node(dlist_head *head)
#define dlist_container(type, membername, ptr)
static dlist_node * dlist_tail_node(dlist_head *head)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
ItemPointerData * ItemPointer
#define ItemPointerIsValid(pointer)
struct ItemPointerData ItemPointerData
#define ItemPointerSetInvalid(pointer)
Assert(fmt[strlen(fmt) - 1] !='\n')
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 *)
bool(* isMoveRight)(GinBtree, Page)
GinPlaceToPageRC(* beginPlaceToPage)(GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void **, Page *, Page *)
void *(* prepareDownlink)(GinBtree, Buffer)
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, char *data, int len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)
void XLogRegisterData(char *data, int len)