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
@@ -172,6 +213,7 @@ struct TPDiskMockState::TImpl {
172
213
for (const TChunkIdx chunkIdx : owner.ReservedChunks ) {
173
214
owner.ChunkData .erase (chunkIdx);
174
215
}
216
+
175
217
FreeChunks.merge (owner.ReservedChunks );
176
218
AdjustFreeChunks ();
177
219
}
@@ -286,8 +328,9 @@ struct TPDiskMockState::TImpl {
286
328
};
287
329
288
330
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))
331
+ NPDisk::EDeviceType deviceType, ESpaceColorPolicy spaceColorPolicy)
332
+ : TPDiskMockState(std::make_unique<TImpl>(nodeId, pdiskId, pdiskGuid, size, chunkSize, isDiskReadOnly, deviceType,
333
+ spaceColorPolicy))
291
334
{}
292
335
293
336
TPDiskMockState::TPDiskMockState (std::unique_ptr<TImpl>&& impl)
@@ -670,12 +713,14 @@ class TPDiskMockActor : public TActorBootstrapped<TPDiskMockActor> {
670
713
if (Impl.GetNumFreeChunks () < msg->SizeChunks ) {
671
714
PDISK_MOCK_LOG (NOTICE, PDM09, " received TEvChunkReserve" , (Msg, msg->ToString ()), (Error, " no free chunks" ));
672
715
res->Status = NKikimrProto::OUT_OF_SPACE;
716
+ res->StatusFlags = GetStatusFlags () | ui32 (NKikimrBlobStorage::StatusNotEnoughDiskSpaceForOperation);
673
717
res->ErrorReason = " no free chunks" ;
674
718
} else {
675
719
PDISK_MOCK_LOG (DEBUG, PDM07, " received TEvChunkReserve" , (Msg, msg->ToString ()), (VDiskId, owner->VDiskId ));
676
720
for (ui32 i = 0 ; i < msg->SizeChunks ; ++i) {
677
721
res->ChunkIds .push_back (Impl.AllocateChunk (*owner));
678
722
}
723
+ res->StatusFlags = GetStatusFlags ();
679
724
PDISK_MOCK_LOG (DEBUG, PDM10, " sending TEvChunkReserveResult" , (Msg, res->ToString ()));
680
725
}
681
726
}
@@ -742,9 +787,11 @@ class TPDiskMockActor : public TActorBootstrapped<TPDiskMockActor> {
742
787
if (!msg->ChunkIdx ) { // allocate chunk
743
788
if (!Impl.GetNumFreeChunks ()) {
744
789
res->Status = NKikimrProto::OUT_OF_SPACE;
790
+ res->StatusFlags = GetStatusFlags () | ui32 (NKikimrBlobStorage::StatusNotEnoughDiskSpaceForOperation);
745
791
res->ErrorReason = " no free chunks" ;
746
792
} else {
747
793
msg->ChunkIdx = res->ChunkIdx = Impl.AllocateChunk (*owner);
794
+ res->StatusFlags = GetStatusFlags ();
748
795
}
749
796
}
750
797
if (msg->ChunkIdx ) {
@@ -848,7 +895,7 @@ class TPDiskMockActor : public TActorBootstrapped<TPDiskMockActor> {
848
895
auto res = std::make_unique<NPDisk::TEvCheckSpaceResult>(NKikimrProto::OK, GetStatusFlags (),
849
896
Impl.GetNumFreeChunks (), Impl.TotalChunks , Impl.TotalChunks - Impl.GetNumFreeChunks (),
850
897
Impl.Owners .size (), TString ());
851
- res->Occupancy = ( double )res-> UsedChunks / res-> TotalChunks ;
898
+ res->Occupancy = GetOccupancy () ;
852
899
Impl.FindOwner (msg, res); // to ensure correct owner/round
853
900
Send (ev->Sender , res.release ());
854
901
}
@@ -883,9 +930,16 @@ class TPDiskMockActor : public TActorBootstrapped<TPDiskMockActor> {
883
930
}
884
931
885
932
NPDisk::TStatusFlags GetStatusFlags () {
933
+ Impl.UpdateStatusFlags ();
886
934
return Impl.StatusFlags ;
887
935
}
888
936
937
+ double GetOccupancy () {
938
+ return (Impl.Occupancy == 0 )
939
+ ? ((double )(Impl.TotalChunks - Impl.GetNumFreeChunks ()) / Impl.TotalChunks )
940
+ : Impl.Occupancy ;
941
+ }
942
+
889
943
void ErrorHandle (NPDisk::TEvYardInit::TPtr &ev) {
890
944
Send (ev->Sender , new NPDisk::TEvYardInitResult (NKikimrProto::CORRUPTED, State->GetStateErrorReason ()));
891
945
}
0 commit comments