PostgreSQL Source Code: src/backend/access/gist/gistbuild.c File Reference (original) (raw)
Go to the source code of this file.
Data Structures | |
---|---|
struct | GISTBuildState |
struct | GistSortedBuildLevelState |
struct | ParentMapEntry |
Macros | |
---|---|
#define | BUFFERING_MODE_SWITCH_CHECK_STEP 256 |
#define | BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET 4096 |
#define | GIST_SORTED_BUILD_PAGE_NUM 4 |
◆ BUFFERING_MODE_SWITCH_CHECK_STEP
#define BUFFERING_MODE_SWITCH_CHECK_STEP 256
◆ BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET
#define BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET 4096
◆ GIST_SORTED_BUILD_PAGE_NUM
#define GIST_SORTED_BUILD_PAGE_NUM 4
◆ GistSortedBuildLevelState
◆ GistBuildMode
Enumerator |
---|
GIST_SORTED_BUILD |
GIST_BUFFERING_DISABLED |
GIST_BUFFERING_AUTO |
GIST_BUFFERING_STATS |
GIST_BUFFERING_ACTIVE |
Definition at line 67 of file gistbuild.c.
68{
71
73
74
76
77
@ GIST_BUFFERING_DISABLED
◆ calculatePagesPerBuffer()
static int calculatePagesPerBuffer ( GISTBuildState * buildstate, int levelStep ) | static |
---|
◆ gist_indexsortbuild()
Definition at line 400 of file gistbuild.c.
401{
405
406
407 state->pages_allocated = 1;
408
410
411
414 levelstate->parent = NULL;
416
417
418
419
421 {
424 }
425
426
427
428
429
430
431
433 {
435
437 parent = levelstate->parent;
441 pfree(levelstate);
442 levelstate = parent;
443 }
444
445
448 memcpy(rootbuf, levelstate->pages[0], BLCKSZ);
450
451 pfree(levelstate);
452
454}
static void PageSetLSN(Page page, XLogRecPtr lsn)
BulkWriteState * smgr_bulk_start_rel(Relation rel, ForkNumber forknum)
void smgr_bulk_write(BulkWriteState *bulkstate, BlockNumber blocknum, BulkWriteBuffer buf, bool page_std)
BulkWriteBuffer smgr_bulk_get_buf(BulkWriteState *bulkstate)
void smgr_bulk_finish(BulkWriteState *bulkstate)
static void gist_indexsortbuild_levelstate_flush(GISTBuildState *state, GistSortedBuildLevelState *levelstate)
static void gist_indexsortbuild_levelstate_add(GISTBuildState *state, GistSortedBuildLevelState *levelstate, IndexTuple itup)
#define GIST_SORTED_BUILD_PAGE_NUM
void gistinitpage(Page page, uint32 f)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
void * palloc0(Size size)
Page pages[GIST_SORTED_BUILD_PAGE_NUM]
struct GistSortedBuildLevelState * parent
IndexTuple tuplesort_getindextuple(Tuplesortstate *state, bool forward)
References GistSortedBuildLevelState::current_page, F_LEAF, gist_indexsortbuild_levelstate_add(), gist_indexsortbuild_levelstate_flush(), GIST_ROOT_BLKNO, GIST_SORTED_BUILD_PAGE_NUM, GistBuildLSN, gistinitpage(), i, MAIN_FORKNUM, MemoryContextReset(), GistSortedBuildLevelState::pages, PageSetLSN(), palloc(), palloc0(), GistSortedBuildLevelState::parent, pfree(), smgr_bulk_finish(), smgr_bulk_get_buf(), smgr_bulk_start_rel(), smgr_bulk_write(), and tuplesort_getindextuple().
Referenced by gistbuild().
◆ gist_indexsortbuild_levelstate_add()
Definition at line 461 of file gistbuild.c.
464{
465 Size sizeNeeded;
466
467
470 {
471 Page newPage;
474
476 {
478 }
479 else
481
484
487 }
488
490}
Size PageGetFreeSpace(const PageData *page)
#define GistPageGetOpaque(page)
void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off)
struct ItemIdData ItemIdData
static Size IndexTupleSize(const IndexTupleData *itup)
#define InvalidOffsetNumber
References GistSortedBuildLevelState::current_page, gist_indexsortbuild_levelstate_flush(), GIST_SORTED_BUILD_PAGE_NUM, gistfillbuffer(), gistinitpage(), GistPageGetOpaque, IndexTupleSize(), InvalidOffsetNumber, PageGetFreeSpace(), GistSortedBuildLevelState::pages, and palloc0().
Referenced by gist_indexsortbuild(), and gist_indexsortbuild_levelstate_flush().
◆ gist_indexsortbuild_levelstate_flush()
Definition at line 493 of file gistbuild.c.
495{
502 int vect_len;
504
506
508
509
512 {
513
515 {
516 int len_local;
518
519 itvec = gistjoinvector(itvec, &vect_len, itvec_local, len_local);
520 pfree(itvec_local);
521 }
522
523
525 }
526 else
527 {
528
530 union_tuple = gistunion(state->indexrel, itvec, vect_len,
531 state->giststate);
532 dist->itup = union_tuple;
535 }
536
538
539
541
542
543 for (; dist != NULL; dist = dist->next)
544 {
548
549
551
552
553 data = (char *) (dist->list);
557 for (int i = 0; i < dist->block.num; i++)
558 {
560
563
565 }
566 union_tuple = dist->itup;
567
568
569
570
571
572
573
574
575
576
577
578
579
582
583
584
585
586
587 blkno = state->pages_allocated++;
592
593
594
595
596
597 parent = levelstate->parent;
598 if (parent == NULL)
599 {
602 parent->parent = NULL;
604
605 levelstate->parent = parent;
606 }
608 }
609}
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
SplitPageLayout * gistSplit(Relation r, Page page, IndexTuple *itup, int len, GISTSTATE *giststate)
#define GistPageIsLeaf(page)
IndexTuple * gistextractpage(Page page, int *len)
IndexTuple * gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen)
IndexTuple gistunion(Relation r, IndexTuple *itvec, int len, GISTSTATE *giststate)
IndexTupleData * gistfillitupvec(IndexTuple *vec, int veclen, int *memlen)
static void ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber)
IndexTupleData * IndexTuple
#define CHECK_FOR_INTERRUPTS()
#define FirstOffsetNumber
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define RelationGetRelationName(relation)
struct SplitPageLayout * next
References SplitPageLayout::block, buf, CHECK_FOR_INTERRUPTS, GistSortedBuildLevelState::current_page, data, elog, ERROR, F_LEAF, FirstOffsetNumber, gist_indexsortbuild_levelstate_add(), GistBuildLSN, gistextractpage(), gistfillitupvec(), gistinitpage(), gistjoinvector(), GistPageGetOpaque, GistPageIsLeaf, gistSplit(), gistunion(), i, IndexTupleSize(), InvalidOffsetNumber, ItemPointerSetBlockNumber(), SplitPageLayout::itup, GistSortedBuildLevelState::last_blkno, SplitPageLayout::lenlist, SplitPageLayout::list, MemoryContextSwitchTo(), SplitPageLayout::next, gistxlogPage::num, PageAddItem, GistSortedBuildLevelState::pages, PageSetLSN(), palloc(), palloc0(), GistSortedBuildLevelState::parent, pfree(), RelationGetRelationName, smgr_bulk_get_buf(), smgr_bulk_write(), and IndexTupleData::t_tid.
Referenced by gist_indexsortbuild(), and gist_indexsortbuild_levelstate_add().
◆ gistBufferingBuildInsert()
◆ gistBufferingFindCorrectParent()
Definition at line 1225 of file gistbuild.c.
1229{
1235
1236 if (level > 0)
1238 else
1239 {
1240
1241
1242
1243
1245 elog(ERROR, "no parent buffer provided of child %u", childblkno);
1246 parent = *parentblkno;
1247 }
1248
1254
1255
1258 {
1261
1263 {
1264
1265 return buffer;
1266 }
1267 }
1268
1269
1270
1271
1272
1273
1274
1275
1277 {
1280
1282 {
1283
1284 *downlinkoffnum = off;
1285 return buffer;
1286 }
1287 }
1288
1289 elog(ERROR, "failed to re-find parent for block %u", childblkno);
1291}
#define InvalidBlockNumber
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
static Page BufferGetPage(Buffer buffer)
static Item PageGetItem(const PageData *page, const ItemIdData *itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
static BlockNumber gistGetParent(GISTBuildState *buildstate, BlockNumber child)
void gistcheckpage(Relation rel, Buffer buf)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
#define OffsetNumberNext(offsetNumber)
References BufferGetPage(), elog, ERROR, FirstOffsetNumber, GIST_EXCLUSIVE, gistcheckpage(), gistGetParent(), GISTBuildState::indexrel, InvalidBlockNumber, InvalidBuffer, InvalidOffsetNumber, ItemPointerGetBlockNumber(), LockBuffer(), OffsetNumberNext, PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), GistSortedBuildLevelState::parent, ReadBuffer(), and IndexTupleData::t_tid.
Referenced by gistbufferinginserttuples().
◆ gistbufferinginserttuples()
Definition at line 1056 of file gistbuild.c.
1059{
1061 List *splitinfo;
1062 bool is_split;
1064
1068 buffer,
1069 itup, ntup, oldoffnum, &placed_to_blk,
1071 &splitinfo,
1072 false,
1073 buildstate->heaprel, true);
1074
1075
1076
1077
1078
1079
1080
1082 {
1086
1089
1090 elog(DEBUG2, "splitting GiST root page, now %d levels deep", gfbb->rootlevel);
1091
1092
1093
1094
1095
1096
1098 {
1101 {
1106
1110
1111
1112
1113
1114
1116 }
1117 }
1118 }
1119
1120 if (splitinfo)
1121 {
1122
1123
1124
1125
1126
1127
1129 int ndownlinks,
1130 i;
1131 Buffer parentBuffer;
1133
1134
1135 parentBuffer =
1138 level,
1139 &parentblk,
1140 &downlinkoffnum);
1141
1142
1143
1144
1145
1146
1147
1148
1152 level,
1153 buffer, splitinfo);
1154
1155
1158 i = 0;
1159 foreach(lc, splitinfo)
1160 {
1162
1163
1164
1165
1166
1167
1168
1169
1170 if (level > 0)
1174
1175
1176
1177
1178
1179
1180
1181 if (level > 1)
1183
1184
1185
1186
1187
1189 downlinks[i++] = splitinfo->downlink;
1190 }
1191
1192
1194 downlinks, ndownlinks, downlinkoffnum,
1196
1197 list_free_deep(splitinfo);
1198 }
1199 else
1201
1202 return placed_to_blk;
1203}
BlockNumber BufferGetBlockNumber(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
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)
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 Buffer gistBufferingFindCorrectParent(GISTBuildState *buildstate, BlockNumber childblkno, int level, BlockNumber *parentblkno, OffsetNumber *downlinkoffnum)
static void gistMemorizeParent(GISTBuildState *buildstate, BlockNumber child, BlockNumber parent)
void gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate, Relation r, int level, Buffer buffer, List *splitinfo)
Assert(PointerIsAligned(start, uint64))
void list_free_deep(List *list)
static int list_length(const List *l)
References Assert(), GISTPageSplitInfo::buf, BufferGetBlockNumber(), BufferGetPage(), DEBUG2, GISTPageSplitInfo::downlink, elog, FirstOffsetNumber, GISTBuildState::freespace, GISTBuildState::gfbb, GIST_ROOT_BLKNO, GIST_SHARE, gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistMemorizeAllDownlinks(), gistMemorizeParent(), gistplacetopage(), gistRelocateBuildBuffersOnSplit(), GISTBuildState::giststate, GISTBuildState::heaprel, i, GISTBuildState::indexrel, InvalidBlockNumber, InvalidBuffer, InvalidOffsetNumber, ItemPointerGetBlockNumber(), lfirst, list_free_deep(), list_length(), LockBuffer(), PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), palloc(), ReadBuffer(), GISTBuildBuffers::rootlevel, IndexTupleData::t_tid, and UnlockReleaseBuffer().
Referenced by gistbufferinginserttuples(), and gistProcessItup().
Definition at line 179 of file gistbuild.c.
180{
182 double reltuples;
188
189
190
191
192
194 elog(ERROR, "index \"%s\" already contains data",
196
198 buildstate.heaprel = heap;
201
202
203
204
205
206
208
209
210
211
212
213
215 {
220 else
222 }
223 else
224 {
226 }
227
228
229
230
232 {
233 bool hasallsortsupports = true;
235
236 for (int i = 0; i < keyscount; i++)
237 {
241 {
242 hasallsortsupports = false;
243 break;
244 }
245 }
246 if (hasallsortsupports)
248 }
249
250
251
252
255
256
257
258
261
263 {
264
265
266
270 NULL,
272
273
276 &buildstate, NULL);
277
278
279
280
282
284
286 }
287 else
288 {
289
290
291
292
295
296
300
302
304
307
309
311
312
315 &buildstate, NULL);
316
317
318
319
320
322 {
323 elog(DEBUG1, "all tuples processed, emptying buffers");
326 }
327
328
329
330
331
333 {
336 true);
337 }
338 }
339
340
343
345
346
347
348
350
353
354 return result;
355}
void MarkBufferDirty(Buffer buffer)
#define RelationGetNumberOfBlocks(reln)
#define OidIsValid(objectId)
GISTSTATE * initGISTstate(Relation index)
MemoryContext createTempGistContext(void)
void freeGISTstate(GISTSTATE *giststate)
#define GIST_SORTSUPPORT_PROC
@ GIST_OPTION_BUFFERING_OFF
@ GIST_OPTION_BUFFERING_ON
#define GIST_DEFAULT_FILLFACTOR
static void gist_indexsortbuild(GISTBuildState *state)
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 gistEmptyAllBuffers(GISTBuildState *buildstate)
void gistFreeBuildBuffers(GISTBuildBuffers *gfbb)
Buffer gistNewBuffer(Relation r, Relation heaprel)
void GISTInitBuffer(Buffer b, uint32 f)
RegProcedure index_getprocid(Relation irel, AttrNumber attnum, uint16 procnum)
if(TABLE==NULL||TABLE_index==NULL)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define START_CRIT_SECTION()
#define END_CRIT_SECTION()
#define RelationNeedsWAL(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
Tuplesortstate * sortstate
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)
void tuplesort_performsort(Tuplesortstate *state)
void tuplesort_end(Tuplesortstate *state)
Tuplesortstate * tuplesort_begin_index_gist(Relation heapRel, Relation indexRel, int workMem, SortCoordinate coordinate, int sortopt)
void log_newpage_range(Relation rel, ForkNumber forknum, BlockNumber startblk, BlockNumber endblk, bool page_std)
References Assert(), BufferGetBlockNumber(), BufferGetPage(), GISTBuildState::buildMode, createTempGistContext(), CurrentMemoryContext, DEBUG1, elog, END_CRIT_SECTION, ERROR, F_LEAF, fillfactor, freeGISTstate(), GISTBuildState::freespace, GISTBuildState::gfbb, GIST_BUFFERING_ACTIVE, GIST_BUFFERING_AUTO, GIST_BUFFERING_DISABLED, GIST_BUFFERING_STATS, GIST_DEFAULT_FILLFACTOR, gist_indexsortbuild(), GIST_OPTION_BUFFERING_OFF, GIST_OPTION_BUFFERING_ON, GIST_ROOT_BLKNO, GIST_SORTED_BUILD, GIST_SORTSUPPORT_PROC, gistBuildCallback(), GistBuildLSN, gistEmptyAllBuffers(), gistFreeBuildBuffers(), GISTInitBuffer(), gistNewBuffer(), gistSortedBuildCallback(), GISTBuildState::giststate, IndexBuildResult::heap_tuples, GISTBuildState::heaprel, i, if(), index_getprocid(), INDEX_MAX_KEYS, IndexBuildResult::index_tuples, GISTBuildState::indexrel, IndexRelationGetNumberOfKeyAttributes, GISTBuildState::indtuples, GISTBuildState::indtuplesSize, initGISTstate(), log_newpage_range(), MAIN_FORKNUM, maintenance_work_mem, MarkBufferDirty(), MemoryContextDelete(), MemoryContextSwitchTo(), OidIsValid, PageSetLSN(), palloc(), RelationGetNumberOfBlocks, RelationGetRelationName, RelationNeedsWAL, GISTBuildState::sortstate, START_CRIT_SECTION, table_index_build_scan(), GISTSTATE::tempCxt, tuplesort_begin_index_gist(), tuplesort_end(), TUPLESORT_NONE, tuplesort_performsort(), and UnlockReleaseBuffer().
Referenced by gisthandler().
◆ gistBuildCallback()
static void gistBuildCallback ( Relation index, ItemPointer tid, Datum * values, bool * isnull, bool tupleIsAlive, void * state ) | static |
---|
Definition at line 822 of file gistbuild.c.
828{
832
834
835
838 true);
839 itup->t_tid = *tid;
840
841
844
845
846
847
848
849
850
851
852
853
855 {
856
858 }
859 else
860 {
861
862
863
864
867 }
868
871
874 {
875
878 }
879
880
881
882
883
884
885
886
887
888
889
896 {
897
898
899
900
902 }
903}
static Datum values[MAXATTR]
void gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate, Relation heapRel, bool is_build)
#define BUFFERING_MODE_SWITCH_CHECK_STEP
static int calculatePagesPerBuffer(GISTBuildState *buildstate, int levelStep)
#define BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET
static void gistInitBuffering(GISTBuildState *buildstate)
static void gistBufferingBuildInsert(GISTBuildState *buildstate, IndexTuple itup)
IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, const Datum *attdata, const bool *isnull, bool isleaf)
static SMgrRelation RelationGetSmgr(Relation rel)
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
References BUFFERING_MODE_SWITCH_CHECK_STEP, BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET, GISTBuildState::buildMode, calculatePagesPerBuffer(), effective_cache_size, GISTBuildState::freespace, GISTBuildState::gfbb, GIST_BUFFERING_ACTIVE, GIST_BUFFERING_AUTO, GIST_BUFFERING_STATS, gistBufferingBuildInsert(), gistdoinsert(), gistFormTuple(), gistInitBuffering(), GISTBuildState::giststate, GISTBuildState::heaprel, IndexTupleSize(), GISTBuildState::indtuples, GISTBuildState::indtuplesSize, GISTBuildBuffers::levelStep, MAIN_FORKNUM, MemoryContextReset(), MemoryContextSwitchTo(), GISTBuildBuffers::pagesPerBuffer, RelationGetSmgr(), smgrnblocks(), IndexTupleData::t_tid, GISTSTATE::tempCxt, and values.
Referenced by gistbuild().
◆ gistEmptyAllBuffers()
Definition at line 1372 of file gistbuild.c.
1373{
1376 int i;
1377
1379
1380
1381
1382
1384 {
1385
1386
1387
1388
1389
1390
1391
1393 {
1395
1397
1399 {
1400
1401
1402
1403
1405 {
1411 }
1413 }
1414 else
1417 }
1418 elog(DEBUG2, "emptied all buffers at level %d", i);
1419 }
1421}
List * list_delete_first(List *list)
List * lcons(void *datum, List *list)
List * bufferEmptyingQueue
References GISTNodeBuffer::blocksCount, GISTBuildBuffers::bufferEmptyingQueue, GISTBuildBuffers::buffersOnLevels, GISTBuildBuffers::buffersOnLevelsLen, GISTBuildBuffers::context, DEBUG2, elog, GISTBuildState::gfbb, gistProcessEmptyingQueue(), GISTBuildState::giststate, i, lcons(), linitial, list_delete_first(), MemoryContextSwitchTo(), NIL, GISTNodeBuffer::queuedForEmptying, and GISTSTATE::tempCxt.
Referenced by gistbuild().
◆ gistGetMaxLevel()
static int gistGetMaxLevel ( Relation index) | static |
---|
Definition at line 1427 of file gistbuild.c.
1428{
1429 int maxLevel;
1431
1432
1433
1434
1435
1436 maxLevel = 0;
1438 while (true)
1439 {
1443
1445
1446
1447
1448
1449
1452
1454 {
1455
1457 break;
1458 }
1459
1460
1461
1462
1463
1464
1469
1470
1471
1472
1473
1474 maxLevel++;
1475 }
1476 return maxLevel;
1477}
References BufferGetPage(), FirstOffsetNumber, GIST_ROOT_BLKNO, GIST_SHARE, GistPageIsLeaf, ItemPointerGetBlockNumber(), LockBuffer(), PageGetItem(), PageGetItemId(), ReadBuffer(), IndexTupleData::t_tid, and UnlockReleaseBuffer().
Referenced by gistInitBuffering().
◆ gistGetParent()
Definition at line 1567 of file gistbuild.c.
1568{
1570 bool found;
1571
1572
1574 &child,
1576 &found);
1577 if (!found)
1578 elog(ERROR, "could not find parent of block %u in lookup table", child);
1579
1581}
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
References elog, ERROR, HASH_FIND, hash_search(), ParentMapEntry::parentblkno, and GISTBuildState::parentMap.
Referenced by gistBufferingFindCorrectParent().
◆ gistInitBuffering()
Definition at line 626 of file gistbuild.c.
627{
629 int pagesPerBuffer;
630 Size pageFreeSpace;
631 Size itupAvgSize,
632 itupMinSize;
633 double avgIndexTuplesPerPage,
634 maxIndexTuplesPerPage;
635 int i;
636 int levelStep;
637
638
642
643
644
645
646
647 itupAvgSize = (double) buildstate->indtuplesSize /
649
650
651
652
653
654
655
656
658 for (i = 0; i < index->rd_att->natts; i++)
659 {
661
662 if (attr->attlen < 0)
664 else
665 itupMinSize += attr->attlen;
666 }
667
668
669 avgIndexTuplesPerPage = pageFreeSpace / itupAvgSize;
670 maxIndexTuplesPerPage = pageFreeSpace / itupMinSize;
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719 levelStep = 1;
720 for (;;)
721 {
722 double subtreesize;
723 double maxlowestlevelpages;
724
725
726 subtreesize =
727 (1 - pow(avgIndexTuplesPerPage, (double) (levelStep + 1))) /
728 (1 - avgIndexTuplesPerPage);
729
730
731 maxlowestlevelpages = pow(maxIndexTuplesPerPage, (double) levelStep);
732
733
735 break;
736
737
739 break;
740
741
742 levelStep++;
743 }
744
745
746
747
748
749 levelStep--;
750
751
752
753
754
755 if (levelStep <= 0)
756 {
757 elog(DEBUG1, "failed to switch to buffered GiST build");
759 return;
760 }
761
762
763
764
765
766
768
769
772
774
776
777 elog(DEBUG1, "switched to buffered GiST build; level step = %d, pagesPerBuffer = %d",
778 levelStep, pagesPerBuffer);
779}
static void gistInitParentMap(GISTBuildState *buildstate)
static int gistGetMaxLevel(Relation index)
GISTBuildBuffers * gistInitBuildBuffers(int pagesPerBuffer, int levelStep, int maxLevel)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
References CompactAttribute::attlen, GISTBuildState::buildMode, calculatePagesPerBuffer(), DEBUG1, effective_cache_size, elog, GISTBuildState::freespace, GISTBuildState::gfbb, GIST_BUFFERING_ACTIVE, GIST_BUFFERING_DISABLED, gistGetMaxLevel(), gistInitBuildBuffers(), gistInitParentMap(), i, GISTBuildState::indexrel, GISTBuildState::indtuples, GISTBuildState::indtuplesSize, maintenance_work_mem, MAXALIGN, SizeOfPageHeaderData, TupleDescCompactAttr(), and VARHDRSZ.
Referenced by gistBuildCallback().
◆ gistInitParentMap()
Definition at line 1516 of file gistbuild.c.
1517{
1519
1524 1024,
1525 &hashCtl,
1527}
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
References CurrentMemoryContext, HASHCTL::entrysize, HASH_BLOBS, HASH_CONTEXT, hash_create(), HASH_ELEM, HASHCTL::hcxt, HASHCTL::keysize, and GISTBuildState::parentMap.
Referenced by gistInitBuffering().
◆ gistMemorizeAllDownlinks()
Definition at line 1546 of file gistbuild.c.
1547{
1552
1554
1557 {
1561
1563 }
1564}
References Assert(), BufferGetBlockNumber(), BufferGetPage(), FirstOffsetNumber, gistMemorizeParent(), GistPageIsLeaf, ItemPointerGetBlockNumber(), PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), and IndexTupleData::t_tid.
Referenced by gistbufferinginserttuples().
◆ gistMemorizeParent()
◆ gistProcessEmptyingQueue()
static void gistProcessEmptyingQueue ( GISTBuildState * buildstate) | static |
---|
Definition at line 1299 of file gistbuild.c.
1300{
1302
1303
1305 {
1307
1308
1312
1313
1314
1315
1316
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331 while (true)
1332 {
1334
1335
1337 break;
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1350 {
1351
1352
1353
1354
1355 break;
1356 }
1357
1358
1360 }
1361 }
1362}
bool gistPopItupFromNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple *itup)
void gistUnloadNodeBuffers(GISTBuildBuffers *gfbb)
References GISTBuildBuffers::bufferEmptyingQueue, GISTBuildState::gfbb, gistPopItupFromNodeBuffer(), gistProcessItup(), GISTBuildState::giststate, gistUnloadNodeBuffers(), GISTNodeBuffer::level, linitial, list_delete_first(), MemoryContextReset(), NIL, GISTNodeBuffer::nodeBlocknum, GISTNodeBuffer::queuedForEmptying, and GISTSTATE::tempCxt.
Referenced by gistBufferingBuildInsert(), and gistEmptyAllBuffers().
◆ gistProcessItup()
Definition at line 925 of file gistbuild.c.
927{
933 bool result = false;
935 int level;
938
940
941
942
943
944
945
946 blkno = startblkno;
947 level = startlevel;
948 for (;;)
949 {
952 newtup;
955
956
958 break;
959
960
961 if (level == 0)
962 break;
963
964
965
966
967
968
969 buffer = ReadBuffer(indexrel, blkno);
971
973 childoffnum = gistchoose(indexrel, page, itup, giststate);
977
978 if (level > 1)
980
981
982
983
984
985 newtup = gistgetadjusted(indexrel, idxtuple, itup, giststate);
986 if (newtup)
987 {
989 buffer,
990 level,
991 &newtup,
992 1,
993 childoffnum,
996
997 }
998 else
1000
1001
1002 parentblkno = blkno;
1003 blkno = childblkno;
1004 downlinkoffnum = childoffnum;
1006 level--;
1007 }
1008
1010 {
1011
1012
1013
1014
1016
1017
1018 childNodeBuffer = gistGetNodeBuffer(gfbb, giststate, blkno, level);
1019
1020
1022
1024 result = true;
1025 }
1026 else
1027 {
1028
1029
1030
1032 buffer = ReadBuffer(indexrel, blkno);
1036 parentblkno, downlinkoffnum);
1037
1038 }
1039
1040 return result;
1041}
#define LEVEL_HAS_BUFFERS(nlevel, gfbb)
#define BUFFER_OVERFLOWED(nodeBuffer, gfbb)
void gistPushItupToNodeBuffer(GISTBuildBuffers *gfbb, GISTNodeBuffer *nodeBuffer, IndexTuple itup)
GISTNodeBuffer * gistGetNodeBuffer(GISTBuildBuffers *gfbb, GISTSTATE *giststate, BlockNumber nodeBlocknum, int level)
IndexTuple gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *giststate)
OffsetNumber gistchoose(Relation r, Page p, IndexTuple it, GISTSTATE *giststate)
References Assert(), BUFFER_OVERFLOWED, BufferGetPage(), CHECK_FOR_INTERRUPTS, GISTBuildState::gfbb, GIST_EXCLUSIVE, gistbufferinginserttuples(), gistchoose(), gistgetadjusted(), gistGetNodeBuffer(), gistMemorizeParent(), gistPushItupToNodeBuffer(), GISTBuildState::giststate, GISTBuildState::indexrel, InvalidBlockNumber, InvalidOffsetNumber, ItemPointerGetBlockNumber(), LEVEL_HAS_BUFFERS, LockBuffer(), PageGetItem(), PageGetItemId(), ReadBuffer(), IndexTupleData::t_tid, and UnlockReleaseBuffer().
Referenced by gistBufferingBuildInsert(), and gistProcessEmptyingQueue().
◆ gistSortedBuildCallback()
static void gistSortedBuildCallback ( Relation index, ItemPointer tid, Datum * values, bool * isnull, bool tupleIsAlive, void * state ) | static |
---|
Definition at line 366 of file gistbuild.c.
372{
376
378
379
382 true, compressed_values);
383
386 tid,
387 compressed_values, isnull);
388
391
392
394}
void gistCompressValues(GISTSTATE *giststate, Relation r, const Datum *attdata, const bool *isnull, bool isleaf, Datum *compatt)
void tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel, ItemPointer self, const Datum *values, const bool *isnull)
References gistCompressValues(), GISTBuildState::giststate, INDEX_MAX_KEYS, GISTBuildState::indexrel, GISTBuildState::indtuples, MemoryContextReset(), MemoryContextSwitchTo(), GISTBuildState::sortstate, GISTSTATE::tempCxt, tuplesort_putindextuplevalues(), and values.
Referenced by gistbuild().