in cachelib/allocator/memory/MemoryPoolManager.cpp [262:328]
PoolAdviseReclaimData MemoryPoolManager::calcNumSlabsToAdviseReclaim(
const std::set<PoolId>& poolIds) const {
folly::SharedMutex::WriteHolder l(lock_);
uint64_t totalSlabsAdvised = 0;
uint64_t totalSlabsInUse = 0;
std::unordered_map<PoolId, size_t> numSlabsInUse;
for (auto id : poolIds) {
// Get the individual pool slab usage and cache it so that any changes to
// it do not reflect in the subsequent calculations.
numSlabsInUse[id] = pools_[id]->getCurrentUsedSize() / Slab::kSize;
totalSlabsInUse += numSlabsInUse[id];
totalSlabsAdvised += pools_[id]->getNumSlabsAdvised();
}
PoolAdviseReclaimData results;
results.advise = false;
// No slabs in use or no slabs advised and no slabs to advise return empty map
if (totalSlabsInUse == 0 ||
(numSlabsToAdvise_ == 0 && totalSlabsAdvised == 0)) {
return results;
}
auto poolAdviseTargets =
getTargetSlabsToAdvise(poolIds, totalSlabsInUse, numSlabsInUse);
if (numSlabsToAdvise_ == totalSlabsAdvised) {
// No need to advise-away or reclaim any new slabs.
// Just rebalance the advised away slabs in each pool
for (auto& target : poolAdviseTargets) {
pools_[target.first]->setNumSlabsAdvised(target.second);
}
return results;
}
if (numSlabsToAdvise_ > totalSlabsAdvised) {
results.advise = true;
uint64_t diff = numSlabsToAdvise_ - totalSlabsAdvised;
for (auto id : poolIds) {
if (diff == 0) {
break;
}
uint64_t slabsToAdvise = poolAdviseTargets[id];
uint64_t currSlabsAdvised = pools_[id]->getNumSlabsAdvised();
if (slabsToAdvise <= currSlabsAdvised) {
continue;
}
uint64_t poolSlabsToAdvise =
std::min(slabsToAdvise - currSlabsAdvised, diff);
results.poolAdviseReclaimMap.emplace(id, poolSlabsToAdvise);
diff -= poolSlabsToAdvise;
}
} else {
uint64_t diff = totalSlabsAdvised - numSlabsToAdvise_;
for (auto id : poolIds) {
if (diff == 0) {
break;
}
auto slabsToAdvise = poolAdviseTargets[id];
auto currSlabsAdvised = pools_[id]->getNumSlabsAdvised();
if (slabsToAdvise >= currSlabsAdvised) {
continue;
}
uint64_t poolSlabsToReclaim =
std::min(currSlabsAdvised - slabsToAdvise, diff);
results.poolAdviseReclaimMap.emplace(id, poolSlabsToReclaim);
diff -= poolSlabsToReclaim;
}
}
return results;
}