@@ -138,7 +138,7 @@ namespace NKikimr {
138
138
Y_VERIFY_S (chunkId, VDiskLogPrefix << " chunkId# " << chunkId);
139
139
TFreeSpace::iterator it;
140
140
141
- auto freeFoundSlot = [&] (TFreeSpace &container, const char *containerName) {
141
+ auto freeFoundSlot = [&] (TFreeSpace &container, const char *containerName, bool inLockedChunks ) {
142
142
TMask &mask = it->second ;
143
143
Y_VERIFY_S (!mask.Get (slotId), VDiskLogPrefix << " TChain::Free: containerName# " << containerName
144
144
<< " id# " << id.ToString () << " State# " << ToString ());
@@ -148,15 +148,15 @@ namespace NKikimr {
148
148
// free chunk
149
149
container.erase (it);
150
150
FreeSlotsInFreeSpace -= SlotsInChunk;
151
- return TFreeRes (chunkId, ConstMask, SlotsInChunk);
151
+ return TFreeRes (chunkId, ConstMask, SlotsInChunk, inLockedChunks );
152
152
} else
153
- return TFreeRes (0 , mask, SlotsInChunk);
153
+ return TFreeRes (0 , mask, SlotsInChunk, false );
154
154
};
155
155
156
156
if ((it = FreeSpace.find (chunkId)) != FreeSpace.end ()) {
157
- return freeFoundSlot (FreeSpace, " FreeSpace" );
157
+ return freeFoundSlot (FreeSpace, " FreeSpace" , false );
158
158
} else if ((it = LockedChunks.find (chunkId)) != LockedChunks.end ()) {
159
- return freeFoundSlot (LockedChunks, " LockedChunks" );
159
+ return freeFoundSlot (LockedChunks, " LockedChunks" , true );
160
160
} else {
161
161
// chunk is neither in FreeSpace nor in LockedChunks
162
162
TDynBitMap mask;
@@ -166,13 +166,13 @@ namespace NKikimr {
166
166
++FreeSlotsInFreeSpace;
167
167
168
168
FreeSpace.emplace (chunkId, mask);
169
- return TFreeRes (0 , mask, SlotsInChunk); // no empty chunk
169
+ return TFreeRes (0 , mask, SlotsInChunk, false ); // no empty chunk
170
170
}
171
171
}
172
172
173
173
bool TChain::LockChunkForAllocation (TChunkID chunkId) {
174
- if (TFreeSpace::iterator it = FreeSpace.find (chunkId); it != FreeSpace. end ( )) {
175
- LockedChunks.insert (FreeSpace. extract (it ));
174
+ if (auto nh = FreeSpace.extract (chunkId)) {
175
+ LockedChunks.insert (std::move (nh ));
176
176
return true ;
177
177
} else {
178
178
// chunk is already freed
@@ -181,8 +181,8 @@ namespace NKikimr {
181
181
}
182
182
183
183
void TChain::UnlockChunk (TChunkID chunkId) {
184
- if (auto it = LockedChunks.find (chunkId); it != LockedChunks. end ( )) {
185
- FreeSpace.insert (LockedChunks. extract (it ));
184
+ if (auto nh = LockedChunks.extract (chunkId)) {
185
+ FreeSpace.insert (std::move (nh ));
186
186
}
187
187
}
188
188
@@ -211,15 +211,20 @@ namespace NKikimr {
211
211
ui32 chunkId = id.GetChunkId ();
212
212
ui32 slotId = id.GetSlotId ();
213
213
214
- TFreeSpace::iterator it = FreeSpace.find (chunkId);
215
- if (it != FreeSpace.end ()) {
214
+ TFreeSpace *map = &FreeSpace;
215
+ TFreeSpace::iterator it = map->find (chunkId);
216
+ if (it == map->end ()) {
217
+ map = &LockedChunks;
218
+ it = map->find (chunkId);
219
+ }
220
+ if (it != map->end ()) {
216
221
TMask &mask = it->second ;
217
222
Y_VERIFY_S (mask.Get (slotId), VDiskLogPrefix << " RecoveryModeAllocate:"
218
223
<< " id# " << id.ToString () << " State# " << ToString ());
219
224
mask.Reset (slotId);
220
225
221
226
if (mask.Empty ()) {
222
- FreeSpace. erase (it);
227
+ map-> erase (it);
223
228
}
224
229
225
230
--FreeSlotsInFreeSpace;
@@ -230,11 +235,11 @@ namespace NKikimr {
230
235
}
231
236
}
232
237
233
- void TChain::RecoveryModeAllocate (const NPrivate::TChunkSlot &id, TChunkID chunkId) {
234
- Y_VERIFY_S (id.GetChunkId () == chunkId && FreeSpace.find (chunkId) == FreeSpace. end ( ),
238
+ void TChain::RecoveryModeAllocate (const NPrivate::TChunkSlot &id, TChunkID chunkId, bool inLockedChunks ) {
239
+ Y_VERIFY_S (id.GetChunkId () == chunkId && ! FreeSpace.contains (chunkId) && !LockedChunks. contains (chunkId ),
235
240
VDiskLogPrefix << " id# " << id.ToString () << " chunkId# " << chunkId << " State# " << ToString ());
236
241
237
- FreeSpace.emplace (chunkId, ConstMask);
242
+ (inLockedChunks ? LockedChunks : FreeSpace) .emplace (chunkId, ConstMask);
238
243
FreeSlotsInFreeSpace += SlotsInChunk;
239
244
bool res = RecoveryModeAllocate (id);
240
245
@@ -358,6 +363,10 @@ namespace NKikimr {
358
363
return NPrivate::TChunkSlot (addr.ChunkIdx , slotId);
359
364
}
360
365
366
+ NPrivate::TChunkSlot TChainDelegator::Convert (const THugeSlot &slot) const {
367
+ return Convert (slot.GetDiskPart ());
368
+ }
369
+
361
370
void TChainDelegator::Save (IOutputStream *s) const {
362
371
::Save (s, *ChainPtr);
363
372
}
@@ -791,7 +800,7 @@ namespace NKikimr {
791
800
TFreeChunks::iterator it = FreeChunks.find (chunkId);
792
801
Y_VERIFY_S (it != FreeChunks.end (), VDiskLogPrefix << " addr# " << addr.ToString () << " State# " << ToString ());
793
802
FreeChunks.erase (it);
794
- chainD->ChainPtr ->RecoveryModeAllocate (id, chunkId);
803
+ chainD->ChainPtr ->RecoveryModeAllocate (id, chunkId, false );
795
804
}
796
805
}
797
806
@@ -807,6 +816,26 @@ namespace NKikimr {
807
816
}
808
817
}
809
818
819
+ bool THeap::ReleaseSlot (THugeSlot slot) {
820
+ TChainDelegator* const chain = Chains.GetChain (slot.GetSize ());
821
+ Y_VERIFY_S (chain, VDiskLogPrefix << " State# " << ToString () << " slot# " << slot.ToString ());
822
+ if (TFreeRes res = chain->ChainPtr ->Free (chain->Convert (slot)); res.ChunkId ) {
823
+ PutChunkIdToFreeChunks (res.ChunkId );
824
+ return res.InLockedChunks ;
825
+ }
826
+ return false ;
827
+ }
828
+
829
+ void THeap::OccupySlot (THugeSlot slot, bool inLockedChunks) {
830
+ TChainDelegator* const chain = Chains.GetChain (slot.GetSize ());
831
+ Y_VERIFY_S (chain, VDiskLogPrefix << " State# " << ToString () << " slot# " << slot.ToString ());
832
+ if (!chain->ChainPtr ->RecoveryModeAllocate (chain->Convert (slot))) {
833
+ const size_t numErased = FreeChunks.erase (slot.GetChunkId ());
834
+ Y_VERIFY_S (numErased, VDiskLogPrefix << " State# " << ToString () << " slot# " << slot.ToString ());
835
+ chain->ChainPtr ->RecoveryModeAllocate (chain->Convert (slot), slot.GetChunkId (), inLockedChunks);
836
+ }
837
+ }
838
+
810
839
// ////////////////////////////////////////////////////////////////////////////////////////
811
840
// THeap: Serialize/Parse/Check
812
841
// ////////////////////////////////////////////////////////////////////////////////////////
0 commit comments