# UNDF: UNDF-2026-000000026 diff --git a/src/osd/OSDMap.cc b/src/osd/OSDMap.cc --- a/src/osd/OSDMap.cc +++ b/src/osd/OSDMap.cc @@ -5818,6 +5818,8 @@ int OSDMap::calc_pg_upmaps( while (max--) { ldout(cct, 30) << "Top of loop #" << max+1 << dendl; // build overfull and underfull set overfull; set more_overfull; bool using_more_overfull = false; vector underfull; vector more_underfull; fill_overfull_underfull(cct, deviation_osd, max_deviation, overfull, more_overfull, underfull, more_underfull); + // Pre-build O(1) lookup sets — underfull/more_underfull are read-only in + // the scan loops below, so unordered_set avoids O(N×U) std::find calls. + std::unordered_set underfull_set(underfull.begin(), underfull.end()); + std::unordered_set more_underfull_set(more_underfull.begin(), more_underfull.end()); @@ -5979,8 +5981,7 @@ int OSDMap::calc_pg_upmaps( for (auto& [deviation, osd] : deviation_osd) { - if (std::find(underfull.begin(), underfull.end(), osd) == - underfull.end()) + if (underfull_set.find(osd) == underfull_set.end()) break; float target = osd_weight[osd] * pgs_per_weight; diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -4118,6 +4118,8 @@ int CrushWrapper::try_remap_rule( for (int pos = 0; pos < fanout; ++pos) { if (type > 0) { // non-leaf: no change } else { // leaf bool replaced = false; if (overfull.count(*i)) { + // Build orig_set once per leaf slot — O(1) membership below + std::unordered_set orig_set(orig.begin(), orig.end()); for (auto item : underfull) { if (used.count(item)) continue; if (!subtree_contains(from, item)) continue; - if (std::find(orig.begin(), orig.end(), item) != orig.end()) { + if (orig_set.count(item)) { ldout(cct, 20) << __func__ << " in orig " << orig << dendl; continue; } @@ -4152,8 +4154,6 @@ int CrushWrapper::try_remap_rule( if (!replaced) { for (auto item : more_underfull) { if (used.count(item)) continue; if (!subtree_contains(from, item)) continue; - if (std::find(orig.begin(), orig.end(), item) != orig.end()) { + if (orig_set.count(item)) { ldout(cct, 20) << __func__ << " in orig " << orig << dendl; continue; }