Skip to content

Commit

Permalink
issue-2461: support clear operation on persistent table
Browse files Browse the repository at this point in the history
  • Loading branch information
budevg committed Nov 11, 2024
1 parent 34b31ed commit 037976b
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 42 deletions.
97 changes: 55 additions & 42 deletions cloud/storage/core/libs/common/persistent_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,48 +145,7 @@ class TPersistentTable
: FileName(fileName)
, RecordCount(initialRecordCount)
{
// if file doesn't exist create file with zeroed header
TFile file(FileName, OpenAlways | WrOnly);
if (file.GetLength() == 0) {
file.Resize(CalcFileSize(0));
}
file.Close();

FileMap = std::make_unique<TFileMap>(FileName, TMemoryMapCommon::oRdWr);
FileMap->Map(0, sizeof(THeader));

auto* header = reinterpret_cast<THeader*>(FileMap->Ptr());
if (header->RecordCount == 0) {
header->Version = Version;
header->RecordCount = RecordCount;
header->HeaderSize = sizeof(THeader);
header->RecordSize = sizeof(TRecord);
header->CompactedRecordSrcIndex = InvalidIndex;
header->CompactedRecordDstIndex = InvalidIndex;
}

Y_ABORT_UNLESS(
header->Version == Version,
"Invalid header version %d",
header->Version);
Y_ABORT_UNLESS(
header->HeaderSize == sizeof(THeader),
"Invalid header size %lu != %lu",
header->HeaderSize,
sizeof(THeader));
Y_ABORT_UNLESS(
header->RecordSize == sizeof(TRecord),
"Invalid record size %lu != %lu",
header->RecordSize,
sizeof(TRecord));

RecordCount = header->RecordCount;

FileMap->ResizeAndRemap(0, CalcFileSize(RecordCount));
HeaderPtr = reinterpret_cast<THeader*>(FileMap->Ptr());
RecordsPtr = reinterpret_cast<TRecord*>(HeaderPtr + 1);

CompactRecords();
Init();
}

H* HeaderData()
Expand Down Expand Up @@ -240,7 +199,61 @@ class TPersistentTable
return NextFreeRecord - FreeRecords.size();
}

void Clear()
{
NextFreeRecord = 0;
FileMap.reset();
FreeRecords.clear();
Init();
}

private:
void Init()
{
// if file doesn't exist create file with zeroed header
TFile file(FileName, OpenAlways | WrOnly);
if (file.GetLength() == 0) {
file.Resize(CalcFileSize(0));
}
file.Close();

FileMap = std::make_unique<TFileMap>(FileName, TMemoryMapCommon::oRdWr);
FileMap->Map(0, sizeof(THeader));

auto* header = reinterpret_cast<THeader*>(FileMap->Ptr());
if (header->RecordCount == 0) {
header->Version = Version;
header->RecordCount = RecordCount;
header->HeaderSize = sizeof(THeader);
header->RecordSize = sizeof(TRecord);
header->CompactedRecordSrcIndex = InvalidIndex;
header->CompactedRecordDstIndex = InvalidIndex;
}

Y_ABORT_UNLESS(
header->Version == Version,
"Invalid header version %d",
header->Version);
Y_ABORT_UNLESS(
header->HeaderSize == sizeof(THeader),
"Invalid header size %lu != %lu",
header->HeaderSize,
sizeof(THeader));
Y_ABORT_UNLESS(
header->RecordSize == sizeof(TRecord),
"Invalid record size %lu != %lu",
header->RecordSize,
sizeof(TRecord));

RecordCount = header->RecordCount;

FileMap->ResizeAndRemap(0, CalcFileSize(RecordCount));
HeaderPtr = reinterpret_cast<THeader*>(FileMap->Ptr());
RecordsPtr = reinterpret_cast<TRecord*>(HeaderPtr + 1);

CompactRecords();
}

size_t CalcFileSize(size_t recordCount)
{
return sizeof(THeader) + recordCount * sizeof(TRecord);
Expand Down
26 changes: 26 additions & 0 deletions cloud/storage/core/libs/common/persistent_table_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,32 @@ Y_UNIT_TEST_SUITE(TPersistentTableTest)
UNIT_ASSERT_VALUES_EQUAL(ri.CountRecords(), table->CountRecords());
}
}

Y_UNIT_TEST(ShouldClearRecords)
{
TTempDir dir;
auto tablePath = dir.Path() / "table";

auto tableSize = 32;

TPersistentTable<THeader, TRecord> table(tablePath, tableSize);
UNIT_ASSERT_VALUES_EQUAL(table.CountRecords(), 0);

for (auto i = 0; i < tableSize; ++i) {
auto index = table.AllocRecord();
UNIT_ASSERT_VALUES_UNEQUAL(table.InvalidIndex, index);
UNIT_ASSERT_VALUES_EQUAL(table.CountRecords(), index + 1);
}

table.Clear();
UNIT_ASSERT_VALUES_EQUAL(table.CountRecords(), 0);

for (auto i = 0; i < tableSize; ++i) {
auto index = table.AllocRecord();
UNIT_ASSERT_VALUES_UNEQUAL(table.InvalidIndex, index);
UNIT_ASSERT_VALUES_EQUAL(table.CountRecords(), index + 1);
}
}
}

} // namespace NCloud

0 comments on commit 037976b

Please sign in to comment.