52 #define BUFFERING_MODE_SWITCH_CHECK_STEP 256 60 #define BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET 4096 131 bool tupleIsAlive,
void *
state);
190 elog(
ERROR,
"index \"%s\" already contains data",
229 bool hasallsortsupports =
true;
232 for (
int i = 0;
i < keyscount;
i++)
238 hasallsortsupports =
false;
242 if (hasallsortsupports)
272 (
void *) &buildstate, NULL);
311 (
void *) &buildstate, NULL);
319 elog(
DEBUG1,
"all tuples processed, emptying buffers");
378 true, compressed_values);
383 compressed_values, isnull);
438 pagestate = leafstate;
439 while (pagestate->
parent != NULL)
444 parent = pagestate->
parent;
457 pagestate->
page,
true);
460 pagestate->
page,
true);
529 parent = pagestate->
parent;
574 elog(
ERROR,
"unexpected block number to flush GiST sorting build");
615 double avgIndexTuplesPerPage,
616 maxIndexTuplesPerPage;
649 avgIndexTuplesPerPage = pageFreeSpace / itupAvgSize;
650 maxIndexTuplesPerPage = pageFreeSpace / itupMinSize;
703 double maxlowestlevelpages;
707 (1 - pow(avgIndexTuplesPerPage, (
double) (levelStep + 1))) /
708 (1 - avgIndexTuplesPerPage);
711 maxlowestlevelpages = pow(maxIndexTuplesPerPage, (
double) levelStep);
737 elog(
DEBUG1,
"failed to switch to buffered GiST build");
757 elog(
DEBUG1,
"switched to buffered GiST build; level step = %d, pagesPerBuffer = %d",
758 levelStep, pagesPerBuffer);
771 double pagesPerBuffer;
772 double avgIndexTuplesPerPage;
788 avgIndexTuplesPerPage = pageFreeSpace / itupAvgSize;
793 pagesPerBuffer = 2 * pow(avgIndexTuplesPerPage, levelStep);
795 return (
int) rint(pagesPerBuffer);
943 childoffnum =
gistchoose(indexrel, page, itup, giststate);
974 downlinkoffnum = childoffnum;
1006 parentblkno, downlinkoffnum);
1039 itup, ntup, oldoffnum, &placed_to_blk,
1129 foreach(lc, splitinfo)
1159 downlinks[i++] = splitinfo->
downlink;
1164 downlinks, ndownlinks, downlinkoffnum,
1172 return placed_to_blk;
1215 elog(
ERROR,
"no parent buffer provided of child %d", childblkno);
1216 parent = *parentblkno;
1254 *downlinkoffnum = off;
1259 elog(
ERROR,
"failed to re-find parent for block %u", childblkno);
1388 elog(
DEBUG2,
"emptied all buffers at level %d", i);
1506 (
const void *) &child,
1544 (
const void *) &child,
1548 elog(
ERROR,
"could not find parent of block %d in lookup table", child);
IndexTuple tuplesort_getindextuple(Tuplesortstate *state, bool forward)
void gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate, Relation r, int level, Buffer buffer, List *splitinfo)
void tuplesort_performsort(Tuplesortstate *state)
void MemoryContextDelete(MemoryContext context)
GistOptBufferingMode buffering_mode
BlockNumber pages_written
static bool gistProcessItup(GISTBuildState *buildstate, IndexTuple itup, BlockNumber startblkno, int startlevel)
static void gistBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
void MarkBufferDirty(Buffer buffer)
void gistPushItupToNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple itup)
MemoryContext createTempGistContext(void)
#define TupleDescAttr(tupdesc, i)
#define GIST_SORTSUPPORT_PROC
struct SMgrRelationData * rd_smgr
void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off)
#define END_CRIT_SECTION()
static void gistProcessEmptyingQueue(GISTBuildState *buildstate)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
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)
#define START_CRIT_SECTION()
void MemoryContextReset(MemoryContext context)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
struct GistSortedBuildPageState GistSortedBuildPageState
#define SizeOfPageHeaderData
static void gist_indexsortbuild(GISTBuildState *state)
static Buffer gistBufferingFindCorrectParent(GISTBuildState *buildstate, BlockNumber childblkno, int level, BlockNumber *parentblk, OffsetNumber *downlinkoffnum)
#define OidIsValid(objectId)
#define PageGetMaxOffsetNumber(page)
IndexTuple gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *giststate)
void list_free_deep(List *list)
void gistinitpage(Page page, uint32 f)
static int gistGetMaxLevel(Relation index)
Size PageGetFreeSpace(Page page)
#define BUFFERING_MODE_SWITCH_CHECK_STEP
#define LEVEL_HAS_BUFFERS(nlevel, gfbb)
Page ready_pages[XLR_MAX_BLOCK_ID]
IndexBuildResult * gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
static void gistSortedBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
#define RelationOpenSmgr(relation)
IndexTuple * gistextractpage(Page page, int *len)
static BlockNumber gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber parentblk, OffsetNumber downlinkoffnum)
void pfree(void *pointer)
Tuplesortstate * tuplesort_begin_index_gist(Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, bool randomAccess)
BlockNumber pages_allocated
void UnlockReleaseBuffer(Buffer buffer)
void gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate, Relation heapRel, bool is_build)
List * bufferEmptyingQueue
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)
GISTBuildBuffers * gistInitBuildBuffers(int pagesPerBuffer, int levelStep, int maxLevel)
void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
#define FirstOffsetNumber
IndexTupleData * IndexTuple
GISTNodeBuffer * gistGetNodeBuffer(GISTBuildBuffers *gfbb, GISTSTATE *giststate, BlockNumber nodeBlocknum, int level)
#define RelationGetRelationName(relation)
struct GISTPageOpaqueData GISTPageOpaqueData
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void gistCompressValues(GISTSTATE *giststate, Relation r, Datum *attdata, bool *isnull, bool isleaf, Datum *compatt)
struct ItemIdData ItemIdData
MemoryContext CurrentMemoryContext
#define IndexRelationGetNumberOfKeyAttributes(relation)
static int calculatePagesPerBuffer(GISTBuildState *buildstate, int levelStep)
#define GIST_DEFAULT_FILLFACTOR
#define BufferGetPage(buffer)
void freeGISTstate(GISTSTATE *giststate)
static BlockNumber gistGetParent(GISTBuildState *buildstate, BlockNumber child)
BlockNumber ready_blknos[XLR_MAX_BLOCK_ID]
OffsetNumber gistchoose(Relation r, Page p, IndexTuple it, GISTSTATE *giststate)
#define GistPageIsLeaf(page)
#define PageGetItemId(page, offsetNumber)
static void gist_indexsortbuild_pagestate_add(GISTBuildState *state, GistSortedBuildPageState *pagestate, IndexTuple itup)
static void gist_indexsortbuild_flush_ready_pages(GISTBuildState *state)
struct GistSortedBuildPageState * parent
void * palloc0(Size size)
static void gist_indexsortbuild_pagestate_flush(GISTBuildState *state, GistSortedBuildPageState *pagestate)
static void gistBufferingBuildInsert(GISTBuildState *buildstate, IndexTuple itup)
void LockBuffer(Buffer buffer, int mode)
#define RelationGetNumberOfBlocks(reln)
void gistUnloadNodeBuffers(GISTBuildBuffers *gfbb)
GISTSTATE * initGISTstate(Relation index)
#define InvalidOffsetNumber
void tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel, ItemPointer self, Datum *values, bool *isnull)
static void gistEmptyAllBuffers(GISTBuildState *buildstate)
#define GistPageGetOpaque(page)
List * lcons(void *datum, List *list)
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
#define Assert(condition)
void gistcheckpage(Relation rel, Buffer buf)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
static void gistMemorizeParent(GISTBuildState *buildstate, BlockNumber child, BlockNumber parent)
#define OffsetNumberNext(offsetNumber)
IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, Datum *attdata, bool *isnull, bool isleaf)
static void gistMemorizeAllDownlinks(GISTBuildState *buildstate, Buffer parent)
#define InvalidBlockNumber
static int list_length(const List *l)
void PageSetChecksumInplace(Page page, BlockNumber blkno)
#define ItemPointerSetBlockNumber(pointer, blockNumber)
#define RelationNeedsWAL(relation)
void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
static Datum values[MAXATTR]
void log_newpage_range(Relation rel, ForkNumber forkNum, BlockNumber startblk, BlockNumber endblk, bool page_std)
void log_newpages(RelFileNode *rnode, ForkNumber forkNum, int num_pages, BlockNumber *blknos, Page *pages, bool page_std)
BlockNumber BufferGetBlockNumber(Buffer buffer)
void gistFreeBuildBuffers(GISTBuildBuffers *gfbb)
IndexTuple gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno, Page page, bool page_std)
static void gistInitBuffering(GISTBuildState *buildstate)
void GISTInitBuffer(Buffer b, uint32 f)
#define BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET
#define BUFFER_OVERFLOWED(nodeBuffer, gfbb)
static void gistInitParentMap(GISTBuildState *buildstate)
#define CHECK_FOR_INTERRUPTS()
#define ItemPointerGetBlockNumber(pointer)
bool gistPopItupFromNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple *itup)
void tuplesort_end(Tuplesortstate *state)
#define PageSetLSN(page, lsn)
Buffer gistNewBuffer(Relation r)
#define PageGetItem(page, itemId)
#define IndexTupleSize(itup)
List * list_delete_first(List *list)
Tuplesortstate * sortstate
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)