Skip to content

Commit ca6eab5

Browse files
authored
Support TString = std::string in TSerializedCellVec (#13382)
1 parent b22deca commit ca6eab5

File tree

2 files changed

+120
-50
lines changed

2 files changed

+120
-50
lines changed

ydb/core/scheme/scheme_tablecell.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,8 @@ namespace {
396396
return true;
397397
}
398398

399-
Y_FORCE_INLINE bool TryDeserializeCellVec(const TString& data, TString& resultBuffer, TVector<TCell> & resultCells) {
400-
resultBuffer.clear();
399+
Y_FORCE_INLINE bool TryDeserializeCellVec(const TString& data, TVector<TCell>& resultCells) {
401400
resultCells.clear();
402-
403401
if (data.empty()) {
404402
return true;
405403
}
@@ -415,14 +413,11 @@ namespace {
415413
return false;
416414
}
417415

418-
resultBuffer = data;
419416
return true;
420417
}
421418

422-
Y_FORCE_INLINE bool TryDeserializeCellMatrix(const TString& data, TString& resultBuffer, TVector<TCell>& resultCells, ui32& rowCount, ui16& colCount) {
423-
resultBuffer.clear();
419+
Y_FORCE_INLINE bool TryDeserializeCellMatrix(const TString& data, TVector<TCell>& resultCells, ui32& rowCount, ui16& colCount) {
424420
resultCells.clear();
425-
426421
if (data.empty()) {
427422
return true;
428423
}
@@ -437,7 +432,6 @@ namespace {
437432
return false;
438433
}
439434

440-
resultBuffer = data;
441435
return true;
442436
}
443437
}
@@ -466,8 +460,13 @@ size_t TSerializedCellVec::SerializedSize(TConstArrayRef<TCell> cells) {
466460
return size;
467461
}
468462

469-
bool TSerializedCellVec::DoTryParse(const TString& data) {
470-
return TryDeserializeCellVec(data, Buf, Cells);
463+
bool TSerializedCellVec::DoTryParse() {
464+
if (!TryDeserializeCellVec(Buf, Cells)) {
465+
Buf.clear();
466+
Cells.clear();
467+
return false;
468+
}
469+
return true;
471470
}
472471

473472
bool TSerializedCellVec::UnsafeAppendCells(TConstArrayRef<TCell> cells, TString& serializedCellVec) {
@@ -554,8 +553,15 @@ TString TSerializedCellMatrix::Serialize(TConstArrayRef<TCell> cells, ui32 rowCo
554553
return result;
555554
}
556555

557-
bool TSerializedCellMatrix::DoTryParse(const TString& data) {
558-
return TryDeserializeCellMatrix(data, Buf, Cells, RowCount, ColCount);
556+
bool TSerializedCellMatrix::DoTryParse() {
557+
if (!TryDeserializeCellMatrix(Buf, Cells, RowCount, ColCount)) {
558+
Buf.clear();
559+
Cells.clear();
560+
RowCount = 0;
561+
ColCount = 0;
562+
return false;
563+
}
564+
return true;
559565
}
560566

561567
void TCellsStorage::Reset(TArrayRef<const TCell> cells)

ydb/core/scheme/scheme_tablecell.h

Lines changed: 102 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -585,55 +585,84 @@ static_assert(std::is_nothrow_default_constructible_v<TOwnedCellVec>, "Expected
585585
// When loading from a buffer the cells will point to the buffer contents
586586
class TSerializedCellVec {
587587
public:
588+
TSerializedCellVec() = default;
589+
588590
explicit TSerializedCellVec(TConstArrayRef<TCell> cells);
589591

590-
explicit TSerializedCellVec(const TString& buf)
592+
explicit TSerializedCellVec(TString&& buf)
593+
: Buf(std::move(buf))
591594
{
592-
Parse(buf);
595+
Y_ABORT_UNLESS(DoTryParse());
593596
}
594597

595-
TSerializedCellVec() = default;
596-
597-
TSerializedCellVec(const TSerializedCellVec &other)
598-
: Buf(other.Buf)
599-
, Cells(other.Cells)
598+
explicit TSerializedCellVec(const TString& buf)
599+
: Buf(buf)
600600
{
601-
Y_ABORT_UNLESS(Buf.data() == other.Buf.data(), "Buffer must be shared");
601+
Y_ABORT_UNLESS(DoTryParse());
602602
}
603603

604-
TSerializedCellVec(TSerializedCellVec &&other)
604+
TSerializedCellVec(TSerializedCellVec&& other)
605605
{
606606
*this = std::move(other);
607607
}
608608

609-
TSerializedCellVec &operator=(const TSerializedCellVec &other)
609+
TSerializedCellVec(const TSerializedCellVec& other)
610+
{
611+
*this = other;
612+
}
613+
614+
TSerializedCellVec& operator=(TSerializedCellVec&& other)
610615
{
611616
if (this == &other)
612617
return *this;
613618

614-
TSerializedCellVec tmp(other);
615-
*this = std::move(tmp);
619+
const char* prevPtr = other.Buf.data();
620+
Buf = std::move(other.Buf);
621+
if (Buf.data() != prevPtr) {
622+
// Data address changed, e.g. when TString is a small std::string
623+
Y_ABORT_UNLESS(DoTryParse(), "Failed to re-parse TSerializedCellVec");
624+
other.Cells.clear();
625+
} else {
626+
// Data address unchanged, reuse parsed Cells
627+
Cells = std::move(other.Cells);
628+
}
616629
return *this;
617630
}
618631

619-
TSerializedCellVec &operator=(TSerializedCellVec &&other)
632+
TSerializedCellVec& operator=(const TSerializedCellVec& other)
620633
{
621634
if (this == &other)
622635
return *this;
623636

624-
const char* otherPtr = other.Buf.data();
625-
Buf = std::move(other.Buf);
626-
Y_ABORT_UNLESS(Buf.data() == otherPtr, "Buffer address must not change");
627-
Cells = std::move(other.Cells);
637+
Buf = other.Buf;
638+
if (Buf.data() != other.Buf.data()) {
639+
// Data address changed, e.g. when TString is std::string
640+
Y_ABORT_UNLESS(DoTryParse(), "Failed to re-parse TSerializedCellVec");
641+
} else {
642+
// Data address unchanged, reuse parsed Cells
643+
Cells = other.Cells;
644+
}
628645
return *this;
629646
}
630647

648+
static bool TryParse(TString&& data, TSerializedCellVec& vec) {
649+
vec.Buf = std::move(data);
650+
return vec.DoTryParse();
651+
}
652+
631653
static bool TryParse(const TString& data, TSerializedCellVec& vec) {
632-
return vec.DoTryParse(data);
654+
vec.Buf = data;
655+
return vec.DoTryParse();
656+
}
657+
658+
void Parse(TString&& buf) {
659+
Buf = std::move(buf);
660+
Y_ABORT_UNLESS(DoTryParse());
633661
}
634662

635-
void Parse(const TString &buf) {
636-
Y_ABORT_UNLESS(DoTryParse(buf));
663+
void Parse(const TString& buf) {
664+
Buf = buf;
665+
Y_ABORT_UNLESS(DoTryParse());
637666
}
638667

639668
TConstArrayRef<TCell> GetCells() const {
@@ -654,15 +683,15 @@ class TSerializedCellVec {
654683

655684
static size_t SerializedSize(TConstArrayRef<TCell> cells);
656685

657-
const TString &GetBuffer() const { return Buf; }
686+
const TString& GetBuffer() const { return Buf; }
658687

659688
TString ReleaseBuffer() {
660689
Cells.clear();
661690
return std::move(Buf);
662691
}
663692

664693
private:
665-
bool DoTryParse(const TString& data);
694+
bool DoTryParse();
666695

667696
private:
668697
TString Buf;
@@ -673,14 +702,21 @@ class TSerializedCellVec {
673702
// When loading from a buffer the cells will point to the buffer contents
674703
class TSerializedCellMatrix {
675704
public:
705+
TSerializedCellMatrix() = default;
706+
676707
explicit TSerializedCellMatrix(TConstArrayRef<TCell> cells, ui32 rowCount, ui16 colCount);
677708

678-
explicit TSerializedCellMatrix(const TString& buf)
709+
explicit TSerializedCellMatrix(TString&& buf)
710+
: Buf(std::move(buf))
679711
{
680-
Parse(buf);
712+
Y_ABORT_UNLESS(DoTryParse());
681713
}
682714

683-
TSerializedCellMatrix() = default;
715+
explicit TSerializedCellMatrix(const TString& buf)
716+
: Buf(buf)
717+
{
718+
Y_ABORT_UNLESS(DoTryParse());
719+
}
684720

685721
TSerializedCellMatrix(const TSerializedCellMatrix& other)
686722
: Buf(other.Buf)
@@ -696,36 +732,64 @@ class TSerializedCellMatrix {
696732
*this = std::move(other);
697733
}
698734

699-
TSerializedCellMatrix& operator=(const TSerializedCellMatrix& other)
735+
TSerializedCellMatrix& operator=(TSerializedCellMatrix&& other)
700736
{
701737
if (this == &other)
702738
return *this;
703739

704-
TSerializedCellMatrix tmp(other);
705-
*this = std::move(tmp);
740+
const char* prevPtr = other.Buf.data();
741+
Buf = std::move(other.Buf);
742+
if (Buf.data() != prevPtr) {
743+
// Data address changed, e.g. when TString is a small std::string
744+
Y_ABORT_UNLESS(DoTryParse(), "Failed to re-parse TSerializedCellMatrix");
745+
other.Cells.clear();
746+
} else {
747+
// Data address unchanged, reuse parsed cells
748+
Cells = std::move(other.Cells);
749+
RowCount = other.RowCount;
750+
ColCount = other.ColCount;
751+
}
752+
other.RowCount = 0;
753+
other.ColCount = 0;
706754
return *this;
707755
}
708756

709-
TSerializedCellMatrix& operator=(TSerializedCellMatrix&& other)
757+
TSerializedCellMatrix& operator=(const TSerializedCellMatrix& other)
710758
{
711759
if (this == &other)
712760
return *this;
713761

714-
const char* otherPtr = other.Buf.data();
715-
Buf = std::move(other.Buf);
716-
Y_ABORT_UNLESS(Buf.data() == otherPtr, "Buffer address must not change");
717-
Cells = std::move(other.Cells);
718-
RowCount = std::move(other.RowCount);
719-
ColCount = std::move(other.ColCount);
762+
Buf = other.Buf;
763+
if (Buf.data() != other.Buf.data()) {
764+
// Data address changed, e.g. when TString is std::string
765+
Y_ABORT_UNLESS(DoTryParse(), "Failed to re-parse TSerializedCellMatrix");
766+
} else {
767+
// Data address unchanged, reuse parsed cells
768+
Cells = other.Cells;
769+
RowCount = other.RowCount;
770+
ColCount = other.ColCount;
771+
}
720772
return *this;
721773
}
722774

775+
static bool TryParse(TString&& data, TSerializedCellMatrix& vec) {
776+
vec.Buf = std::move(data);
777+
return vec.DoTryParse();
778+
}
779+
723780
static bool TryParse(const TString& data, TSerializedCellMatrix& vec) {
724-
return vec.DoTryParse(data);
781+
vec.Buf = data;
782+
return vec.DoTryParse();
783+
}
784+
785+
void Parse(TString&& buf) {
786+
Buf = std::move(buf);
787+
Y_ABORT_UNLESS(DoTryParse());
725788
}
726789

727790
void Parse(const TString& buf) {
728-
Y_ABORT_UNLESS(DoTryParse(buf));
791+
Buf = buf;
792+
Y_ABORT_UNLESS(DoTryParse());
729793
}
730794

731795
TConstArrayRef<TCell> GetCells() const { return Cells; }
@@ -753,7 +817,7 @@ class TSerializedCellMatrix {
753817
}
754818

755819
private:
756-
bool DoTryParse(const TString& data);
820+
bool DoTryParse();
757821

758822
private:
759823
TString Buf;

0 commit comments

Comments
 (0)