Skip to content

Commit d3137c8

Browse files
authored
1 parent 77f1571 commit d3137c8

File tree

10 files changed

+108
-46
lines changed

10 files changed

+108
-46
lines changed

cloud/filestore/libs/storage/service/service_actor_writedata.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,45 @@ bool IsThreeStageWriteEnabled(const NProto::TFileStore& fs)
3636

3737
////////////////////////////////////////////////////////////////////////////////
3838

39+
template <bool Owner = false>
3940
class TIovecContiguousChunk: public IContiguousChunk
4041
{
4142
private:
42-
ui64 Base = 0;
43+
char* Base = 0;
4344
ui64 Size = 0;
4445

4546
public:
4647
TIovecContiguousChunk(ui64 base, ui64 size)
47-
: Base(base)
48+
: Base(reinterpret_cast<char*>(base))
4849
, Size(size)
49-
{}
50+
{
51+
static_assert(sizeof(ui64) == sizeof(char*));
52+
}
53+
54+
~TIovecContiguousChunk() {
55+
if constexpr(Owner) {
56+
delete[] Base;
57+
}
58+
}
5059

5160
TContiguousSpan GetData() const override
5261
{
53-
return TContiguousSpan(reinterpret_cast<const char*>(Base), Size);
62+
return TContiguousSpan(Base, Size);
5463
}
5564

56-
TMutableContiguousSpan GetDataMut() override
65+
TMutableContiguousSpan UnsafeGetDataMut() override
5766
{
58-
return TMutableContiguousSpan(reinterpret_cast<char*>(Base), Size);
67+
return TMutableContiguousSpan(Base, Size);
68+
}
69+
70+
IContiguousChunk::TPtr Clone() override
71+
{
72+
auto copy = new char[Size];
73+
::memcpy(copy, Base, Size);
74+
75+
return MakeIntrusive<TIovecContiguousChunk<true>>(
76+
reinterpret_cast<ui64>(copy),
77+
Size);
5978
}
6079

6180
size_t GetOccupiedMemorySize() const override
@@ -76,7 +95,7 @@ TRope CreateRopeFromIovecs(const NProto::TWriteDataRequest& request)
7695
rope.Insert(
7796
rope.End(),
7897
TRope(TRcBuf(
79-
MakeIntrusive<TIovecContiguousChunk>(
98+
MakeIntrusive<TIovecContiguousChunk<>>(
8099
iovec.GetBase(),
81100
iovec.GetLength()))));
82101
}

contrib/ydb/core/blobstorage/crypto/ut/ut_helpers.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class TAlignedBuf {
5252
return BufSize;
5353
}
5454

55+
size_t GetAlign() const {
56+
return Align;
57+
}
58+
5559
~TAlignedBuf() {
5660
delete[] Buf;
5761
}
@@ -69,17 +73,19 @@ class TRopeAlignedBufferBackend : public IContiguousChunk {
6973
return {reinterpret_cast<const char *>(Buffer.Data()), Buffer.Size()};
7074
}
7175

72-
TMutableContiguousSpan GetDataMut() override {
73-
return {reinterpret_cast<char *>(Buffer.Data()), Buffer.Size()};
74-
}
75-
7676
TMutableContiguousSpan UnsafeGetDataMut() override {
7777
return {reinterpret_cast<char *>(Buffer.Data()), Buffer.Size()};
7878
}
7979

8080
size_t GetOccupiedMemorySize() const override {
8181
return Buffer.Size();
8282
}
83+
84+
IContiguousChunk::TPtr Clone() override {
85+
auto newBackend = MakeIntrusive<TRopeAlignedBufferBackend>(Buffer.Size(), Buffer.GetAlign());
86+
::memcpy(newBackend->UnsafeGetDataMut().data(), GetData().data(), GetData().size());
87+
return newBackend;
88+
}
8389
};
8490

8591
void inline Print(const ui8* out, size_t size) {

contrib/ydb/core/blobstorage/vdisk/hulldb/base/hullds_arena.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,20 @@ namespace NKikimr {
2222
return Capacity;
2323
}
2424

25-
TMutableContiguousSpan GetDataMut() override {
25+
TMutableContiguousSpan UnsafeGetDataMut() override {
2626
return {Data, Capacity};
2727
}
2828

2929
static TIntrusivePtr<IContiguousChunk> Allocate() {
3030
return MakeIntrusive<TRopeArenaBackend>();
3131
}
32+
33+
IContiguousChunk::TPtr Clone() override {
34+
IContiguousChunk::TPtr buf = Allocate();
35+
TContiguousSpan src = GetData();
36+
::memcpy(buf->UnsafeGetDataMut().GetData(), src.Data(), src.GetSize());
37+
return buf;
38+
}
3239
};
3340

3441
}

contrib/ydb/core/erasure/erasure_split.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ namespace NKikimr {
1010
return {ZeroData, sizeof(ZeroData)};
1111
}
1212

13-
TMutableContiguousSpan GetDataMut() override {
14-
return {const_cast<char*>(ZeroData), sizeof(ZeroData)};
15-
}
16-
1713
TMutableContiguousSpan UnsafeGetDataMut() override {
1814
return {const_cast<char*>(ZeroData), sizeof(ZeroData)};
1915
}
2016

2117
size_t GetOccupiedMemorySize() const override {
2218
return sizeof(ZeroData);
2319
}
20+
21+
IContiguousChunk::TPtr Clone() noexcept override {
22+
return this;
23+
}
2424
};
2525

2626
void ErasureSplitBlock42Prepare(const TRope& whole, std::span<TRope> parts) {

contrib/ydb/library/actors/util/rc_buf.h

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -276,32 +276,30 @@ struct IContiguousChunk : TThrRefBase {
276276
*/
277277
virtual TContiguousSpan GetData() const = 0;
278278

279-
/**
280-
* Should give mutable access to underlying data
281-
* If data is shared - data should be copied
282-
* E.g. for TString str.Detach() should be used
283-
* Possibly invalidates previous *GetData*() calls
284-
*/
285-
virtual TMutableContiguousSpan GetDataMut() = 0;
286-
287279
/**
288280
* Should give mutable access to undelying data as fast as possible
289281
* Even if data is shared this property should be ignored
290282
* E.g. in TString const_cast<char *>(str.data()) should be used
291283
* Possibly invalidates previous *GetData*() calls
292284
*/
293-
virtual TMutableContiguousSpan UnsafeGetDataMut() {
294-
return GetDataMut();
295-
}
285+
virtual TMutableContiguousSpan UnsafeGetDataMut() = 0;
296286

297287
/**
298-
* Should return true if GetDataMut() would not copy contents when called.
288+
* Must return false if the implementation shares data
299289
*/
300290
virtual bool IsPrivate() const {
301-
return true;
291+
return RefCount() == 1;
302292
}
303293

304294
virtual size_t GetOccupiedMemorySize() const = 0;
295+
296+
297+
/**
298+
* Allocate new chunk and copy data into it
299+
* NOTE: The actual implementation of clonned chunk may be different
300+
*/
301+
302+
virtual IContiguousChunk::TPtr Clone() = 0;
305303
};
306304

307305
class TRope;
@@ -444,7 +442,7 @@ class TRcBuf {
444442
} else if constexpr (std::is_same_v<T, TString>) {
445443
return value.IsDetached();
446444
} else if constexpr (std::is_same_v<T, IContiguousChunk::TPtr>) {
447-
return value.RefCount() == 1 && value->IsPrivate();
445+
return value->IsPrivate();
448446
} else {
449447
static_assert(TDependentFalse<T>);
450448
}
@@ -486,7 +484,10 @@ class TRcBuf {
486484
}
487485
return {value.mutable_data(), value.size()};
488486
} else if constexpr (std::is_same_v<T, IContiguousChunk::TPtr>) {
489-
return value->GetDataMut();
487+
if (!value->IsPrivate()) {
488+
value = value->Clone();
489+
}
490+
return value->UnsafeGetDataMut();
490491
} else {
491492
static_assert(TDependentFalse<T>, "unexpected type");
492493
}

contrib/ydb/library/actors/util/rc_buf_ut.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,25 @@ Y_UNIT_TEST_SUITE(TRcBuf) {
6363
Y_UNIT_TEST(Detach) {
6464
TRcBuf data = TRcBuf::Copy(TString("test"));
6565
TRcBuf data2 = data;
66+
UNIT_ASSERT_EQUAL(data.GetData(), data2.GetData());
6667
char* res = data2.Detach();
6768
UNIT_ASSERT_UNEQUAL(data.GetData(), data2.GetData());
6869
UNIT_ASSERT_EQUAL(res, data2.GetData());
6970
UNIT_ASSERT_EQUAL(::memcmp(res, "test", 4), 0);
7071
UNIT_ASSERT_EQUAL(::memcmp(data.GetData(), "test", 4), 0);
7172
}
7273

74+
Y_UNIT_TEST(DetachAndDestroySrc) {
75+
TRcBuf data = TRcBuf::Copy(TString("test"));
76+
TRcBuf data2 = data;
77+
data = {};
78+
UNIT_ASSERT_EQUAL(data2.GetSize(), 4);
79+
char* res = data2.Detach();
80+
UNIT_ASSERT_EQUAL(data2.GetSize(), 4);
81+
UNIT_ASSERT_EQUAL(res, data2.GetData());
82+
UNIT_ASSERT_EQUAL(::memcmp(res, "test", 4), 0);
83+
}
84+
7385
Y_UNIT_TEST(Resize) {
7486
TRcBuf data = TRcBuf::Uninitialized(10, 20, 30);
7587
UNIT_ASSERT_EQUAL(data.size(), 10);

contrib/ydb/library/actors/util/rope.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class TRopeAlignedBuffer : public IContiguousChunk {
2020
static constexpr size_t Alignment = 16;
2121
static constexpr size_t MallocAlignment = sizeof(size_t);
2222

23-
ui32 Size;
23+
const ui32 Size;
2424
const ui32 Capacity;
2525
const ui32 Offset;
2626
alignas(Alignment) char Data[];
@@ -38,6 +38,13 @@ class TRopeAlignedBuffer : public IContiguousChunk {
3838
return new(malloc(sizeof(TRopeAlignedBuffer) + size + Alignment - MallocAlignment)) TRopeAlignedBuffer(size);
3939
}
4040

41+
IContiguousChunk::TPtr Clone() override {
42+
TIntrusivePtr<TRopeAlignedBuffer> buf = Allocate(Size);
43+
TContiguousSpan src = GetData();
44+
::memcpy(buf->UnsafeGetDataMut().GetData(), src.Data(), src.GetSize());
45+
return buf;
46+
}
47+
4148
void *operator new(size_t) {
4249
Y_ABORT();
4350
}
@@ -59,7 +66,7 @@ class TRopeAlignedBuffer : public IContiguousChunk {
5966
return {Data + Offset, Size};
6067
}
6168

62-
TMutableContiguousSpan GetDataMut() override {
69+
TMutableContiguousSpan UnsafeGetDataMut() override {
6370
return {Data + Offset, Size};
6471
}
6572

contrib/ydb/library/actors/util/rope_ut.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,19 @@ class TRopeStringBackend : public IContiguousChunk {
1515
return {Buffer.data(), Buffer.size()};
1616
}
1717

18-
TMutableContiguousSpan GetDataMut() override {
19-
return {Buffer.Detach(), Buffer.size()};
20-
}
21-
2218
TMutableContiguousSpan UnsafeGetDataMut() override {
2319
return {const_cast<char*>(Buffer.data()), Buffer.size()};
2420
}
2521

2622
size_t GetOccupiedMemorySize() const override {
2723
return Buffer.capacity();
2824
}
25+
26+
IContiguousChunk::TPtr Clone() override {
27+
auto ptr = MakeIntrusive<TRopeStringBackend>(Buffer);
28+
ptr->Buffer.Detach();
29+
return ptr;
30+
}
2931
};
3032

3133
TRope CreateRope(TString s, size_t sliceSize) {

contrib/ydb/library/actors/util/shared_data_rope_backend.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,27 @@ class TRopeSharedDataBackend : public IContiguousChunk {
1818
return {Buffer.data(), Buffer.size()};
1919
}
2020

21-
TMutableContiguousSpan GetDataMut() override {
22-
if(Buffer.IsShared()) {
21+
TMutableContiguousSpan UnsafeGetDataMut() override {
22+
// Actualy should newer be true, but acciording to the API this class can share TSharedData with some external buffer
23+
if (Buffer.IsShared()) {
2324
Buffer = TSharedData::Copy(Buffer.data(), Buffer.size());
2425
}
2526
return {Buffer.mutable_data(), Buffer.size()};
2627
}
2728

28-
TMutableContiguousSpan UnsafeGetDataMut() override {
29-
return {const_cast<char *>(Buffer.data()), Buffer.size()};
30-
}
31-
3229
bool IsPrivate() const override {
33-
return Buffer.IsPrivate();
30+
return RefCount() == 1 && Buffer.IsPrivate();
3431
}
3532

3633
size_t GetOccupiedMemorySize() const override {
3734
return Buffer.size();
3835
}
36+
37+
IContiguousChunk::TPtr Clone() override {
38+
auto backend = MakeIntrusive<TRopeSharedDataBackend>(Buffer);
39+
backend->Buffer.Detach();
40+
return backend;
41+
}
3942
};
4043

4144
} // namespace NActors

contrib/ydb/library/yql/utils/rope_over_buffer.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,19 @@ class TContigousChunkOverBuf : public IContiguousChunk {
1818
return Span_;
1919
}
2020

21-
TMutableContiguousSpan GetDataMut() override {
21+
TMutableContiguousSpan UnsafeGetDataMut() override {
2222
YQL_ENSURE(false, "Payload mutation is not supported");
2323
}
2424

2525
size_t GetOccupiedMemorySize() const override {
2626
return Span_.GetSize();
2727
}
2828

29+
IContiguousChunk::TPtr Clone() noexcept override {
30+
// Mutable call is not supported.
31+
return this;
32+
}
33+
2934
const std::shared_ptr<const void> Owner_;
3035
const TContiguousSpan Span_;
3136
};
@@ -40,4 +45,4 @@ TRope MakeReadOnlyRope(const std::shared_ptr<const void>& owner, const char* dat
4045
return TRope(new TContigousChunkOverBuf(owner, {data, size}));
4146
}
4247

43-
} // namespace NYql
48+
} // namespace NYql

0 commit comments

Comments
 (0)