Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize creation of expression and partial indices #7559

Merged
merged 5 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
716 changes: 350 additions & 366 deletions src/jrd/btr.cpp

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions src/jrd/btr.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,108 @@ class IndexErrorContext
bool isLocationDefined;
};

// Helper classes to allow efficient evaluation of index conditions/expressions

class IndexCondition
{
public:
IndexCondition(thread_db* tdbb, index_desc* idx);
~IndexCondition();

bool evaluate(Record* record) const;

private:
thread_db* const m_tdbb;
BoolExprNode* m_condition = nullptr;
Request* m_request = nullptr;
};

class IndexExpression
{
public:
IndexExpression(thread_db* tdbb, index_desc* idx);
~IndexExpression();

dsc* evaluate(Record* record) const;

private:
thread_db* const m_tdbb;
ValueExprNode* m_expression = nullptr;
Request* m_request = nullptr;
};

// Index key wrapper

class IndexKey
{
public:
IndexKey(thread_db* tdbb, jrd_rel* relation, index_desc* idx)
: m_tdbb(tdbb), m_relation(relation), m_index(idx),
m_keyType((idx->idx_flags & idx_unique) ? INTL_KEY_UNIQUE : INTL_KEY_SORT),
m_segments(idx->idx_count), m_expression(tdbb, idx)
{}

IndexKey(thread_db* tdbb, jrd_rel* relation, index_desc* idx,
USHORT keyType, USHORT segments)
: m_tdbb(tdbb), m_relation(relation), m_index(idx),
m_keyType(keyType), m_segments(segments), m_expression(tdbb, idx)
{
fb_assert(m_segments && m_segments <= idx->idx_count);
}

idx_e compose(Record* record);

operator temporary_key*()
{
return &m_key;
}

temporary_key* operator->()
{
return &m_key;
}

bool operator==(const IndexKey& other) const
{
if (m_key.key_length != other.m_key.key_length)
return false;

return !memcmp(m_key.key_data, other.m_key.key_data, m_key.key_length);
}

bool operator!=(const IndexKey& other) const
{
if (m_key.key_length != other.m_key.key_length)
return true;

return memcmp(m_key.key_data, other.m_key.key_data, m_key.key_length);
}

// Return ordinal number of the first NULL segment
USHORT getNullSegment() const
{
USHORT nulls = m_key.key_nulls;

for (USHORT i = 0; nulls; i++)
{
if (nulls & 1)
return i;

nulls >>= 1;
}

return MAX_USHORT;
}

private:
thread_db* const m_tdbb;
jrd_rel* const m_relation;
index_desc* const m_index;
const USHORT m_keyType;
const USHORT m_segments;
temporary_key m_key;
IndexExpression m_expression;
};

} //namespace Jrd

Expand Down
4 changes: 1 addition & 3 deletions src/jrd/btr_proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,12 @@ void BTR_create(Jrd::thread_db*, Jrd::IndexCreation&, Jrd::SelectivityList&);
bool BTR_delete_index(Jrd::thread_db*, Jrd::win*, USHORT);
bool BTR_description(Jrd::thread_db*, Jrd::jrd_rel*, Ods::index_root_page*, Jrd::index_desc*, USHORT);
bool BTR_check_condition(Jrd::thread_db*, Jrd::index_desc*, Jrd::Record*);
DSC* BTR_eval_expression(Jrd::thread_db*, Jrd::index_desc*, Jrd::Record*, bool&);
dsc* BTR_eval_expression(Jrd::thread_db*, Jrd::index_desc*, Jrd::Record*);
void BTR_evaluate(Jrd::thread_db*, const Jrd::IndexRetrieval*, Jrd::RecordBitmap**, Jrd::RecordBitmap*);
UCHAR* BTR_find_leaf(Ods::btree_page*, Jrd::temporary_key*, UCHAR*, USHORT*, bool, int);
Ods::btree_page* BTR_find_page(Jrd::thread_db*, const Jrd::IndexRetrieval*, Jrd::win*, Jrd::index_desc*,
Jrd::temporary_key*, Jrd::temporary_key*, bool = true);
void BTR_insert(Jrd::thread_db*, Jrd::win*, Jrd::index_insertion*);
Jrd::idx_e BTR_key(Jrd::thread_db*, Jrd::jrd_rel*, Jrd::Record*, Jrd::index_desc*, Jrd::temporary_key*,
const USHORT, USHORT = 0);
USHORT BTR_key_length(Jrd::thread_db*, Jrd::jrd_rel*, Jrd::index_desc*);
Ods::btree_page* BTR_left_handoff(Jrd::thread_db*, Jrd::win*, Ods::btree_page*, SSHORT);
bool BTR_lookup(Jrd::thread_db*, Jrd::jrd_rel*, USHORT, Jrd::index_desc*, Jrd::RelationPages*);
Expand Down
Loading