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
Functions
static void gistSortedBuildCallback (Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
static void gist_indexsortbuild (GISTBuildState *state)
static void gist_indexsortbuild_levelstate_add (GISTBuildState *state, GistSortedBuildLevelState *levelstate, IndexTuple itup)
static void gist_indexsortbuild_levelstate_flush (GISTBuildState *state, GistSortedBuildLevelState *levelstate)
static void gistInitBuffering (GISTBuildState *buildstate)
static int calculatePagesPerBuffer (GISTBuildState *buildstate, int levelStep)
static void gistBuildCallback (Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
static void gistBufferingBuildInsert (GISTBuildState *buildstate, IndexTuple itup)
static bool gistProcessItup (GISTBuildState *buildstate, IndexTuple itup, BlockNumber startblkno, int startlevel)
static BlockNumber gistbufferinginserttuples (GISTBuildState *buildstate, Buffer buffer, int level, IndexTuple *itup, int ntup, OffsetNumber oldoffnum, BlockNumber parentblk, OffsetNumber downlinkoffnum)
static Buffer gistBufferingFindCorrectParent (GISTBuildState *buildstate, BlockNumber childblkno, int level, BlockNumber *parentblkno, OffsetNumber *downlinkoffnum)
static void gistProcessEmptyingQueue (GISTBuildState *buildstate)
static void gistEmptyAllBuffers (GISTBuildState *buildstate)
static int gistGetMaxLevel (Relation index)
static void gistInitParentMap (GISTBuildState *buildstate)
static void gistMemorizeParent (GISTBuildState *buildstate, BlockNumber child, BlockNumber parent)
static void gistMemorizeAllDownlinks (GISTBuildState *buildstate, Buffer parentbuf)
static BlockNumber gistGetParent (GISTBuildState *buildstate, BlockNumber child)
IndexBuildResult * gistbuild (Relation heap, Relation index, IndexInfo *indexInfo)

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;

439 if (levelstate->pages[i])

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().

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().