Skip to content

Commit d0c6dfb

Browse files
authored
add unsafe append to tablecell (#6696)
1 parent e1cde29 commit d0c6dfb

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

ydb/core/scheme/scheme_tablecell.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,45 @@ bool TSerializedCellVec::DoTryParse(const TString& data) {
258258
return TryDeserializeCellVec(data, Buf, Cells);
259259
}
260260

261+
bool TSerializedCellVec::UnsafeAppendCells(TConstArrayRef<TCell> cells, TString& serializedCellVec) {
262+
if (Y_UNLIKELY(cells.size() == 0)) {
263+
return true;
264+
}
265+
266+
if (!serializedCellVec) {
267+
TSerializedCellVec::Serialize(serializedCellVec, cells);
268+
return true;
269+
}
270+
271+
const char* buf = serializedCellVec.data();
272+
const char* bufEnd = serializedCellVec.data() + serializedCellVec.size();
273+
const size_t bufSize = bufEnd - buf;
274+
275+
if (Y_UNLIKELY(bufSize < static_cast<ptrdiff_t>(sizeof(ui16)))) {
276+
return false;
277+
}
278+
279+
ui16 cellCount = ReadUnaligned<ui16>(buf);
280+
cellCount += cells.size();
281+
282+
size_t newSize = serializedCellVec.size();
283+
284+
for (auto& cell : cells) {
285+
newSize += sizeof(TCellHeader) + cell.Size();
286+
}
287+
288+
serializedCellVec.ReserveAndResize(newSize);
289+
290+
char* mutableBuf = serializedCellVec.Detach();
291+
char* oldBufEnd = mutableBuf + bufSize;
292+
293+
WriteUnaligned<ui16>(mutableBuf, cellCount);
294+
295+
SerializeCellVecBody(cells, oldBufEnd, nullptr);
296+
297+
return true;
298+
}
299+
261300
TSerializedCellMatrix::TSerializedCellMatrix(TConstArrayRef<TCell> cells, ui32 rowCount, ui16 colCount)
262301
: RowCount(rowCount), ColCount(colCount)
263302
{

ydb/core/scheme/scheme_tablecell.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,9 @@ class TSerializedCellVec {
555555
return Cells;
556556
}
557557

558+
// read headers, assuming the buf is correct and append additional cells at the end
559+
static bool UnsafeAppendCells(TConstArrayRef<TCell> cells, TString& serializedCellVec);
560+
558561
static void Serialize(TString& res, TConstArrayRef<TCell> cells);
559562

560563
static TString Serialize(TConstArrayRef<TCell> cells);

ydb/core/scheme/scheme_tablecell_ut.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,4 +507,37 @@ Y_UNIT_TEST_SUITE(Scheme) {
507507
}
508508
}
509509
}
510+
511+
Y_UNIT_TEST(UnsafeAppend) {
512+
TString appended = TSerializedCellVec::Serialize({});
513+
514+
UNIT_ASSERT(TSerializedCellVec::UnsafeAppendCells({}, appended));
515+
516+
UNIT_ASSERT_EQUAL(appended.size(), 0);
517+
518+
ui64 intVal = 42;
519+
char bigStrVal[] = "This is a large string value that shouldn't be inlined";
520+
521+
TVector<TCell> cells;
522+
cells.emplace_back(TCell::Make(intVal));
523+
cells.emplace_back(bigStrVal, sizeof(bigStrVal));
524+
525+
UNIT_ASSERT(TSerializedCellVec::UnsafeAppendCells(cells, appended));
526+
TString serialized = TSerializedCellVec::Serialize(cells);
527+
528+
UNIT_ASSERT_VALUES_EQUAL(appended, serialized);
529+
530+
UNIT_ASSERT(TSerializedCellVec::UnsafeAppendCells(cells, appended));
531+
532+
cells.emplace_back(TCell::Make(intVal));
533+
cells.emplace_back(bigStrVal, sizeof(bigStrVal));
534+
535+
serialized = TSerializedCellVec::Serialize(cells);
536+
537+
UNIT_ASSERT_VALUES_EQUAL(appended, serialized);
538+
539+
appended.resize(1);
540+
541+
UNIT_ASSERT(!TSerializedCellVec::UnsafeAppendCells(cells, appended));
542+
}
510543
}

0 commit comments

Comments
 (0)