Skip to content

Commit

Permalink
KIKIMR-19521 BTreeIndex Loader & Dump
Browse files Browse the repository at this point in the history
  • Loading branch information
kunga committed Dec 14, 2023
1 parent 33afeca commit 897ada7
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 31 deletions.
8 changes: 8 additions & 0 deletions ydb/core/tablet_flat/flat_part_btree_index_iter.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ class TPartBtreeIndexIt : public IIndexIter {
return DoSeek<TSeekRowId>({rowId});
}

EReady SeekLast() override {
if (Y_UNLIKELY(GetEndRowId() == 0)) {
Y_DEBUG_ABORT_UNLESS(false, "TPart can't be empty");
return Exhaust();
}
return Seek(GetEndRowId() - 1);
}

/**
* Searches for the first page that may contain given key with specified seek mode
*
Expand Down
8 changes: 4 additions & 4 deletions ydb/core/tablet_flat/flat_part_dump.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "flat_part_dump.h"
#include "flat_part_iface.h"
#include "flat_part_index_iter.h"
#include "flat_part_index_iter_iface.h"
#include "flat_page_data.h"
#include "flat_page_frames.h"
#include "flat_page_blobs.h"
Expand Down Expand Up @@ -52,10 +52,10 @@ namespace {
BTreeIndex(part);

if (depth > 2) {
auto index = TPartIndexIt(&part, Env, { });
auto index = CreateIndexIter(&part, Env, { });

for (ssize_t i = 0; ; i++) {
auto ready = i == 0 ? index.Seek(0) : index.Next();
auto ready = i == 0 ? index->Seek(0) : index->Next();
if (ready != EReady::Data) {
if (ready == EReady::Page) {
Out << " | -- the rest of the index rows aren't loaded" << Endl;
Expand All @@ -65,7 +65,7 @@ namespace {

Out << Endl;

DataPage(part, index.GetPageId());
DataPage(part, index->GetPageId());
}
}
}
Expand Down
22 changes: 11 additions & 11 deletions ydb/core/tablet_flat/flat_part_index_iter.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,36 +36,36 @@ class TPartIndexIt : public IIndexIter {
return DataOrGone();
}

EReady Seek(ESeek seek, TCells key, const TKeyCellDefaults *keyDefaults) override {
EReady SeekLast() override {
auto index = TryGetIndex();
if (!index) {
return EReady::Page;
}

Iter = index->LookupKey(key, GroupInfo, seek, keyDefaults);
Iter = (*index)->End();
if (Iter.Off() == 0) {
return EReady::Gone;
}
Iter--;
return DataOrGone();
}

EReady SeekReverse(ESeek seek, TCells key, const TKeyCellDefaults *keyDefaults) override {
EReady Seek(ESeek seek, TCells key, const TKeyCellDefaults *keyDefaults) override {
auto index = TryGetIndex();
if (!index) {
return EReady::Page;
}

Iter = index->LookupKeyReverse(key, GroupInfo, seek, keyDefaults);
Iter = index->LookupKey(key, GroupInfo, seek, keyDefaults);
return DataOrGone();
}

EReady SeekLast() {
EReady SeekReverse(ESeek seek, TCells key, const TKeyCellDefaults *keyDefaults) override {
auto index = TryGetIndex();
if (!index) {
return EReady::Page;
}
Iter = (*index)->End();
if (Iter.Off() == 0) {
return EReady::Gone;
}
Iter--;

Iter = index->LookupKeyReverse(key, GroupInfo, seek, keyDefaults);
return DataOrGone();
}

Expand Down
1 change: 1 addition & 0 deletions ydb/core/tablet_flat/flat_part_index_iter_iface.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace NKikimr::NTable {
using TCells = NPage::TCells;

virtual EReady Seek(TRowId rowId) = 0;
virtual EReady SeekLast() = 0;
virtual EReady Seek(ESeek seek, TCells key, const TKeyCellDefaults *keyDefaults) = 0;
virtual EReady SeekReverse(ESeek seek, TCells key, const TKeyCellDefaults *keyDefaults) = 0;
virtual EReady Next() = 0;
Expand Down
21 changes: 10 additions & 11 deletions ydb/core/tablet_flat/flat_part_keys.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
#pragma once
#include "flat_part_iface.h"
#include "flat_part_index_iter.h"
#include "flat_part_index_iter_iface.h"
#include "flat_part_slice.h"
#include "flat_sausage_fetch.h"
#include "flat_sausagecache.h"
#include "util_fmt_abort.h"

namespace NKikimr {
namespace NTable {
Expand Down Expand Up @@ -82,7 +81,7 @@ namespace NTable {
explicit TKeysLoader(const TPart* part, IPages* env)
: Part(part)
, Env(env)
, Index(Part, Env, {})
, Index(CreateIndexIter(part, env, {}))
{
}

Expand Down Expand Up @@ -151,7 +150,7 @@ namespace NTable {
return true;
}

auto ready = Index.Seek(rowId);
auto ready = Index->Seek(rowId);
if (ready == EReady::Page) {
return false;
} else if (ready == EReady::Gone) {
Expand All @@ -161,11 +160,11 @@ namespace NTable {
return true;
}

Y_ABORT_UNLESS(Index.GetRowId() <= rowId, "SeekIndex invariant failure");
if (!LoadPage(Index.GetPageId())) {
Y_ABORT_UNLESS(Index->GetRowId() <= rowId, "SeekIndex invariant failure");
if (!LoadPage(Index->GetPageId())) {
return false;
}
Y_ABORT_UNLESS(Page.BaseRow() == Index.GetRowId(), "Index and data are out of sync");
Y_ABORT_UNLESS(Page.BaseRow() == Index->GetRowId(), "Index and data are out of sync");
auto lastRowId = Page.BaseRow() + (Page->Count - 1);
if (lastRowId < rowId) {
// Row is out of range for this page
Expand All @@ -180,16 +179,16 @@ namespace NTable {

bool SeekLastRow() noexcept
{
auto hasLast = Index.SeekLast();
auto hasLast = Index->SeekLast();
if (hasLast == EReady::Page) {
return false;
}
Y_ABORT_UNLESS(hasLast != EReady::Gone, "Unexpected failure to find the last index record");

if (!LoadPage(Index.GetPageId())) {
if (!LoadPage(Index->GetPageId())) {
return false;
}
Y_ABORT_UNLESS(Page.BaseRow() == Index.GetRowId(), "Index and data are out of sync");
Y_ABORT_UNLESS(Page.BaseRow() == Index->GetRowId(), "Index and data are out of sync");
auto lastRowId = Page.BaseRow() + (Page->Count - 1);
LoadRow(lastRowId);
return true;
Expand Down Expand Up @@ -227,7 +226,7 @@ namespace NTable {
IPages* Env;
TRowId RowId = Max<TRowId>();
TPageId PageId = Max<TPageId>();
TPartIndexIt Index;
THolder<IIndexIter> Index;
NPage::TDataPage Page;
TSmallVec<TCell> Key;
};
Expand Down
22 changes: 22 additions & 0 deletions ydb/core/tablet_flat/ut/ut_btree_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,13 @@ Y_UNIT_TEST_SUITE(TPartBtreeIndexIt) {
}, message, failsAllowed);
}

template<typename TIter>
EReady SeekLast(TIter& iter, const TString& message, ui32 failsAllowed = 10) {
return Retry([&]() {
return iter.SeekLast();
}, message, failsAllowed);
}

template<typename TIter>
EReady SeekKey(TIter& iter, ESeek seek, bool reverse, TCells key, const TKeyCellDefaults *keyDefaults, const TString& message, ui32 failsAllowed = 10) {
return Retry([&]() {
Expand Down Expand Up @@ -966,6 +973,19 @@ Y_UNIT_TEST_SUITE(TPartBtreeIndexIt) {
}
}

template<typename TEnv>
void CheckSeekLast(const TPartStore& part) {
TEnv env;
TPartBtreeIndexIt bTree(&part, &env, { });
TPartIndexIt flat(&part, &env, { });

TString message = TStringBuilder() << "SeekLast<" << typeid(TEnv).name() << ">";
EReady bTreeReady = SeekLast(bTree, message);
EReady flatReady = SeekLast(flat, message);
UNIT_ASSERT_VALUES_EQUAL(bTreeReady, EReady::Data);
AssertEqual(bTree, bTreeReady, flat, flatReady, message);
}

template<typename TEnv>
void CheckSeekKey(const TPartStore& part, const TKeyCellDefaults *keyDefaults) {
for (bool reverse : {false, true}) {
Expand Down Expand Up @@ -1055,6 +1075,8 @@ Y_UNIT_TEST_SUITE(TPartBtreeIndexIt) {

CheckSeekRowId<TTestEnv>(part);
CheckSeekRowId<TTouchEnv>(part);
CheckSeekLast<TTestEnv>(part);
CheckSeekLast<TTouchEnv>(part);
CheckSeekKey<TTestEnv>(part, eggs.Scheme->Keys.Get());
CheckSeekKey<TTouchEnv>(part, eggs.Scheme->Keys.Get());
CheckNextPrev<TTestEnv>(part);
Expand Down
16 changes: 11 additions & 5 deletions ydb/core/tablet_flat/ut/ut_slice_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace {
NPage::TConf conf{ true, 2 * 1024 };

conf.Group(0).IndexMin = 1024; /* Should cover index buffer grow code */
conf.Group(0).BTreeIndexNodeTargetSize = 512; /* Should cover up/down moves */
conf.SmallEdge = 19; /* Packed to page collection large cell values */
conf.LargeEdge = 29; /* Large values placed to single blobs */
conf.SliceSize = conf.Group(0).PageSize * 4;
Expand Down Expand Up @@ -53,6 +54,11 @@ namespace {
return part;
}

bool IsBTreeIndex()
{
return Eggs0().Lone()->IndexPages.BTreeGroups.size();
}

class TTestPartPageCollection : public NPageCollection::IPageCollection {
public:
TTestPartPageCollection(TIntrusiveConstPtr<NTest::TPartStore> part, ui32 room)
Expand Down Expand Up @@ -187,7 +193,7 @@ Y_UNIT_TEST_SUITE(TPartSliceLoader) {

Y_UNIT_TEST(RestoreMissingSlice) {
auto result = RunLoaderTest(Part0(), nullptr);
UNIT_ASSERT_C(result.Pages == 3, // index + first + last
UNIT_ASSERT_C(result.Pages == (IsBTreeIndex() ? 5 : 1) + 2, // index + first + last
"Restoring slice bounds needed " << result.Pages << " extra pages");
}

Expand All @@ -199,7 +205,7 @@ Y_UNIT_TEST_SUITE(TPartSliceLoader) {
TIntrusiveConstPtr<TScreen> screen = new TScreen(std::move(holes));
auto result = RunLoaderTest(Part0(), screen);

UNIT_ASSERT_VALUES_EQUAL_C(result.Pages, 3, // index + first + last
UNIT_ASSERT_VALUES_EQUAL_C(result.Pages, (IsBTreeIndex() ? 5 : 1) + 2, // index + first + last
"Restoring slice [" << startOff << ", " << IndexTools::GetEndRowId(*Part0()) + endOff << "] bounds needed "
<< result.Pages << " extra pages");
}
Expand Down Expand Up @@ -227,7 +233,7 @@ Y_UNIT_TEST_SUITE(TPartSliceLoader) {
screen = new TScreen(std::move(holes));
}
auto result = RunLoaderTest(Part0(), screen);
UNIT_ASSERT_VALUES_EQUAL_C(result.Pages, 1 + IndexTools::CountMainPages(*Part0()), // index + all data pages
UNIT_ASSERT_VALUES_EQUAL_C(result.Pages, (IsBTreeIndex() ? 70 : 1) + IndexTools::CountMainPages(*Part0()), // index + all data pages
"Restoring slice bounds needed " << result.Pages << " extra pages");
}

Expand All @@ -254,7 +260,7 @@ Y_UNIT_TEST_SUITE(TPartSliceLoader) {
screen = new TScreen(std::move(holes));
}
auto result = RunLoaderTest(Part0(), screen);
UNIT_ASSERT_VALUES_EQUAL_C(result.Pages, 1 + IndexTools::CountMainPages(*Part0()), // index + all data pages
UNIT_ASSERT_VALUES_EQUAL_C(result.Pages, (IsBTreeIndex() ? 70 : 1) + IndexTools::CountMainPages(*Part0()), // index + all data pages
"Restoring slice bounds needed " << result.Pages << " extra pages");
}

Expand Down Expand Up @@ -283,7 +289,7 @@ Y_UNIT_TEST_SUITE(TPartSliceLoader) {
screen = new TScreen(std::move(holes));
}
auto result = RunLoaderTest(Part0(), screen);
UNIT_ASSERT_VALUES_EQUAL_C(result.Pages, screen->Size() + 1, // index + data pages
UNIT_ASSERT_VALUES_EQUAL_C(result.Pages, (IsBTreeIndex() ? 70 : 1) + screen->Size(), // index + data pages
"Restoring slice bounds needed " << result.Pages <<
" extra pages, expected " << screen->Size());
}
Expand Down
1 change: 1 addition & 0 deletions ydb/core/tablet_flat/ut/ut_stat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace {
conf.Groups.resize(groups);
for (size_t group : xrange(groups)) {
conf.Group(group).IndexMin = 1024; /* Should cover index buffer grow code */
conf.Group(group).BTreeIndexNodeTargetSize = 512; /* Should cover up/down moves */
}
conf.SmallEdge = 19; /* Packed to page collection large cell values */
conf.LargeEdge = 29; /* Large values placed to single blobs */
Expand Down

0 comments on commit 897ada7

Please sign in to comment.