Skip to content

Commit 6e92bb0

Browse files
authored
Increase index flags capacity in ODS14 (#8340)
* Increase index flags capacity. Store transaction number as plain int64. Avoid private data members in ODS structures. Fix SLONG->ULONG in page numbers in gstat. * Revert back private members of irt_repeat * Fix alignment incompatibility between 32-bit and 64-bit builds. Partially sync with the tablespace branch to simplify merging the code later. * Sync with the metacache branch
1 parent 93db880 commit 6e92bb0

File tree

8 files changed

+126
-90
lines changed

8 files changed

+126
-90
lines changed

src/jrd/btr.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -924,12 +924,12 @@ bool BTR_delete_index(thread_db* tdbb, WIN* window, USHORT id)
924924
{
925925
index_root_page::irt_repeat* irt_desc = root->irt_rpt + id;
926926
CCH_MARK(tdbb, window);
927-
const PageNumber next(window->win_page.getPageSpaceID(), irt_desc->getRoot());
928-
tree_exists = (irt_desc->getRoot() != 0);
927+
const ULONG rootPage = irt_desc->getRoot();
928+
const PageNumber next(window->win_page.getPageSpaceID(), rootPage);
929+
tree_exists = (rootPage != 0);
929930

930931
// remove the pointer to the top-level index page before we delete it
931-
irt_desc->setRoot(0);
932-
irt_desc->irt_flags = 0;
932+
irt_desc->setEmpty();
933933
const PageNumber prior = window->win_page;
934934
const USHORT relation_id = root->irt_relation;
935935

@@ -962,11 +962,12 @@ bool BTR_description(thread_db* tdbb, jrd_rel* relation, index_root_page* root,
962962

963963
const index_root_page::irt_repeat* irt_desc = &root->irt_rpt[id];
964964

965-
if (irt_desc->getRoot() == 0)
965+
const ULONG rootPage = irt_desc->getRoot();
966+
if (!rootPage)
966967
return false;
967968

968969
idx->idx_id = id;
969-
idx->idx_root = irt_desc->getRoot();
970+
idx->idx_root = rootPage;
970971
idx->idx_count = irt_desc->irt_keys;
971972
idx->idx_flags = irt_desc->irt_flags;
972973
idx->idx_runtime_flags = 0;
@@ -2124,18 +2125,18 @@ bool BTR_next_index(thread_db* tdbb, jrd_rel* relation, jrd_tra* transaction, in
21242125
for (; id < root->irt_count; ++id)
21252126
{
21262127
const index_root_page::irt_repeat* irt_desc = root->irt_rpt + id;
2127-
if (irt_desc->getTransaction() && transaction)
2128+
const TraNumber inProgressTrans = irt_desc->inProgress();
2129+
if (inProgressTrans && transaction)
21282130
{
2129-
const TraNumber trans = irt_desc->getTransaction();
21302131
CCH_RELEASE(tdbb, window);
2131-
const int trans_state = TRA_wait(tdbb, transaction, trans, jrd_tra::tra_wait);
2132+
const int trans_state = TRA_wait(tdbb, transaction, inProgressTrans, jrd_tra::tra_wait);
21322133
if ((trans_state == tra_dead) || (trans_state == tra_committed))
21332134
{
21342135
// clean up this left-over index
21352136
root = (index_root_page*) CCH_FETCH(tdbb, window, LCK_write, pag_root);
21362137
irt_desc = root->irt_rpt + id;
21372138

2138-
if (irt_desc->getTransaction() == trans)
2139+
if (irt_desc->inProgress() == inProgressTrans)
21392140
BTR_delete_index(tdbb, window, id);
21402141
else
21412142
CCH_RELEASE(tdbb, window);
@@ -2359,7 +2360,7 @@ void BTR_reserve_slot(thread_db* tdbb, IndexCreation& creation)
23592360
fb_assert(idx->idx_count <= MAX_UCHAR);
23602361
slot->irt_keys = (UCHAR) idx->idx_count;
23612362
slot->irt_flags = idx->idx_flags;
2362-
slot->setTransaction(transaction->tra_number);
2363+
slot->setInProgress(transaction->tra_number);
23632364

23642365
// Exploit the fact idx_repeat structure matches ODS IRTD one
23652366
memcpy(desc, idx->idx_rpt, len);
@@ -2393,13 +2394,13 @@ void BTR_selectivity(thread_db* tdbb, jrd_rel* relation, USHORT id, SelectivityL
23932394
if (!root)
23942395
return;
23952396

2396-
ULONG page;
2397-
if (id >= root->irt_count || !(page = root->irt_rpt[id].getRoot()))
2397+
if (id >= root->irt_count || !root->irt_rpt[id].getRoot())
23982398
{
23992399
CCH_RELEASE(tdbb, &window);
24002400
return;
24012401
}
24022402

2403+
ULONG page = root->irt_rpt[id].getRoot();
24032404
const bool descending = (root->irt_rpt[id].irt_flags & irt_descending);
24042405
const ULONG segments = root->irt_rpt[id].irt_keys;
24052406

src/jrd/btr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ struct index_desc
5858
ULONG idx_root; // Index root
5959
float idx_selectivity; // selectivity of index
6060
USHORT idx_id;
61-
UCHAR idx_flags;
61+
USHORT idx_flags;
6262
UCHAR idx_runtime_flags; // flags used at runtime, not stored on disk
6363
USHORT idx_primary_index; // id for primary key partner index
6464
USHORT idx_primary_relation; // id for primary key partner relation

src/jrd/idx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct ini_idx_t
3636
{
3737
UCHAR ini_idx_index_id;
3838
UCHAR ini_idx_relid;
39-
UCHAR ini_idx_flags;
39+
USHORT ini_idx_flags;
4040
UCHAR ini_idx_segment_count;
4141
USHORT ini_idx_ods;
4242
struct ini_idx_segment_t

src/jrd/ini.epp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1636,7 +1636,7 @@ static void store_indices(thread_db* tdbb, USHORT odsVersion)
16361636
PAD(relation->rel_name, X.RDB$RELATION_NAME);
16371637
PAD(indexName, X.RDB$INDEX_NAME);
16381638

1639-
X.RDB$UNIQUE_FLAG = index->ini_idx_flags & idx_unique;
1639+
X.RDB$UNIQUE_FLAG = (index->ini_idx_flags & idx_unique) ? 1 : 0;
16401640
X.RDB$SEGMENT_COUNT = index->ini_idx_segment_count;
16411641

16421642
if (index->ini_idx_flags & idx_descending)

src/jrd/ods.h

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -366,42 +366,51 @@ struct index_root_page
366366
{
367367
pag irt_header;
368368
USHORT irt_relation; // relation id (for consistency)
369-
USHORT irt_count; // Number of indices
369+
USHORT irt_count; // number of indices
370+
ULONG irt_dummy; // so far used as a padding to ensure the same
371+
// alignment between 32-bit and 64-bit builds
370372
struct irt_repeat
371373
{
374+
friend class index_root_page; // to allow offset check for private members
375+
372376
private:
373-
friend struct index_root_page; // to allow offset check for private members
374-
ULONG irt_root; // page number of index root if irt_in_progress is NOT set, or
375-
// highest 32 bit of transaction if irt_in_progress is set
376-
ULONG irt_transaction; // transaction in progress (lowest 32 bits)
377+
FB_UINT64 irt_transaction; // transaction in progress
378+
ULONG irt_page_num; // page number
379+
ULONG irt_page_space_id; // page space
377380
public:
378-
USHORT irt_desc; // offset to key descriptions
379-
UCHAR irt_keys; // number of keys in index
380-
UCHAR irt_flags;
381+
USHORT irt_desc; // offset to key descriptions
382+
USHORT irt_flags; // index flags
383+
UCHAR irt_state; // index state
384+
UCHAR irt_keys; // number of keys in index
385+
private:
386+
USHORT irt_dummy; // alignment to 8-byte boundary
381387

382-
ULONG getRoot() const;
383-
void setRoot(ULONG root_page);
388+
public:
389+
TraNumber inProgress() const;
390+
void setInProgress(TraNumber traNumber);
384391

385-
TraNumber getTransaction() const;
386-
void setTransaction(TraNumber traNumber);
392+
ULONG getRoot() const;
393+
void setRoot(ULONG rootPage);
387394

388395
bool isUsed() const;
389-
396+
void setEmpty();
390397
} irt_rpt[1];
391398

392-
static_assert(sizeof(struct irt_repeat) == 12, "struct irt_repeat size mismatch");
393-
static_assert(offsetof(struct irt_repeat, irt_root) == 0, "irt_root offset mismatch");
394-
static_assert(offsetof(struct irt_repeat, irt_transaction) == 4, "irt_transaction offset mismatch");
395-
static_assert(offsetof(struct irt_repeat, irt_desc) == 8, "irt_desc offset mismatch");
396-
static_assert(offsetof(struct irt_repeat, irt_keys) == 10, "irt_keys offset mismatch");
397-
static_assert(offsetof(struct irt_repeat, irt_flags) == 11, "irt_flags offset mismatch");
399+
static_assert(sizeof(struct irt_repeat) == 24, "struct irt_repeat size mismatch");
400+
static_assert(offsetof(struct irt_repeat, irt_transaction) == 0, "irt_transaction offset mismatch");
401+
static_assert(offsetof(struct irt_repeat, irt_page_num) == 8, "irt_root offset mismatch");
402+
static_assert(offsetof(struct irt_repeat, irt_page_space_id) == 12, "irt_root offset mismatch");
403+
static_assert(offsetof(struct irt_repeat, irt_desc) == 16, "irt_desc offset mismatch");
404+
static_assert(offsetof(struct irt_repeat, irt_flags) == 18, "irt_flags offset mismatch");
405+
static_assert(offsetof(struct irt_repeat, irt_state) == 20, "irt_state offset mismatch");
406+
static_assert(offsetof(struct irt_repeat, irt_keys) == 21, "irt_keys offset mismatch");
398407
};
399408

400-
static_assert(sizeof(struct index_root_page) == 32, "struct index_root_page size mismatch");
409+
static_assert(sizeof(struct index_root_page) == 48, "struct index_root_page size mismatch");
401410
static_assert(offsetof(struct index_root_page, irt_header) == 0, "irt_header offset mismatch");
402411
static_assert(offsetof(struct index_root_page, irt_relation) == 16, "irt_relation offset mismatch");
403412
static_assert(offsetof(struct index_root_page, irt_count) == 18, "irt_count offset mismatch");
404-
static_assert(offsetof(struct index_root_page, irt_rpt) == 20, "irt_rpt offset mismatch");
413+
static_assert(offsetof(struct index_root_page, irt_rpt) == 24, "irt_rpt offset mismatch");
405414

406415
// key descriptor
407416

@@ -420,38 +429,65 @@ static_assert(offsetof(struct irtd, irtd_selectivity) == 4, "irtd_selectivity of
420429
// irt_flags, must match the idx_flags (see btr.h)
421430
inline constexpr USHORT irt_unique = 1;
422431
inline constexpr USHORT irt_descending = 2;
423-
inline constexpr USHORT irt_in_progress = 4;
424-
inline constexpr USHORT irt_foreign = 8;
425-
inline constexpr USHORT irt_primary = 16;
426-
inline constexpr USHORT irt_expression = 32;
427-
inline constexpr USHORT irt_condition = 64;
432+
inline constexpr USHORT irt_foreign = 4;
433+
inline constexpr USHORT irt_primary = 8;
434+
inline constexpr USHORT irt_expression = 16;
435+
inline constexpr USHORT irt_condition = 32;
436+
437+
// possible index states
438+
inline constexpr UCHAR irt_unused = 0; // empty slot
439+
inline constexpr UCHAR irt_in_progress = 1; // under construction - sort & merge
440+
inline constexpr UCHAR irt_rollback = 2; // index to be removed when irt_transaction dead (rolled back)
441+
inline constexpr UCHAR irt_normal = 3; // normal working state of index
442+
inline constexpr UCHAR irt_kill = 4; // index to be removed when irt_transaction ended (both commit/rollback)
443+
inline constexpr UCHAR irt_commit = 5; // start index removal (switch to irt_drop) when irt_transaction committed
444+
inline constexpr UCHAR irt_drop = 6; // index to be removed when OAT > irt_transaction
428445

429-
inline ULONG index_root_page::irt_repeat::getRoot() const
446+
inline bool index_root_page::irt_repeat::isUsed() const
430447
{
431-
return (irt_flags & irt_in_progress) ? 0 : irt_root;
448+
return (irt_state != irt_unused);
432449
}
433450

434-
inline void index_root_page::irt_repeat::setRoot(ULONG root_page)
451+
inline void index_root_page::irt_repeat::setEmpty()
435452
{
436-
irt_root = root_page;
437-
irt_flags &= ~irt_in_progress;
453+
irt_transaction = 0;
454+
irt_page_num = 0;
455+
irt_page_space_id = 0;
456+
irt_flags = 0;
457+
irt_state = irt_unused;
438458
}
439459

440-
inline TraNumber index_root_page::irt_repeat::getTransaction() const
460+
inline TraNumber index_root_page::irt_repeat::inProgress() const
441461
{
442-
return (irt_flags & irt_in_progress) ? ((TraNumber) irt_root << BITS_PER_LONG) | irt_transaction : 0;
462+
return irt_transaction;
443463
}
444464

445-
inline void index_root_page::irt_repeat::setTransaction(TraNumber traNumber)
465+
inline void index_root_page::irt_repeat::setInProgress(TraNumber traNumber)
446466
{
447-
irt_root = ULONG(traNumber >> BITS_PER_LONG);
448-
irt_transaction = ULONG(traNumber);
449-
irt_flags |= irt_in_progress;
467+
fb_assert(irt_state == irt_unused);
468+
fb_assert(!irt_page_num && !irt_page_space_id);
469+
470+
irt_transaction = traNumber;
471+
irt_page_num = 0;
472+
irt_page_space_id = 0;
473+
irt_state = irt_in_progress;
450474
}
451475

452-
inline bool index_root_page::irt_repeat::isUsed() const
476+
inline ULONG index_root_page::irt_repeat::getRoot() const
477+
{
478+
return (irt_state == irt_unused) ? 0 : irt_page_num;
479+
}
480+
481+
inline void index_root_page::irt_repeat::setRoot(ULONG rootPage)
453482
{
454-
return (irt_flags & irt_in_progress) || (irt_root != 0);
483+
fb_assert(irt_state == irt_in_progress);
484+
fb_assert(!irt_page_num && !irt_page_space_id);
485+
fb_assert(rootPage);
486+
487+
irt_transaction = 0;
488+
irt_page_num = rootPage;
489+
irt_page_space_id = 0;
490+
irt_state = irt_normal;
455491
}
456492

457493

src/jrd/validation.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1955,7 +1955,7 @@ void Validation::walk_generators()
19551955
}
19561956
}
19571957

1958-
Validation::RTN Validation::walk_index(jrd_rel* relation, index_root_page& root_page, USHORT id)
1958+
Validation::RTN Validation::walk_index(jrd_rel* relation, index_root_page* root_page, USHORT id)
19591959
{
19601960
/**************************************
19611961
*
@@ -1975,25 +1975,24 @@ Validation::RTN Validation::walk_index(jrd_rel* relation, index_root_page& root_
19751975
**************************************/
19761976
Database* dbb = vdr_tdbb->getDatabase();
19771977

1978-
const ULONG page_number = root_page.irt_rpt[id].getRoot();
1979-
if (!page_number) {
1978+
const ULONG page_number = root_page->irt_rpt[id].getRoot();
1979+
if (!page_number)
19801980
return rtn_ok;
1981-
}
19821981

1983-
const bool unique = (root_page.irt_rpt[id].irt_flags & (irt_unique | idx_primary));
1984-
const bool descending = (root_page.irt_rpt[id].irt_flags & irt_descending);
1985-
const bool condition = (root_page.irt_rpt[id].irt_flags & irt_condition);
1982+
const bool unique = (root_page->irt_rpt[id].irt_flags & (irt_unique | idx_primary));
1983+
const bool descending = (root_page->irt_rpt[id].irt_flags & irt_descending);
1984+
const bool condition = (root_page->irt_rpt[id].irt_flags & irt_condition);
19861985

1987-
temporary_key nullKey, *null_key = 0;
1986+
temporary_key nullKey, *null_key = nullptr;
19881987
if (unique)
19891988
{
19901989
index_desc idx;
19911990
{
19921991
// No need to evaluate index expression and/or condition
1993-
AutoSetRestoreFlag<UCHAR> flags(&root_page.irt_rpt[id].irt_flags,
1992+
AutoSetRestoreFlag<USHORT> flags(&root_page->irt_rpt[id].irt_flags,
19941993
irt_expression | irt_condition, false);
19951994

1996-
BTR_description(vdr_tdbb, relation, &root_page, &idx, id);
1995+
BTR_description(vdr_tdbb, relation, root_page, &idx, id);
19971996
}
19981997

19991998
null_key = &nullKey;
@@ -3209,13 +3208,13 @@ Validation::RTN Validation::walk_root(jrd_rel* relation, bool getInfo)
32093208
if (!relPages->rel_index_root)
32103209
return corrupt(VAL_INDEX_ROOT_MISSING, relation);
32113210

3212-
index_root_page* page = 0;
3211+
index_root_page* page = nullptr;
32133212
WIN window(DB_PAGE_SPACE, -1);
32143213
fetch_page(!getInfo, relPages->rel_index_root, pag_root, &window, &page);
32153214

32163215
for (USHORT i = 0; i < page->irt_count; i++)
32173216
{
3218-
if (page->irt_rpt[i].getRoot() == 0)
3217+
if (!page->irt_rpt[i].getRoot())
32193218
continue;
32203219

32213220
MetaName index;
@@ -3241,7 +3240,7 @@ Validation::RTN Validation::walk_root(jrd_rel* relation, bool getInfo)
32413240
if (page->irt_rpt[i].irt_flags & irt_condition)
32423241
{
32433242
// No need to evaluate index expression
3244-
AutoSetRestoreFlag<UCHAR> flag(&page->irt_rpt[i].irt_flags, irt_expression, false);
3243+
AutoSetRestoreFlag<USHORT> flag(&page->irt_rpt[i].irt_flags, irt_expression, false);
32453244

32463245
IdxInfo info;
32473246
if (BTR_description(vdr_tdbb, relation, page, &info.m_desc, i))
@@ -3251,7 +3250,7 @@ Validation::RTN Validation::walk_root(jrd_rel* relation, bool getInfo)
32513250
}
32523251

32533252
output("Index %d (%s)\n", i + 1, index.c_str());
3254-
walk_index(relation, *page, i);
3253+
walk_index(relation, page, i);
32553254
}
32563255

32573256
release_page(&window);

src/jrd/validation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ class Validation
213213
RTN walk_data_page(jrd_rel*, ULONG, ULONG, UCHAR&);
214214
void walk_database();
215215
void walk_generators();
216-
RTN walk_index(jrd_rel*, Ods::index_root_page&, USHORT);
216+
RTN walk_index(jrd_rel*, Ods::index_root_page*, USHORT);
217217
void walk_pip();
218218
RTN walk_pointer_page(jrd_rel*, ULONG);
219219
RTN walk_record(jrd_rel*, const Ods::rhd*, USHORT, RecordNumber, bool);

0 commit comments

Comments
 (0)