Skip to content

Commit 2a00a58

Browse files
committed
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.
1 parent e218777 commit 2a00a58

File tree

8 files changed

+93
-91
lines changed

8 files changed

+93
-91
lines changed

src/jrd/btr.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -924,12 +924,11 @@ 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 PageNumber next(window->win_page.getPageSpaceID(), irt_desc->irt_root);
928+
tree_exists = !irt_desc->isEmpty();
929929

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

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

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

965-
if (irt_desc->getRoot() == 0)
964+
if (irt_desc->isEmpty())
966965
return false;
967966

968967
idx->idx_id = id;
969-
idx->idx_root = irt_desc->getRoot();
968+
idx->idx_root = irt_desc->irt_root;
970969
idx->idx_count = irt_desc->irt_keys;
971970
idx->idx_flags = irt_desc->irt_flags;
972971
idx->idx_runtime_flags = 0;
@@ -1451,7 +1450,7 @@ void BTR_insert(thread_db* tdbb, WIN* root_window, index_insertion* insertion)
14511450
// update the index root page. Oh boy.
14521451
index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, root_window, LCK_write, pag_root);
14531452

1454-
window.win_page = root->irt_rpt[idx->idx_id].getRoot();
1453+
window.win_page = root->irt_rpt[idx->idx_id].irt_root;
14551454
bucket = (btree_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_index);
14561455

14571456
if (window.win_page.getPageNum() != idx->idx_root)
@@ -1501,7 +1500,7 @@ void BTR_insert(thread_db* tdbb, WIN* root_window, index_insertion* insertion)
15011500
BUGCHECK(204); // msg 204 index inconsistent
15021501
}
15031502

1504-
window.win_page = root->irt_rpt[idx->idx_id].getRoot();
1503+
window.win_page = root->irt_rpt[idx->idx_id].irt_root;
15051504
bucket = (btree_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_index);
15061505
key.key_length = ret_key.key_length;
15071506
memcpy(key.key_data, ret_key.key_data, ret_key.key_length);
@@ -2124,18 +2123,18 @@ bool BTR_next_index(thread_db* tdbb, jrd_rel* relation, jrd_tra* transaction, in
21242123
for (; id < root->irt_count; ++id)
21252124
{
21262125
const index_root_page::irt_repeat* irt_desc = root->irt_rpt + id;
2127-
if (irt_desc->getTransaction() && transaction)
2126+
const TraNumber inProgressTrans = irt_desc->inProgress();
2127+
if (inProgressTrans && transaction)
21282128
{
2129-
const TraNumber trans = irt_desc->getTransaction();
21302129
CCH_RELEASE(tdbb, window);
2131-
const int trans_state = TRA_wait(tdbb, transaction, trans, jrd_tra::tra_wait);
2130+
const int trans_state = TRA_wait(tdbb, transaction, inProgressTrans, jrd_tra::tra_wait);
21322131
if ((trans_state == tra_dead) || (trans_state == tra_committed))
21332132
{
21342133
// clean up this left-over index
21352134
root = (index_root_page*) CCH_FETCH(tdbb, window, LCK_write, pag_root);
21362135
irt_desc = root->irt_rpt + id;
21372136

2138-
if (irt_desc->getTransaction() == trans)
2137+
if (irt_desc->inProgress() == inProgressTrans)
21392138
BTR_delete_index(tdbb, window, id);
21402139
else
21412140
CCH_RELEASE(tdbb, window);
@@ -2359,7 +2358,7 @@ void BTR_reserve_slot(thread_db* tdbb, IndexCreation& creation)
23592358
fb_assert(idx->idx_count <= MAX_UCHAR);
23602359
slot->irt_keys = (UCHAR) idx->idx_count;
23612360
slot->irt_flags = idx->idx_flags;
2362-
slot->setTransaction(transaction->tra_number);
2361+
slot->setInProgress(transaction->tra_number);
23632362

23642363
// Exploit the fact idx_repeat structure matches ODS IRTD one
23652364
memcpy(desc, idx->idx_rpt, len);
@@ -2393,13 +2392,15 @@ void BTR_selectivity(thread_db* tdbb, jrd_rel* relation, USHORT id, SelectivityL
23932392
if (!root)
23942393
return;
23952394

2396-
ULONG page;
2397-
if (id >= root->irt_count || !(page = root->irt_rpt[id].getRoot()))
2395+
if (id >= root->irt_count || root->irt_rpt[id].isEmpty())
23982396
{
23992397
CCH_RELEASE(tdbb, &window);
24002398
return;
24012399
}
24022400

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

@@ -3334,7 +3335,7 @@ static USHORT compress_root(thread_db* tdbb, index_root_page* page)
33343335
for (const index_root_page::irt_repeat* const end = root_idx + page->irt_count;
33353336
root_idx < end; root_idx++)
33363337
{
3337-
if (root_idx->getRoot())
3338+
if (!root_idx->isEmpty())
33383339
{
33393340
const USHORT len = root_idx->irt_keys * sizeof(irtd);
33403341
p -= len;

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: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -368,39 +368,39 @@ struct index_root_page
368368
USHORT irt_count; // Number of indices
369369
struct irt_repeat
370370
{
371-
private:
372-
friend struct index_root_page; // to allow offset check for private members
373-
ULONG irt_root; // page number of index root if irt_in_progress is NOT set, or
374-
// highest 32 bit of transaction if irt_in_progress is set
375-
ULONG irt_transaction; // transaction in progress (lowest 32 bits)
376-
public:
377-
USHORT irt_desc; // offset to key descriptions
378-
UCHAR irt_keys; // number of keys in index
379-
UCHAR irt_flags;
380-
381-
ULONG getRoot() const;
382-
void setRoot(ULONG root_page);
383-
384-
TraNumber getTransaction() const;
385-
void setTransaction(TraNumber traNumber);
386-
371+
union
372+
{
373+
FB_UINT64 irt_transaction; // transaction in progress
374+
ULONG irt_root; // page number of index root
375+
};
376+
USHORT irt_desc; // offset to key descriptions
377+
USHORT irt_flags; // index flags
378+
UCHAR irt_keys; // number of keys in index
379+
380+
TraNumber inProgress() const;
381+
bool isEmpty() const;
387382
bool isUsed() const;
388383

384+
void setEmpty();
385+
void setInProgress(TraNumber traNumber);
386+
void clearInProgress(ULONG rootPage);
387+
void setRoot(ULONG rootPage);
388+
389389
} irt_rpt[1];
390390

391-
static_assert(sizeof(struct irt_repeat) == 12, "struct irt_repeat size mismatch");
391+
static_assert(sizeof(struct irt_repeat) == 16, "struct irt_repeat size mismatch");
392+
static_assert(offsetof(struct irt_repeat, irt_transaction) == 0, "irt_transaction offset mismatch");
392393
static_assert(offsetof(struct irt_repeat, irt_root) == 0, "irt_root offset mismatch");
393-
static_assert(offsetof(struct irt_repeat, irt_transaction) == 4, "irt_transaction offset mismatch");
394394
static_assert(offsetof(struct irt_repeat, irt_desc) == 8, "irt_desc offset mismatch");
395-
static_assert(offsetof(struct irt_repeat, irt_keys) == 10, "irt_keys offset mismatch");
396-
static_assert(offsetof(struct irt_repeat, irt_flags) == 11, "irt_flags offset mismatch");
395+
static_assert(offsetof(struct irt_repeat, irt_flags) == 10, "irt_flags offset mismatch");
396+
static_assert(offsetof(struct irt_repeat, irt_keys) == 12, "irt_keys offset mismatch");
397397
};
398398

399-
static_assert(sizeof(struct index_root_page) == 32, "struct index_root_page size mismatch");
399+
static_assert(sizeof(struct index_root_page) == 40, "struct index_root_page size mismatch");
400400
static_assert(offsetof(struct index_root_page, irt_header) == 0, "irt_header offset mismatch");
401401
static_assert(offsetof(struct index_root_page, irt_relation) == 16, "irt_relation offset mismatch");
402402
static_assert(offsetof(struct index_root_page, irt_count) == 18, "irt_count offset mismatch");
403-
static_assert(offsetof(struct index_root_page, irt_rpt) == 20, "irt_rpt offset mismatch");
403+
static_assert(offsetof(struct index_root_page, irt_rpt) == 24, "irt_rpt offset mismatch");
404404

405405
// key descriptor
406406

@@ -425,32 +425,37 @@ inline constexpr USHORT irt_primary = 16;
425425
inline constexpr USHORT irt_expression = 32;
426426
inline constexpr USHORT irt_condition = 64;
427427

428-
inline ULONG index_root_page::irt_repeat::getRoot() const
428+
inline TraNumber index_root_page::irt_repeat::inProgress() const
429429
{
430-
return (irt_flags & irt_in_progress) ? 0 : irt_root;
430+
return (irt_flags & irt_in_progress) ? irt_transaction : 0;
431431
}
432432

433-
inline void index_root_page::irt_repeat::setRoot(ULONG root_page)
433+
inline bool index_root_page::irt_repeat::isEmpty() const
434434
{
435-
irt_root = root_page;
436-
irt_flags &= ~irt_in_progress;
435+
return (irt_flags & irt_in_progress) || (irt_root == 0);
437436
}
438437

439-
inline TraNumber index_root_page::irt_repeat::getTransaction() const
438+
inline bool index_root_page::irt_repeat::isUsed() const
440439
{
441-
return (irt_flags & irt_in_progress) ? ((TraNumber) irt_root << BITS_PER_LONG) | irt_transaction : 0;
440+
return (irt_flags & irt_in_progress) || (irt_root != 0);
442441
}
443442

444-
inline void index_root_page::irt_repeat::setTransaction(TraNumber traNumber)
443+
inline void index_root_page::irt_repeat::setEmpty()
445444
{
446-
irt_root = ULONG(traNumber >> BITS_PER_LONG);
447-
irt_transaction = ULONG(traNumber);
445+
irt_transaction = 0;
446+
irt_flags = 0;
447+
}
448+
449+
inline void index_root_page::irt_repeat::setInProgress(TraNumber traNumber)
450+
{
451+
irt_transaction = traNumber;
448452
irt_flags |= irt_in_progress;
449453
}
450454

451-
inline bool index_root_page::irt_repeat::isUsed() const
455+
inline void index_root_page::irt_repeat::setRoot(ULONG rootPage)
452456
{
453-
return (irt_flags & irt_in_progress) || (irt_root != 0);
457+
irt_root = rootPage;
458+
irt_flags &= ~irt_in_progress;
454459
}
455460

456461

src/jrd/validation.cpp

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

1959-
Validation::RTN Validation::walk_index(jrd_rel* relation, index_root_page& root_page, USHORT id)
1959+
Validation::RTN Validation::walk_index(jrd_rel* relation, index_root_page* root_page, USHORT id)
19601960
{
19611961
/**************************************
19621962
*
@@ -1976,25 +1976,26 @@ Validation::RTN Validation::walk_index(jrd_rel* relation, index_root_page& root_
19761976
**************************************/
19771977
Database* dbb = vdr_tdbb->getDatabase();
19781978

1979-
const ULONG page_number = root_page.irt_rpt[id].getRoot();
1980-
if (!page_number) {
1979+
if (root_page->irt_rpt[id].isEmpty())
19811980
return rtn_ok;
1982-
}
19831981

1984-
const bool unique = (root_page.irt_rpt[id].irt_flags & (irt_unique | idx_primary));
1985-
const bool descending = (root_page.irt_rpt[id].irt_flags & irt_descending);
1986-
const bool condition = (root_page.irt_rpt[id].irt_flags & irt_condition);
1982+
const ULONG page_number = root_page->irt_rpt[id].irt_root;
1983+
fb_assert(page_number);
1984+
1985+
const bool unique = (root_page->irt_rpt[id].irt_flags & (irt_unique | idx_primary));
1986+
const bool descending = (root_page->irt_rpt[id].irt_flags & irt_descending);
1987+
const bool condition = (root_page->irt_rpt[id].irt_flags & irt_condition);
19871988

1988-
temporary_key nullKey, *null_key = 0;
1989+
temporary_key nullKey, *null_key = nullptr;
19891990
if (unique)
19901991
{
19911992
index_desc idx;
19921993
{
19931994
// No need to evaluate index expression and/or condition
1994-
AutoSetRestoreFlag<UCHAR> flags(&root_page.irt_rpt[id].irt_flags,
1995+
AutoSetRestoreFlag<USHORT> flags(&root_page->irt_rpt[id].irt_flags,
19951996
irt_expression | irt_condition, false);
19961997

1997-
BTR_description(vdr_tdbb, relation, &root_page, &idx, id);
1998+
BTR_description(vdr_tdbb, relation, root_page, &idx, id);
19981999
}
19992000

20002001
null_key = &nullKey;
@@ -3216,7 +3217,7 @@ Validation::RTN Validation::walk_root(jrd_rel* relation, bool getInfo)
32163217

32173218
for (USHORT i = 0; i < page->irt_count; i++)
32183219
{
3219-
if (page->irt_rpt[i].getRoot() == 0)
3220+
if (page->irt_rpt[i].isEmpty())
32203221
continue;
32213222

32223223
MetaName index;
@@ -3242,7 +3243,7 @@ Validation::RTN Validation::walk_root(jrd_rel* relation, bool getInfo)
32423243
if (page->irt_rpt[i].irt_flags & irt_condition)
32433244
{
32443245
// No need to evaluate index expression
3245-
AutoSetRestoreFlag<UCHAR> flag(&page->irt_rpt[i].irt_flags, irt_expression, false);
3246+
AutoSetRestoreFlag<USHORT> flag(&page->irt_rpt[i].irt_flags, irt_expression, false);
32463247

32473248
IdxInfo info;
32483249
if (BTR_description(vdr_tdbb, relation, page, &info.m_desc, i))
@@ -3252,7 +3253,7 @@ Validation::RTN Validation::walk_root(jrd_rel* relation, bool getInfo)
32523253
}
32533254

32543255
output("Index %d (%s)\n", i + 1, index.c_str());
3255-
walk_index(relation, *page, i);
3256+
walk_index(relation, page, i);
32563257
}
32573258

32583259
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)