diff options
author | alexvru <alexvru@ydb.tech> | 2023-08-03 10:50:52 +0300 |
---|---|---|
committer | alexvru <alexvru@ydb.tech> | 2023-08-03 10:50:52 +0300 |
commit | e0ff37fbb9f0dbd6a20932a40b72e79dd77b572b (patch) | |
tree | 6a5ed43c96c6bbc501ffece029e08966242d5fd3 /library/cpp | |
parent | 6c82f53a066b2d61863529956787639fce914fbf (diff) | |
download | ydb-e0ff37fbb9f0dbd6a20932a40b72e79dd77b572b.tar.gz |
Fix Compact to support undetached containers KIKIMR-18902
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/actors/util/rc_buf.h | 39 | ||||
-rw-r--r-- | library/cpp/actors/util/shared_data_rope_backend.h | 4 |
2 files changed, 34 insertions, 9 deletions
diff --git a/library/cpp/actors/util/rc_buf.h b/library/cpp/actors/util/rc_buf.h index 11a09f5b9a..7b6c68d269 100644 --- a/library/cpp/actors/util/rc_buf.h +++ b/library/cpp/actors/util/rc_buf.h @@ -294,6 +294,13 @@ struct IContiguousChunk : TThrRefBase { return GetDataMut(); } + /** + * Should return true if GetDataMut() would not copy contents when called. + */ + virtual bool IsPrivate() const { + return true; + } + virtual size_t GetOccupiedMemorySize() const = 0; }; @@ -434,8 +441,12 @@ class TRcBuf { using T = std::decay_t<decltype(value)>; if constexpr (std::is_same_v<T, NActors::TSharedData> || std::is_same_v<T, TInternalBackend>) { return value.IsPrivate(); + } else if constexpr (std::is_same_v<T, TString>) { + return value.IsDetached(); + } else if constexpr (std::is_same_v<T, IContiguousChunk::TPtr>) { + return value.RefCount() == 1 && value->IsPrivate(); } else { - return false; + static_assert(TDependentFalse<T>); } }); } @@ -865,14 +876,20 @@ public: return Begin; } - char* GetDataMut() { - const char* oldBegin = Backend.GetData().data(); - ptrdiff_t offset = Begin - oldBegin; - size_t size = GetSize(); - char* newBegin = Backend.GetDataMut().data(); - Begin = newBegin + offset; - End = Begin + size; - return newBegin + offset; + char* GetDataMut(size_t headroom = 0, size_t tailroom = 0) { + const TContiguousSpan backendData = Backend.GetData(); + if (IsPrivate() || (backendData.data() == GetData() && backendData.size() == GetSize())) { // if we own container or reference it whole + const char* oldBegin = backendData.data(); + ptrdiff_t offset = Begin - oldBegin; + size_t size = GetSize(); + char* newBegin = Backend.GetDataMut().data(); + Begin = newBegin + offset; + End = Begin + size; + return newBegin + offset; + } else { // make a copy of referenced data + *this = Copy(GetContiguousSpan(), headroom, tailroom); + return Backend.GetDataMut().data(); + } } char* UnsafeGetDataMut() { @@ -1064,6 +1081,10 @@ public: return GetDataMut(); } + bool IsPrivate() const { + return Backend.IsPrivate(); + } + size_t UnsafeHeadroom() const { return Begin - Backend.GetData().data(); } diff --git a/library/cpp/actors/util/shared_data_rope_backend.h b/library/cpp/actors/util/shared_data_rope_backend.h index 2abfcf5584..a221ae668b 100644 --- a/library/cpp/actors/util/shared_data_rope_backend.h +++ b/library/cpp/actors/util/shared_data_rope_backend.h @@ -29,6 +29,10 @@ public: return {const_cast<char *>(Buffer.data()), Buffer.size()}; } + bool IsPrivate() const override { + return Buffer.IsPrivate(); + } + size_t GetOccupiedMemorySize() const override { return Buffer.size(); } |