@@ -450,24 +450,25 @@ namespace NKikimr {
450
450
State.CheckConsistency ();
451
451
}
452
452
453
- private:
453
+ private:
454
454
template <typename T>
455
455
std::invoke_result_t <T, TGroupGeometryInfo&, TGroupMapper&, TGroupId, TGroupMapper::TGroupDefinition&, TGroupMapper::TGroupConstraintsDefinition&,
456
456
const THashMap<TVDiskIdShort, TPDiskId>&, TGroupMapper::TForbiddenPDisks, i64 > AllocateOrSanitizeGroup (
457
457
TGroupId groupId, TGroupMapper::TGroupDefinition& group, TGroupMapper::TGroupConstraintsDefinition& constraints,
458
458
const THashMap<TVDiskIdShort, TPDiskId>& replacedDisks, TGroupMapper::TForbiddenPDisks forbid,
459
459
i64 requiredSpace, bool addExistingDisks, T&& func) {
460
460
if (!Mapper) {
461
- Mapper.emplace (Geometry, StoragePool.RandomizeGroupMapping );
461
+ Mapper.emplace (Geometry, StoragePool.RandomizeGroupMapping , State. Fit . PreferLessOccupiedRack , State. Fit . WithAttentionToReplication );
462
462
PopulateGroupMapper ();
463
463
}
464
+ TPDiskSlotTracker& pdiskSlotTracker= Mapper->GetPDiskSlotTracker ();
464
465
TStackVec<TPDiskId, 32 > removeQ;
465
466
if (addExistingDisks) {
466
467
for (const auto & realm : group) {
467
468
for (const auto & domain : realm) {
468
469
for (const TPDiskId id : domain) {
469
470
if (id != TPDiskId ()) {
470
- if (auto *info = State.PDisks .Find (id); info && RegisterPDisk (id, *info, false , " X" )) {
471
+ if (auto *info = State.PDisks .Find (id); info && RegisterPDisk (id, *info, false , pdiskSlotTracker, " X" )) {
471
472
removeQ.push_back (id);
472
473
}
473
474
}
@@ -476,14 +477,14 @@ namespace NKikimr {
476
477
}
477
478
}
478
479
struct TUnregister {
479
- TGroupMapper& Mapper ;
480
+ TBlobStorageController::TGroupFitter& Self ;
480
481
TStackVec<TPDiskId, 32 >& RemoveQ;
481
482
~TUnregister () {
482
483
for (const TPDiskId pdiskId : RemoveQ) {
483
- Mapper .UnregisterPDisk (pdiskId);
484
+ Self .UnregisterPDisk (pdiskId);
484
485
}
485
486
}
486
- } unregister{*Mapper , removeQ};
487
+ } unregister{*this , removeQ};
487
488
return std::invoke (func, Geometry, *Mapper, groupId, group, constraints, replacedDisks, std::move (forbid), requiredSpace);
488
489
}
489
490
@@ -500,6 +501,22 @@ namespace NKikimr {
500
501
void PopulateGroupMapper () {
501
502
const TBoxId boxId = std::get<0 >(StoragePoolId);
502
503
504
+ TPDiskSlotTracker pdiskSlotTracker;
505
+
506
+ bool populateSlotTracker = State.Fit .PreferLessOccupiedRack || State.Fit .WithAttentionToReplication ;
507
+
508
+ if (populateSlotTracker) {
509
+ State.VSlots .ForEach ([&](const TVSlotId& id, const TVSlotInfo& info) {
510
+ if (info.IsBeingDeleted ()) {
511
+ return ; // ignore slots being deleted
512
+ }
513
+ if (info.GetStatus () == NKikimrBlobStorage::EVDiskStatus::REPLICATING) {
514
+ TPDiskId pdiskId = id.ComprisingPDiskId ();
515
+ pdiskSlotTracker.AddReplicatingVSlot (pdiskId);
516
+ }
517
+ });
518
+ }
519
+
503
520
State.PDisks .ForEach ([&](const TPDiskId& id, const TPDiskInfo& info) {
504
521
if (info.BoxId != boxId) {
505
522
return ; // ignore disks not from desired box
@@ -511,15 +528,17 @@ namespace NKikimr {
511
528
512
529
for (const auto & filter : StoragePool.PDiskFilters ) {
513
530
if (filter.MatchPDisk (info)) {
514
- const bool inserted = RegisterPDisk (id, info, true );
531
+ const bool inserted = RegisterPDisk (id, info, true , pdiskSlotTracker );
515
532
Y_ABORT_UNLESS (inserted);
516
533
break ;
517
534
}
518
535
}
519
536
});
537
+
538
+ Mapper->SetPDiskSlotTracker (std::move (pdiskSlotTracker));
520
539
}
521
540
522
- bool RegisterPDisk (TPDiskId id, const TPDiskInfo& info, bool usable, TString whyUnusable = {}) {
541
+ bool RegisterPDisk (TPDiskId id, const TPDiskInfo& info, bool usable, TPDiskSlotTracker& pdiskSlotTracker, TString whyUnusable = {}) {
523
542
// calculate number of used slots on this PDisk, also counting the static ones
524
543
ui32 numSlots = info.NumActiveSlots + info.StaticSlotUsage ;
525
544
@@ -574,19 +593,42 @@ namespace NKikimr {
574
593
whyUnusable.append (' D' );
575
594
}
576
595
596
+ ui32 maxSlots = info.ExpectedSlotCount ;
597
+ auto location = State.HostRecords ->GetLocation (id.NodeId );
598
+
577
599
// register PDisk in the mapper
578
- return Mapper->RegisterPDisk ({
600
+ bool registered = Mapper->RegisterPDisk ({
579
601
.PDiskId = id,
580
- .Location = State. HostRecords -> GetLocation (id. NodeId ) ,
602
+ .Location = location ,
581
603
.Usable = usable,
582
604
.NumSlots = numSlots,
583
- .MaxSlots = info. ExpectedSlotCount ,
605
+ .MaxSlots = maxSlots ,
584
606
.Groups = std::move (groups),
585
607
.SpaceAvailable = availableSpace,
586
608
.Operational = info.Operational ,
587
609
.Decommitted = info.Decommitted (),
588
610
.WhyUnusable = std::move (whyUnusable),
589
611
});
612
+
613
+ bool populateSlotTracker = State.Fit .PreferLessOccupiedRack || State.Fit .WithAttentionToReplication ;
614
+
615
+ if (registered && populateSlotTracker) {
616
+ i32 freeSlots = i32 (maxSlots) - numSlots;
617
+ pdiskSlotTracker.AddFreeSlotsForRack (location.GetRackId (), freeSlots);
618
+ }
619
+
620
+ return registered;
621
+ }
622
+
623
+ void UnregisterPDisk (TPDiskId id) {
624
+ TGroupMapper::TPDiskRecord rec = Mapper->UnregisterPDisk (id);
625
+
626
+ bool populatedSlotTracker = State.Fit .PreferLessOccupiedRack || State.Fit .WithAttentionToReplication ;
627
+
628
+ if (populatedSlotTracker) {
629
+ i32 freeSlots = i32 (rec.MaxSlots ) - rec.NumSlots ;
630
+ Mapper->GetPDiskSlotTracker ().AddFreeSlotsForRack (rec.Location .GetRackId (), -freeSlots);
631
+ }
590
632
}
591
633
592
634
std::map<TVDiskIdShort, TVSlotInfo*> CreateVSlotsForGroup (TGroupInfo *groupInfo,
0 commit comments