32 #define BUFFERING_MODE_SWITCH_CHECK_STEP 256 40 #define BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET 4096 131 if (strcmp(bufferingMode,
"on") == 0)
133 else if (strcmp(bufferingMode,
"off") == 0)
157 elog(
ERROR,
"index \"%s\" already contains data",
214 elog(
DEBUG1,
"all tuples processed, emptying buffers");
244 (strcmp(value,
"on") != 0 &&
245 strcmp(value,
"off") != 0 &&
246 strcmp(value,
"auto") != 0))
249 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
250 errmsg(
"invalid value for \"buffering\" option"),
251 errdetail(
"Valid values are \"on\", \"off\", and \"auto\".")));
271 double avgIndexTuplesPerPage,
272 maxIndexTuplesPerPage;
305 avgIndexTuplesPerPage = pageFreeSpace / itupAvgSize;
306 maxIndexTuplesPerPage = pageFreeSpace / itupMinSize;
359 double maxlowestlevelpages;
363 (1 - pow(avgIndexTuplesPerPage, (
double) (levelStep + 1))) /
364 (1 - avgIndexTuplesPerPage);
367 maxlowestlevelpages = pow(maxIndexTuplesPerPage, (
double) levelStep);
393 elog(
DEBUG1,
"failed to switch to buffered GiST build");
413 elog(
DEBUG1,
"switched to buffered GiST build; level step = %d, pagesPerBuffer = %d",
414 levelStep, pagesPerBuffer);
427 double pagesPerBuffer;
428 double avgIndexTuplesPerPage;
444 avgIndexTuplesPerPage = pageFreeSpace / itupAvgSize;
449 pagesPerBuffer = 2 * pow(avgIndexTuplesPerPage, levelStep);
451 return (
int)
rint(pagesPerBuffer);
594 childoffnum =
gistchoose(indexrel, page, itup, giststate);
625 downlinkoffnum = childoffnum;
657 parentblkno, downlinkoffnum);
690 itup, ntup, oldoffnum, &placed_to_blk,
779 foreach(lc, splitinfo)
809 downlinks[i++] = splitinfo->
downlink;
814 downlinks, ndownlinks, downlinkoffnum,
822 return placed_to_blk;
865 elog(
ERROR,
"no parent buffer provided of child %d", childblkno);
866 parent = *parentblkno;
904 *downlinkoffnum = off;
909 elog(
ERROR,
"failed to re-find parent for block %u", childblkno);
1038 elog(
DEBUG2,
"emptied all buffers at level %d", i);
1156 (
const void *) &
child,
1194 (
const void *) &
child,
1198 elog(
ERROR,
"could not find parent of block %d in lookup table", child);
void gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate, Relation r, int level, Buffer buffer, List *splitinfo)
void MemoryContextDelete(MemoryContext context)
static bool gistProcessItup(GISTBuildState *buildstate, IndexTuple itup, BlockNumber startblkno, int startlevel)
void MarkBufferDirty(Buffer buffer)
void gistPushItupToNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple itup)
MemoryContext createTempGistContext(void)
void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
#define TupleDescAttr(tupdesc, i)
struct SMgrRelationData * rd_smgr
#define END_CRIT_SECTION()
static void gistProcessEmptyingQueue(GISTBuildState *buildstate)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define START_CRIT_SECTION()
int errcode(int sqlerrcode)
#define XLOG_GIST_CREATE_INDEX
void MemoryContextReset(MemoryContext context)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
void gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
#define SizeOfPageHeaderData
GistBufferingMode bufferingMode
static Buffer gistBufferingFindCorrectParent(GISTBuildState *buildstate, BlockNumber childblkno, int level, BlockNumber *parentblk, OffsetNumber *downlinkoffnum)
#define PageGetMaxOffsetNumber(page)
IndexTuple gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *giststate)
void list_free_deep(List *list)
XLogRecPtr gistGetFakeLSN(Relation rel)
static int gistGetMaxLevel(Relation index)
#define BUFFERING_MODE_SWITCH_CHECK_STEP
#define LEVEL_HAS_BUFFERS(nlevel, gfbb)
IndexBuildResult * gistbuild(Relation heap, Relation index, IndexInfo *indexInfo)
static BlockNumber gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber parentblk, OffsetNumber downlinkoffnum)
void UnlockReleaseBuffer(Buffer buffer)
double IndexBuildHeapScan(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, bool allow_sync, IndexBuildCallback callback, void *callback_state, HeapScanDesc scan)
List * bufferEmptyingQueue
bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, Buffer buffer, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber *newblkno, Buffer leftchildbuf, List **splitinfo, bool markfollowright)
GISTBuildBuffers * gistInitBuildBuffers(int pagesPerBuffer, int levelStep, int maxLevel)
void gistValidateBufferingOption(const char *value)
#define FirstOffsetNumber
IndexTupleData * IndexTuple
int errdetail(const char *fmt,...)
GISTNodeBuffer * gistGetNodeBuffer(GISTBuildBuffers *gfbb, GISTSTATE *giststate, BlockNumber nodeBlocknum, int level)
#define RelationGetRelationName(relation)
struct GISTPageOpaqueData GISTPageOpaqueData
MemoryContext CurrentMemoryContext
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)
#define ereport(elevel, rest)
OffsetNumber gistchoose(Relation r, Page p, IndexTuple it, GISTSTATE *giststate)
#define GistPageIsLeaf(page)
#define PageGetItemId(page, offsetNumber)
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
static void gistBufferingBuildInsert(GISTBuildState *buildstate, IndexTuple itup)
void LockBuffer(Buffer buffer, int mode)
#define RelationGetNumberOfBlocks(reln)
void gistUnloadNodeBuffers(GISTBuildBuffers *gfbb)
GISTSTATE * initGISTstate(Relation index)
struct DataPageDeleteStack * child
#define InvalidOffsetNumber
static void gistEmptyAllBuffers(GISTBuildState *buildstate)
List * lcons(void *datum, List *list)
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
#define Assert(condition)
struct DataPageDeleteStack * parent
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
void gistcheckpage(Relation rel, Buffer buf)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
static void gistMemorizeParent(GISTBuildState *buildstate, BlockNumber child, BlockNumber parent)
#define OffsetNumberNext(offsetNumber)
static void gistMemorizeAllDownlinks(GISTBuildState *buildstate, Buffer parent)
#define InvalidBlockNumber
static int list_length(const List *l)
#define RelationNeedsWAL(relation)
static Datum values[MAXATTR]
BlockNumber BufferGetBlockNumber(Buffer buffer)
void gistFreeBuildBuffers(GISTBuildBuffers *gfbb)
int errmsg(const char *fmt,...)
static void gistBuildCallback(Relation index, HeapTuple htup, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
static void gistInitBuffering(GISTBuildState *buildstate)
void GISTInitBuffer(Buffer b, uint32 f)
#define BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET
IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, Datum attdata[], bool isnull[], bool isleaf)
#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 XLogBeginInsert(void)
#define PageSetLSN(page, lsn)
Buffer gistNewBuffer(Relation r)
#define PageGetItem(page, itemId)
#define IndexTupleSize(itup)
List * list_delete_first(List *list)