in cachelib/allocator/HitsPerSlabStrategy.cpp [123:189]
RebalanceContext HitsPerSlabStrategy::pickVictimAndReceiverImpl(
const CacheBase& cache, PoolId pid) {
if (!cache.getPool(pid).allSlabsAllocated()) {
XLOGF(DBG,
"Pool Id: {}"
" does not have all its slabs allocated"
" and does not need rebalancing.",
static_cast<int>(pid));
return kNoOpContext;
}
const auto poolStats = cache.getPoolStats(pid);
const auto config = getConfigCopy();
RebalanceContext ctx;
ctx.victimClassId = pickVictim(config, cache, pid, poolStats);
ctx.receiverClassId = pickReceiver(config, pid, poolStats, ctx.victimClassId);
if (ctx.victimClassId == ctx.receiverClassId ||
ctx.victimClassId == Slab::kInvalidClassId ||
ctx.receiverClassId == Slab::kInvalidClassId) {
return kNoOpContext;
}
auto& poolState = getPoolState(pid);
double weightVictim = 1;
double weightReceiver = 1;
if (config.getWeight) {
weightReceiver = config.getWeight(pid, ctx.receiverClassId, poolStats);
weightVictim = config.getWeight(pid, ctx.victimClassId, poolStats);
}
const auto victimProjectedDeltaHitsPerSlab =
poolState.at(ctx.victimClassId).projectedDeltaHitsPerSlab(poolStats) *
weightVictim;
const auto receiverDeltaHitsPerSlab =
poolState.at(ctx.receiverClassId).deltaHitsPerSlab(poolStats) *
weightReceiver;
XLOGF(DBG,
"Rebalancing: receiver = {}, receiver delta hits per slab = {}, victim "
"= {}, victim projected delta hits per slab = {}",
static_cast<int>(ctx.receiverClassId), receiverDeltaHitsPerSlab,
static_cast<int>(ctx.victimClassId), victimProjectedDeltaHitsPerSlab);
const auto improvement =
receiverDeltaHitsPerSlab - victimProjectedDeltaHitsPerSlab;
if (receiverDeltaHitsPerSlab < victimProjectedDeltaHitsPerSlab ||
improvement < config.minDiff ||
improvement < config.diffRatio * static_cast<long double>(
victimProjectedDeltaHitsPerSlab)) {
XLOG(DBG, " Not enough to trigger slab rebalancing");
return kNoOpContext;
}
// start a hold off so that the receiver does not become a victim soon
// enough.
poolState.at(ctx.receiverClassId).startHoldOff();
// update all alloc classes' hits state to current hits so that next time we
// only look at the delta hits sicne the last rebalance.
for (const auto i : poolStats.getClassIds()) {
poolState[i].updateHits(poolStats);
}
return ctx;
}