@@ -428,10 +428,6 @@ void TDeviceList::MarkDeviceAllocated(const TDiskId& diskId, const TDeviceId& id
428428 AllocatedDevices.emplace (id, diskId);
429429}
430430
431- // returns a list of racks sorted by preference and then by occupied space ASC
432- // then by free space DESC
433- // the nodes in each rack are sorted by occupied space ASC then by free space
434- // DESC
435431auto TDeviceList::SelectRacks (
436432 const TAllocationQuery& query,
437433 const TString& poolName) const -> TVector<TRack>
@@ -446,7 +442,6 @@ auto TDeviceList::SelectRacks(
446442 auto & rack = racks[currentRack];
447443 rack.Id = currentRack;
448444 rack.Nodes .push_back ({nodeId, 0 , 0 });
449- rack.Preferred = query.PreferredRacks .contains (currentRack);
450445 };
451446
452447 if (!query.NodeIds .empty ()) {
@@ -486,59 +481,71 @@ auto TDeviceList::SelectRacks(
486481
487482 TVector<TRack> result;
488483 result.reserve (racks.size ());
489- for (auto & r: racks) {
490- result.push_back (std::move (r.second ));
484+ for (auto & [_, r]: racks) {
485+ if (r.FreeSpace ) {
486+ result.push_back (std::move (r));
487+ }
491488 }
492489
493490 return result;
494491}
495492
493+ // Returns a ranked list of nodes. Sorting is performed in stages:
494+ // - Sort racks by preference, occupied space, free space
495+ // - Sort nodes within each rack by occupied space, free space
496+ // - Optionally apply custom NodeRankingFunc to all nodes (if set in query)
496497auto TDeviceList::RankNodes (
497498 const TAllocationQuery& query,
498- TVector<TRack> racks) const -> TVector<TNodeInfo >
499+ TVector<TRack> racks) const -> TVector<TNodeId >
499500{
501+ // Sort racks by occupied space ASC then by free space DESC
500502 Sort (
501503 racks,
502- [](const TRack& l , const TRack& r )
504+ [](const TRack& lhs , const TRack& rhs )
503505 {
504- return std::tie (r. Preferred , l. OccupiedSpace , r .FreeSpace , l .Id ) <
505- std::tie (l. Preferred , r. OccupiedSpace , l .FreeSpace , r .Id );
506+ return std::tie (lhs. OccupiedSpace , rhs .FreeSpace , lhs .Id ) <
507+ std::tie (rhs. OccupiedSpace , lhs .FreeSpace , rhs .Id );
506508 });
507509
508- TVector<TNodeInfo> nodes;
510+ // Move preferred racks to the start of the list
511+ if (query.PreferredRacks ) {
512+ std::stable_partition (
513+ racks.begin (),
514+ racks.end (),
515+ [&](const TRack& rack)
516+ { return query.PreferredRacks .contains (rack.Id ); });
517+ }
518+
519+ TVector<TNodeId> nodeIds;
509520 {
510521 size_t size = 0 ;
511522 for (const auto & rack: racks) {
512523 size += rack.Nodes .size ();
513524 }
514- nodes .reserve (size);
525+ nodeIds .reserve (size);
515526 }
516527
517- for (auto & rack: racks) {
528+ for (TRack& rack: racks) {
529+ // Sort rack's nodes by occupied space ASC then by free space DESC
518530 Sort (
519531 rack.Nodes ,
520- [](const TNodeInfo& l , const TNodeInfo& r )
532+ [](const TNodeInfo& lhs , const TNodeInfo& rhs )
521533 {
522- return std::tie (l .OccupiedSpace , r .FreeSpace ) <
523- std::tie (r .OccupiedSpace , l .FreeSpace );
534+ return std::tie (lhs .OccupiedSpace , rhs .FreeSpace ) <
535+ std::tie (rhs .OccupiedSpace , lhs .FreeSpace );
524536 });
525537
526- nodes.insert (
527- nodes.end (),
528- std::make_move_iterator (rack.Nodes .begin ()),
529- std::make_move_iterator (rack.Nodes .end ()));
538+ for (const TNodeInfo& node: rack.Nodes ) {
539+ nodeIds.push_back (node.NodeId );
540+ }
530541 }
531542
532- if (query.DownrankedNodeIds ) {
533- // move downranked nodes to the end of the list
534- std::stable_partition (
535- nodes.begin (),
536- nodes.end (),
537- [&](const TNodeInfo& node)
538- { return !query.DownrankedNodeIds .contains (node.NodeId ); });
543+ // Get the final order of nodes
544+ if (query.NodeRankingFunc ) {
545+ query.NodeRankingFunc (nodeIds);
539546 }
540547
541- return nodes ;
548+ return nodeIds ;
542549}
543550
544551TVector<TDeviceList::TDeviceRange> TDeviceList::CollectDevices (
@@ -552,8 +559,8 @@ TVector<TDeviceList::TDeviceRange> TDeviceList::CollectDevices(
552559 TVector<TDeviceRange> ranges;
553560 ui64 totalSize = query.GetTotalByteCount ();
554561
555- for (const auto & node : RankNodes (query, SelectRacks (query, poolName))) {
556- const auto * nodeDevices = NodeDevices.FindPtr (node. NodeId );
562+ for (ui32 nodeId : RankNodes (query, SelectRacks (query, poolName))) {
563+ const auto * nodeDevices = NodeDevices.FindPtr (nodeId );
557564 Y_ABORT_UNLESS (nodeDevices);
558565
559566 // finding free devices belonging to this node that match our
@@ -615,7 +622,7 @@ TVector<TDeviceList::TDeviceRange> TDeviceList::CollectDevices(
615622 }
616623
617624 if (deviceInfo.Range .first != it) {
618- ranges.emplace_back (node. NodeId , deviceInfo.Range .first , it);
625+ ranges.emplace_back (nodeId , deviceInfo.Range .first , it);
619626 }
620627
621628 if (totalSize == 0 ) {
0 commit comments