3
3
#include < ydb/core/util/stlog.h>
4
4
#include < ydb/core/util/interval_set.h>
5
5
6
+ #include < ydb/core/blobstorage/pdisk/blobstorage_pdisk_quota_record.h>
6
7
#include < ydb/core/blobstorage/pdisk/blobstorage_pdisk_util_space_color.h>
7
8
8
9
namespace NKikimr {
@@ -50,7 +51,12 @@ struct TPDiskMockState::TImpl {
50
51
NPDisk::EDeviceType DeviceType;
51
52
std::optional<TRcBuf> Metadata;
52
53
53
- TImpl (ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize, bool isDiskReadOnly, NPDisk::EDeviceType deviceType)
54
+ ESpaceColorPolicy SpaceColorPolicy;
55
+ std::shared_ptr<NPDisk::TQuotaRecord> ChunkSharedQuota;
56
+ double Occupancy = 0 ;
57
+
58
+ TImpl (ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize, bool isDiskReadOnly, NPDisk::EDeviceType deviceType,
59
+ ESpaceColorPolicy spaceColorPolicy)
54
60
: NodeId(nodeId)
55
61
, PDiskId(pdiskId)
56
62
, PDiskGuid(pdiskGuid)
@@ -62,7 +68,20 @@ struct TPDiskMockState::TImpl {
62
68
, NextFreeChunk(1 )
63
69
, StatusFlags(NPDisk::TStatusFlags{})
64
70
, DeviceType(deviceType)
65
- {}
71
+ , SpaceColorPolicy(spaceColorPolicy)
72
+ {
73
+ switch (SpaceColorPolicy) {
74
+ case ESpaceColorPolicy::SharedQuota: {
75
+ ChunkSharedQuota = std::make_shared<NPDisk::TQuotaRecord>();
76
+ // 13% for CYAN is default value in prod
77
+ ChunkSharedQuota->ForceHardLimit (TotalChunks, NPDisk::TColorLimits::MakeChunkLimits (130 ));
78
+ break ;
79
+ }
80
+ case ESpaceColorPolicy::None:
81
+ default :
82
+ break ;
83
+ }
84
+ }
66
85
67
86
TImpl (const TImpl&) = default ;
68
87
@@ -76,6 +95,28 @@ struct TPDiskMockState::TImpl {
76
95
}
77
96
}
78
97
98
+ void UpdateStatusFlags () {
99
+ switch (SpaceColorPolicy) {
100
+ case ESpaceColorPolicy::SharedQuota: {
101
+ i64 before = ChunkSharedQuota->GetFree ();
102
+ i64 now = GetNumFreeChunks ();
103
+ if (before < now) {
104
+ ChunkSharedQuota->Release (now - before);
105
+ } else if (before > now) {
106
+ ChunkSharedQuota->ForceAllocate (before - now);
107
+ }
108
+
109
+ NKikimrBlobStorage::TPDiskSpaceColor::E newColor =
110
+ ChunkSharedQuota->EstimateSpaceColor (0 , &Occupancy);
111
+ SetStatusFlags (SpaceColorToStatusFlag (newColor));
112
+ break ;
113
+ }
114
+ case ESpaceColorPolicy::None:
115
+ default :
116
+ break ;
117
+ }
118
+ }
119
+
79
120
ui32 AllocateChunk (TOwner& to) {
80
121
ui32 chunkIdx = TotalChunks;
81
122
@@ -88,7 +129,8 @@ struct TPDiskMockState::TImpl {
88
129
to.ReservedChunks .insert (FreeChunks.extract (it));
89
130
}
90
131
91
- Y_VERIFY (chunkIdx != TotalChunks);
132
+ Y_ABORT_UNLESS (chunkIdx != TotalChunks);
133
+
92
134
return chunkIdx;
93
135
}
94
136
@@ -172,6 +214,7 @@ struct TPDiskMockState::TImpl {
172
214
for (const TChunkIdx chunkIdx : owner.ReservedChunks ) {
173
215
owner.ChunkData .erase (chunkIdx);
174
216
}
217
+
175
218
FreeChunks.merge (owner.ReservedChunks );
176
219
AdjustFreeChunks ();
177
220
}
@@ -188,7 +231,8 @@ struct TPDiskMockState::TImpl {
188
231
Y_VERIFY (num);
189
232
owner.ChunkData .erase (chunkIdx);
190
233
const bool inserted = FreeChunks.insert (chunkIdx).second ;
191
- Y_VERIFY (inserted);
234
+ Y_ABORT_UNLESS (inserted);
235
+
192
236
AdjustFreeChunks ();
193
237
}
194
238
@@ -286,8 +330,9 @@ struct TPDiskMockState::TImpl {
286
330
};
287
331
288
332
TPDiskMockState::TPDiskMockState (ui32 nodeId, ui32 pdiskId, ui64 pdiskGuid, ui64 size, ui32 chunkSize, bool isDiskReadOnly,
289
- NPDisk::EDeviceType deviceType)
290
- : TPDiskMockState(std::make_unique<TImpl>(nodeId, pdiskId, pdiskGuid, size, chunkSize, isDiskReadOnly, deviceType))
333
+ NPDisk::EDeviceType deviceType, ESpaceColorPolicy spaceColorPolicy)
334
+ : TPDiskMockState(std::make_unique<TImpl>(nodeId, pdiskId, pdiskGuid, size, chunkSize, isDiskReadOnly, deviceType,
335
+ spaceColorPolicy))
291
336
{}
292
337
293
338
TPDiskMockState::TPDiskMockState (std::unique_ptr<TImpl>&& impl)
@@ -670,12 +715,14 @@ class TPDiskMockActor : public TActorBootstrapped<TPDiskMockActor> {
670
715
if (Impl.GetNumFreeChunks () < msg->SizeChunks ) {
671
716
PDISK_MOCK_LOG (NOTICE, PDM09, " received TEvChunkReserve" , (Msg, msg->ToString ()), (Error, " no free chunks" ));
672
717
res->Status = NKikimrProto::OUT_OF_SPACE;
718
+ res->StatusFlags = GetStatusFlags () | ui32 (NKikimrBlobStorage::StatusNotEnoughDiskSpaceForOperation);
673
719
res->ErrorReason = " no free chunks" ;
674
720
} else {
675
721
PDISK_MOCK_LOG (DEBUG, PDM07, " received TEvChunkReserve" , (Msg, msg->ToString ()), (VDiskId, owner->VDiskId ));
676
722
for (ui32 i = 0 ; i < msg->SizeChunks ; ++i) {
677
723
res->ChunkIds .push_back (Impl.AllocateChunk (*owner));
678
724
}
725
+ res->StatusFlags = GetStatusFlags ();
679
726
PDISK_MOCK_LOG (DEBUG, PDM10, " sending TEvChunkReserveResult" , (Msg, res->ToString ()));
680
727
}
681
728
}
@@ -742,9 +789,11 @@ class TPDiskMockActor : public TActorBootstrapped<TPDiskMockActor> {
742
789
if (!msg->ChunkIdx ) { // allocate chunk
743
790
if (!Impl.GetNumFreeChunks ()) {
744
791
res->Status = NKikimrProto::OUT_OF_SPACE;
792
+ res->StatusFlags = GetStatusFlags () | ui32 (NKikimrBlobStorage::StatusNotEnoughDiskSpaceForOperation);
745
793
res->ErrorReason = " no free chunks" ;
746
794
} else {
747
795
msg->ChunkIdx = res->ChunkIdx = Impl.AllocateChunk (*owner);
796
+ res->StatusFlags = GetStatusFlags ();
748
797
}
749
798
}
750
799
if (msg->ChunkIdx ) {
@@ -848,7 +897,7 @@ class TPDiskMockActor : public TActorBootstrapped<TPDiskMockActor> {
848
897
auto res = std::make_unique<NPDisk::TEvCheckSpaceResult>(NKikimrProto::OK, GetStatusFlags (),
849
898
Impl.GetNumFreeChunks (), Impl.TotalChunks , Impl.TotalChunks - Impl.GetNumFreeChunks (),
850
899
Impl.Owners .size (), TString ());
851
- res->Occupancy = ( double )res-> UsedChunks / res-> TotalChunks ;
900
+ res->Occupancy = GetOccupancy () ;
852
901
Impl.FindOwner (msg, res); // to ensure correct owner/round
853
902
Send (ev->Sender , res.release ());
854
903
}
@@ -883,9 +932,16 @@ class TPDiskMockActor : public TActorBootstrapped<TPDiskMockActor> {
883
932
}
884
933
885
934
NPDisk::TStatusFlags GetStatusFlags () {
935
+ Impl.UpdateStatusFlags ();
886
936
return Impl.StatusFlags ;
887
937
}
888
938
939
+ double GetOccupancy () {
940
+ return (Impl.Occupancy == 0 )
941
+ ? ((double )(Impl.TotalChunks - Impl.GetNumFreeChunks ()) / Impl.TotalChunks )
942
+ : Impl.Occupancy ;
943
+ }
944
+
889
945
void ErrorHandle (NPDisk::TEvYardInit::TPtr &ev) {
890
946
Send (ev->Sender , new NPDisk::TEvYardInitResult (NKikimrProto::CORRUPTED, State->GetStateErrorReason ()));
891
947
}
0 commit comments