Skip to content

BTreeIndex Iterator Remove single run optimization #995

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

Merged
merged 5 commits into from
Jan 17, 2024
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
10 changes: 7 additions & 3 deletions ydb/core/tablet_flat/benchmark/b_part_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ namespace {
UNIT_ASSERT_GE(part->Stat.Bytes, 100ull*1024*1024);
UNIT_ASSERT_LE(part->Stat.Bytes, 100ull*1024*1024 + 10ull*1024*1024);

UNIT_ASSERT_VALUES_EQUAL(part->Slices->size(), 1);

GroupId = TGroupId(groups ? 1 : 0);
}

Expand Down Expand Up @@ -192,18 +194,19 @@ BENCHMARK_DEFINE_F(TPartIndexSeekFixture, SeekKey)(benchmark::State& state) {

BENCHMARK_DEFINE_F(TPartIndexIteratorFixture, DoReads)(benchmark::State& state) {
const bool reverse = state.range(3);
const ui32 items = state.range(4);
const ESeek seek = static_cast<ESeek>(state.range(4));
const ui32 items = state.range(5);

for (auto _ : state) {
auto it = Mass->Saved.Any(Rnd);

if (reverse) {
CheckerReverse->Seek(*it, ESeek::Lower);
CheckerReverse->Seek(*it, seek);
for (ui32 i = 1; CheckerReverse->GetReady() == EReady::Data && i < items; i++) {
CheckerReverse->Next();
}
} else {
Checker->Seek(*it, ESeek::Lower);
Checker->Seek(*it, seek);
for (ui32 i = 1; Checker->GetReady() == EReady::Data && i < items; i++) {
Checker->Next();
}
Expand Down Expand Up @@ -242,6 +245,7 @@ BENCHMARK_REGISTER_F(TPartIndexIteratorFixture, DoReads)
/* groups: */ {0, 1},
/* history: */ {0, 1},
/* reverse: */ {0, 1},
/* ESeek: */ {1, 2, 3},
/* items */ {1, 10, 100}})
->Unit(benchmark::kMicrosecond);

Expand Down
76 changes: 28 additions & 48 deletions ydb/core/tablet_flat/flat_part_iter_multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,12 +297,12 @@ namespace NTable {
return EReady::Data;
}

EReady SeekToStart() noexcept
EReady SeekToSliceFirstRow() noexcept
{
return Seek(BeginRowId);
}

EReady SeekToEnd() noexcept
EReady SeekToSliceLastRow() noexcept
{
return Seek(EndRowId - 1);
}
Expand Down Expand Up @@ -828,16 +828,16 @@ namespace NTable {
return Main.Seek(rowId);
}

EReady SeekToStart() noexcept
EReady SeekToSliceFirstRow() noexcept
{
ClearKey();
return Main.SeekToStart();
return Main.SeekToSliceFirstRow();
}

EReady SeekToEnd() noexcept
EReady SeekToSliceLastRow() noexcept
{
ClearKey();
return Main.SeekToEnd();
return Main.SeekToSliceLastRow();
}

EReady Next() noexcept
Expand Down Expand Up @@ -1387,18 +1387,7 @@ namespace NTable {

EReady Seek(const TCells key, ESeek seek) noexcept
{
if (Run.size() == 1) {
// Avoid overhead of extra key comparisons in a single slice
Current = Run.begin();

if (!CurrentIt) {
InitCurrent();
}

return CurrentIt->Seek(key, seek);
}

bool seekToStart = false;
bool seekToSliceFirstRow = false;
TRun::const_iterator pos;

switch (seek) {
Expand All @@ -1409,16 +1398,16 @@ namespace NTable {
case ESeek::Lower:
if (!key) {
pos = Run.begin();
seekToStart = true;
seekToSliceFirstRow = true;
break;
}

pos = Run.LowerBound(key);
if (pos != Run.end() &&
TSlice::CompareSearchKeyFirstKey(key, pos->Slice, *KeyCellDefaults) <= 0)
{
// Key is at the start of the slice
seekToStart = true;
// key <= FirstKey
seekToSliceFirstRow = true;
}
break;

Expand All @@ -1432,8 +1421,8 @@ namespace NTable {
if (pos != Run.end() &&
TSlice::CompareSearchKeyFirstKey(key, pos->Slice, *KeyCellDefaults) < 0)
{
// Key is at the start of the slice
seekToStart = true;
// key < FirstKey
seekToSliceFirstRow = true;
}
break;

Expand All @@ -1452,7 +1441,7 @@ namespace NTable {
UpdateCurrent();
}

if (!seekToStart) {
if (!seekToSliceFirstRow) {
auto ready = CurrentIt->Seek(key, seek);
if (ready != EReady::Gone) {
return ready;
Expand All @@ -1472,23 +1461,12 @@ namespace NTable {
UpdateCurrent();
}

return SeekToStart();
return SeekToSliceFirstRow();
}

EReady SeekReverse(const TCells key, ESeek seek) noexcept
{
if (Run.size() == 1) {
// Avoid overhead of extra key comparisons in a single slice
Current = Run.begin();

if (!CurrentIt) {
InitCurrent();
}

return CurrentIt->SeekReverse(key, seek);
}

bool seekToEnd = false;
bool seekToSliceLastRow = false;
TRun::const_iterator pos;

switch (seek) {
Expand All @@ -1498,7 +1476,7 @@ namespace NTable {

case ESeek::Lower:
if (!key) {
seekToEnd = true;
seekToSliceLastRow = true;
pos = Run.end();
--pos;
break;
Expand All @@ -1508,7 +1486,8 @@ namespace NTable {
if (pos != Run.end() &&
TSlice::CompareLastKeySearchKey(pos->Slice, key, *KeyCellDefaults) <= 0)
{
seekToEnd = true;
// LastKey <= key
seekToSliceLastRow = true;
}
break;

Expand All @@ -1522,7 +1501,8 @@ namespace NTable {
if (pos != Run.end() &&
TSlice::CompareLastKeySearchKey(pos->Slice, key, *KeyCellDefaults) < 0)
{
seekToEnd = true;
// LastKey < key
seekToSliceLastRow = true;
}
break;

Expand All @@ -1541,7 +1521,7 @@ namespace NTable {
UpdateCurrent();
}

if (!seekToEnd) {
if (!seekToSliceLastRow) {
auto ready = CurrentIt->SeekReverse(key, seek);
if (ready != EReady::Gone) {
return ready;
Expand All @@ -1563,7 +1543,7 @@ namespace NTable {
UpdateCurrent();
}

return SeekToEnd();
return SeekToSliceLastRow();
}

EReady Next() noexcept
Expand All @@ -1586,7 +1566,7 @@ namespace NTable {

UpdateCurrent();

ready = SeekToStart();
ready = SeekToSliceFirstRow();
if (ready == EReady::Page) {
// we haven't sought start, will do it again later
Current--;
Expand Down Expand Up @@ -1618,7 +1598,7 @@ namespace NTable {
--Current;
UpdateCurrent();

ready = SeekToEnd();
ready = SeekToSliceLastRow();
if (ready == EReady::Page) {
// we haven't sought end, will do it again later
Current++;
Expand Down Expand Up @@ -1747,17 +1727,17 @@ namespace NTable {
InitCurrent();
}

Y_FORCE_INLINE EReady SeekToStart() noexcept
Y_FORCE_INLINE EReady SeekToSliceFirstRow() noexcept
{
auto ready = CurrentIt->SeekToStart();
auto ready = CurrentIt->SeekToSliceFirstRow();
Y_ABORT_UNLESS(ready != EReady::Gone,
"Unexpected slice without the first row");
return ready;
}

Y_FORCE_INLINE EReady SeekToEnd() noexcept
Y_FORCE_INLINE EReady SeekToSliceLastRow() noexcept
{
auto ready = CurrentIt->SeekToEnd();
auto ready = CurrentIt->SeekToSliceLastRow();
Y_ABORT_UNLESS(ready != EReady::Gone,
"Unexpected slice without the last row");
return ready;
Expand Down
5 changes: 2 additions & 3 deletions ydb/core/tablet_flat/test/libs/table/test_part.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,15 @@ namespace NTest {
return index.GetLastRecord();
}

inline const TPartIndexIt::TRecord * GetRecord(const TPartStore& part, TPageId pageId) {
inline const TPartIndexIt::TRecord * GetRecord(const TPartStore& part, TPageId pageIndex) {
Copy link
Member

@snaury snaury Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Очень минорное: немного странное переименование pageId -> pageIndex, ведь индекс это и есть page id.

Copy link
Member Author

@kunga kunga Jan 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pageIndex это типо номер с начала внутри TPart

например TPart из 10 страниц их индексы [0..9]

а pageId могут быть [0, 1, 5, 10, 15, ..

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В таком случае использовать TPageId в качестве типа очень странно.

TTestEnv env;
TPartIndexIt index(&part, &env, { });

Y_ABORT_UNLESS(index.Seek(0) == EReady::Data);
for (TPageId p = 0; p < pageId; p++) {
for (TPageId p = 0; p < pageIndex; p++) {
Y_ABORT_UNLESS(index.Next() == EReady::Data);
}

Y_ABORT_UNLESS(index.GetPageId() == pageId);
return index.GetRecord();
}
}
Expand Down
Loading