From 2cc063e0f35c716883a8f05f9afb8b0502c69387 Mon Sep 17 00:00:00 2001 From: Innokentii Mokin Date: Mon, 15 Jul 2024 13:41:46 +0000 Subject: [PATCH 1/2] add unsafe append to tablecell --- ydb/core/scheme/scheme_tablecell.cpp | 35 +++++++++++++++++++++++++ ydb/core/scheme/scheme_tablecell.h | 3 +++ ydb/core/scheme/scheme_tablecell_ut.cpp | 33 +++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/ydb/core/scheme/scheme_tablecell.cpp b/ydb/core/scheme/scheme_tablecell.cpp index 77c0e3319196..be58763d54b4 100644 --- a/ydb/core/scheme/scheme_tablecell.cpp +++ b/ydb/core/scheme/scheme_tablecell.cpp @@ -258,6 +258,41 @@ bool TSerializedCellVec::DoTryParse(const TString& data) { return TryDeserializeCellVec(data, Buf, Cells); } +bool TSerializedCellVec::UnsafeAppendCells(TConstArrayRef cells, TString& serializedCellVec) { + if (Y_UNLIKELY(cells.size() == 0)) { + return true; + } + + if (!serializedCellVec) { + TSerializedCellVec::Serialize(serializedCellVec, cells); + return true; + } + + const char* buf = serializedCellVec.data(); + const char* bufEnd = serializedCellVec.data() + serializedCellVec.size(); + + if (Y_UNLIKELY(bufEnd - buf < static_cast(sizeof(ui16)))) { + return false; + } + + ui16 cellCount = ReadUnaligned(buf); + cellCount += cells.size(); + + const ui64 addSize = std::accumulate( + std::begin(cells), std::end(cells), 0ul, [](const auto& acc, const auto& cell){ return acc + cell.Size(); }); + + serializedCellVec.ReserveAndResize(serializedCellVec.size() + sizeof(ui32) * cells.size() + addSize); + + char* mutableBuf = serializedCellVec.Detach(); + char* oldBufEnd = mutableBuf + (bufEnd - buf); + + WriteUnaligned(mutableBuf, cellCount); + + SerializeCellVecBody(cells, oldBufEnd, nullptr); + + return true; +} + TSerializedCellMatrix::TSerializedCellMatrix(TConstArrayRef cells, ui32 rowCount, ui16 colCount) : RowCount(rowCount), ColCount(colCount) { diff --git a/ydb/core/scheme/scheme_tablecell.h b/ydb/core/scheme/scheme_tablecell.h index 752be860abc6..5ce8d5515cc2 100644 --- a/ydb/core/scheme/scheme_tablecell.h +++ b/ydb/core/scheme/scheme_tablecell.h @@ -555,6 +555,9 @@ class TSerializedCellVec { return Cells; } + // read headers, assuming the buf is correct and append additional cells at the end + static bool UnsafeAppendCells(TConstArrayRef cells, TString& serializedCellVec); + static void Serialize(TString& res, TConstArrayRef cells); static TString Serialize(TConstArrayRef cells); diff --git a/ydb/core/scheme/scheme_tablecell_ut.cpp b/ydb/core/scheme/scheme_tablecell_ut.cpp index ae780b8cfc5f..e842cf5268e4 100644 --- a/ydb/core/scheme/scheme_tablecell_ut.cpp +++ b/ydb/core/scheme/scheme_tablecell_ut.cpp @@ -507,4 +507,37 @@ Y_UNIT_TEST_SUITE(Scheme) { } } } + + Y_UNIT_TEST(UnsafeAppend) { + TString appended = TSerializedCellVec::Serialize({}); + + UNIT_ASSERT(TSerializedCellVec::UnsafeAppendCells({}, appended)); + + UNIT_ASSERT_EQUAL(appended.size(), 0); + + ui64 intVal = 42; + char bigStrVal[] = "This is a large string value that shouldn't be inlined"; + + TVector cells; + cells.emplace_back(TCell::Make(intVal)); + cells.emplace_back(bigStrVal, sizeof(bigStrVal)); + + UNIT_ASSERT(TSerializedCellVec::UnsafeAppendCells(cells, appended)); + TString serialized = TSerializedCellVec::Serialize(cells); + + UNIT_ASSERT_VALUES_EQUAL(appended, serialized); + + UNIT_ASSERT(TSerializedCellVec::UnsafeAppendCells(cells, appended)); + + cells.emplace_back(TCell::Make(intVal)); + cells.emplace_back(bigStrVal, sizeof(bigStrVal)); + + serialized = TSerializedCellVec::Serialize(cells); + + UNIT_ASSERT_VALUES_EQUAL(appended, serialized); + + appended.resize(1); + + UNIT_ASSERT(!TSerializedCellVec::UnsafeAppendCells(cells, appended)); + } } From 7d794a42a5560822544e758390d5410a1acf4b1e Mon Sep 17 00:00:00 2001 From: Innokentii Mokin Date: Mon, 15 Jul 2024 14:16:14 +0000 Subject: [PATCH 2/2] fix --- ydb/core/scheme/scheme_tablecell.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ydb/core/scheme/scheme_tablecell.cpp b/ydb/core/scheme/scheme_tablecell.cpp index be58763d54b4..50fc875003eb 100644 --- a/ydb/core/scheme/scheme_tablecell.cpp +++ b/ydb/core/scheme/scheme_tablecell.cpp @@ -278,10 +278,12 @@ bool TSerializedCellVec::UnsafeAppendCells(TConstArrayRef cells, TString& ui16 cellCount = ReadUnaligned(buf); cellCount += cells.size(); - const ui64 addSize = std::accumulate( - std::begin(cells), std::end(cells), 0ul, [](const auto& acc, const auto& cell){ return acc + cell.Size(); }); + size_t newSize = serializedCellVec.size(); - serializedCellVec.ReserveAndResize(serializedCellVec.size() + sizeof(ui32) * cells.size() + addSize); + for (auto& cell : cells) + newSize += sizeof(TCellHeader) + cell.Size(); + + serializedCellVec.ReserveAndResize(newSize); char* mutableBuf = serializedCellVec.Detach(); char* oldBufEnd = mutableBuf + (bufEnd - buf);