52 #define BUFFERING_MODE_SWITCH_CHECK_STEP 256
60 #define BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET 4096
116 #define GIST_SORTED_BUILD_PAGE_NUM 4
138 bool tupleIsAlive,
void *
state);
198 elog(
ERROR,
"index \"%s\" already contains data",
237 bool hasallsortsupports =
true;
240 for (
int i = 0;
i < keyscount;
i++)
246 hasallsortsupports =
false;
250 if (hasallsortsupports)
280 (
void *) &buildstate, NULL);
319 (
void *) &buildstate, NULL);
327 elog(
DEBUG1,
"all tuples processed, emptying buffers");
386 true, compressed_values);
391 compressed_values, isnull);
410 state->pages_allocated = 0;
411 state->pages_written = 0;
412 state->ready_num_pages = 0;
421 state->pages_allocated++;
422 state->pages_written++;
426 levelstate->
pages[0] = page;
427 levelstate->
parent = NULL;
464 levelstate->
pages[0],
true);
467 levelstate->
pages[0],
true);
562 dist->
itup = union_tuple;
573 for (; dist != NULL; dist = dist->
next)
594 union_tuple = dist->
itup;
604 blkno =
state->pages_allocated++;
605 state->ready_blknos[
state->ready_num_pages] = blkno;
606 state->ready_pages[
state->ready_num_pages] = target;
607 state->ready_num_pages++;
647 if (
state->ready_num_pages == 0)
650 for (
int i = 0;
i <
state->ready_num_pages;
i++)
656 if (blkno !=
state->pages_written)
657 elog(
ERROR,
"unexpected block number to flush GiST sorting build");
664 state->pages_written++;
669 state->ready_blknos,
state->ready_pages,
true);
671 for (
int i = 0;
i <
state->ready_num_pages;
i++)
674 state->ready_num_pages = 0;
699 double avgIndexTuplesPerPage,
700 maxIndexTuplesPerPage;
724 for (
i = 0;
i <
index->rd_att->natts;
i++)
733 avgIndexTuplesPerPage = pageFreeSpace / itupAvgSize;
734 maxIndexTuplesPerPage = pageFreeSpace / itupMinSize;
787 double maxlowestlevelpages;
791 (1 - pow(avgIndexTuplesPerPage, (
double) (levelStep + 1))) /
792 (1 - avgIndexTuplesPerPage);
795 maxlowestlevelpages = pow(maxIndexTuplesPerPage, (
double) levelStep);
821 elog(
DEBUG1,
"failed to switch to buffered GiST build");
841 elog(
DEBUG1,
"switched to buffered GiST build; level step = %d, pagesPerBuffer = %d",
842 levelStep, pagesPerBuffer);
855 double pagesPerBuffer;
856 double avgIndexTuplesPerPage;
872 avgIndexTuplesPerPage = pageFreeSpace / itupAvgSize;
877 pagesPerBuffer = 2 * pow(avgIndexTuplesPerPage, levelStep);
879 return (
int) rint(pagesPerBuffer);
1037 childoffnum =
gistchoose(indexrel, page, itup, giststate);
1066 parentblkno = blkno;
1068 downlinkoffnum = childoffnum;
1100 parentblkno, downlinkoffnum);
1133 itup, ntup, oldoffnum, &placed_to_blk,
1223 foreach(lc, splitinfo)
1258 downlinks, ndownlinks, downlinkoffnum,
1266 return placed_to_blk;
1309 elog(
ERROR,
"no parent buffer provided of child %u", childblkno);
1348 *downlinkoffnum = off;
1353 elog(
ERROR,
"failed to re-find parent for block %u", childblkno);
1482 elog(
DEBUG2,
"emptied all buffers at level %d",
i);
1642 elog(
ERROR,
"could not find parent of block %u in lookup table", child);
#define InvalidBlockNumber
static Datum values[MAXATTR]
BlockNumber BufferGetBlockNumber(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
void PageSetChecksumInplace(Page page, BlockNumber blkno)
Size PageGetFreeSpace(Page page)
static Item PageGetItem(Page page, ItemId itemId)
#define SizeOfPageHeaderData
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define OidIsValid(objectId)
elog(ERROR, "%s: %s", p2, msg)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate, Relation heapRel, bool is_build)
bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, Buffer buffer, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber *newblkno, Buffer leftchildbuf, List **splitinfo, bool markfollowright, Relation heapRel, bool is_build)
SplitedPageLayout * gistSplit(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate)
GISTSTATE * initGISTstate(Relation index)
MemoryContext createTempGistContext(void)
void freeGISTstate(GISTSTATE *giststate)
#define GIST_SORTSUPPORT_PROC
struct GISTPageOpaqueData GISTPageOpaqueData
#define GistPageIsLeaf(page)
#define GistPageGetOpaque(page)
#define LEVEL_HAS_BUFFERS(nlevel, gfbb)
@ GIST_OPTION_BUFFERING_OFF
@ GIST_OPTION_BUFFERING_ON
#define GIST_DEFAULT_FILLFACTOR
#define BUFFER_OVERFLOWED(nodeBuffer, gfbb)
@ GIST_BUFFERING_DISABLED
static BlockNumber gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber parentblk, OffsetNumber downlinkoffnum)
static void gistMemorizeAllDownlinks(GISTBuildState *buildstate, Buffer parentbuf)
static bool gistProcessItup(GISTBuildState *buildstate, IndexTuple itup, BlockNumber startblkno, int startlevel)
static void gist_indexsortbuild_levelstate_flush(GISTBuildState *state, GistSortedBuildLevelState *levelstate)
#define BUFFERING_MODE_SWITCH_CHECK_STEP
static Buffer gistBufferingFindCorrectParent(GISTBuildState *buildstate, BlockNumber childblkno, int level, BlockNumber *parentblkno, OffsetNumber *downlinkoffnum)
static int calculatePagesPerBuffer(GISTBuildState *buildstate, int levelStep)
static void gist_indexsortbuild_levelstate_add(GISTBuildState *state, GistSortedBuildLevelState *levelstate, IndexTuple itup)
static void gist_indexsortbuild(GISTBuildState *state)
static void gistInitParentMap(GISTBuildState *buildstate)
static void gistBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
static void gistSortedBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
static void gistMemorizeParent(GISTBuildState *buildstate, BlockNumber child, BlockNumber parent)
#define GIST_SORTED_BUILD_PAGE_NUM
static void gistEmptyAllBuffers(GISTBuildState *buildstate)
#define BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET
static void gistInitBuffering(GISTBuildState *buildstate)
static void gist_indexsortbuild_flush_ready_pages(GISTBuildState *state)
static void gistBufferingBuildInsert(GISTBuildState *buildstate, IndexTuple itup)
IndexBuildResult * gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
static BlockNumber gistGetParent(GISTBuildState *buildstate, BlockNumber child)
static int gistGetMaxLevel(Relation index)
struct GistSortedBuildLevelState GistSortedBuildLevelState
static void gistProcessEmptyingQueue(GISTBuildState *buildstate)
void gistPushItupToNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple itup)
void gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate, Relation r, int level, Buffer buffer, List *splitinfo)
GISTBuildBuffers * gistInitBuildBuffers(int pagesPerBuffer, int levelStep, int maxLevel)
void gistFreeBuildBuffers(GISTBuildBuffers *gfbb)
GISTNodeBuffer * gistGetNodeBuffer(GISTBuildBuffers *gfbb, GISTSTATE *giststate, BlockNumber nodeBlocknum, int level)
bool gistPopItupFromNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple *itup)
void gistUnloadNodeBuffers(GISTBuildBuffers *gfbb)
IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, Datum *attdata, bool *isnull, bool isleaf)
Buffer gistNewBuffer(Relation r, Relation heaprel)
void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off)
IndexTuple * gistextractpage(Page page, int *len)
IndexTuple gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *giststate)
OffsetNumber gistchoose(Relation r, Page p, IndexTuple it, GISTSTATE *giststate)
IndexTuple * gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)
void gistinitpage(Page page, uint32 f)
IndexTuple gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
void GISTInitBuffer(Buffer b, uint32 f)
IndexTupleData * gistfillitupvec(IndexTuple *vec, int veclen, int *memlen)
void gistCompressValues(GISTSTATE *giststate, Relation r, Datum *attdata, bool *isnull, bool isleaf, Datum *compatt)
void gistcheckpage(Relation rel, Buffer buf)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
if(TABLE==NULL||TABLE_index==NULL)
struct ItemIdData ItemIdData
static void ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
IndexTupleData * IndexTuple
#define IndexTupleSize(itup)
Assert(fmt[strlen(fmt) - 1] !='\n')
List * list_delete_first(List *list)
List * lcons(void *datum, List *list)
void list_free_deep(List *list)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * palloc_aligned(Size size, Size alignto, int flags)
void MemoryContextDelete(MemoryContext context)
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define END_CRIT_SECTION()
#define InvalidOffsetNumber
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static int list_length(const List *l)
static SMgrRelation RelationGetSmgr(Relation rel)
#define RelationGetRelationName(relation)
#define RelationNeedsWAL(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
void smgrimmedsync(SMgrRelation reln, ForkNumber forknum)
void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
List * bufferEmptyingQueue
BlockNumber pages_allocated
BlockNumber pages_written
Tuplesortstate * sortstate
Page pages[GIST_SORTED_BUILD_PAGE_NUM]
struct GistSortedBuildLevelState * parent
struct SplitedPageLayout * next
static double table_index_build_scan(Relation table_rel, Relation index_rel, struct IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
#define TupleDescAttr(tupdesc, i)
void tuplesort_performsort(Tuplesortstate *state)
void tuplesort_end(Tuplesortstate *state)
IndexTuple tuplesort_getindextuple(Tuplesortstate *state, bool forward)
Tuplesortstate * tuplesort_begin_index_gist(Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
void tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel, ItemPointer self, Datum *values, bool *isnull)
XLogRecPtr log_newpage(RelFileLocator *rlocator, ForkNumber forknum, BlockNumber blkno, Page page, bool page_std)
void log_newpages(RelFileLocator *rlocator, ForkNumber forknum, int num_pages, BlockNumber *blknos, Page *pages, bool page_std)
void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std)