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)
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);
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)
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)
elog(ERROR, "%s: %s", p2, msg)
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_out)
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_has_next(const dlist_head *head, const dlist_node *node)
static bool dlist_has_prev(const dlist_head *head, const dlist_node *node)
static void dlist_delete(dlist_node *node)
static dlist_node * dlist_next_node(dlist_head *head, dlist_node *node)
static bool dlist_is_empty(const dlist_head *head)
static void dlist_push_tail(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)
static void ItemPointerSetInvalid(ItemPointerData *pointer)
ItemPointerData * ItemPointer
struct ItemPointerData ItemPointerData
static bool ItemPointerIsValid(const ItemPointerData *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)
void XLogRegisterData(char *data, uint32 len)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterBufData(uint8 block_id, char *data, uint32 len)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
void XLogBeginInsert(void)