PoolAdviseReclaimData MemoryPoolManager::calcNumSlabsToAdviseReclaim()

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;
}