RebalanceContext LruTailAgeStrategy::pickVictimAndReceiverImpl()

in cachelib/allocator/LruTailAgeStrategy.cpp [104:155]


RebalanceContext LruTailAgeStrategy::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 config = getConfigCopy();

  const auto poolStats = cache.getPoolStats(pid);
  const auto poolEvictionAgeStats =
      cache.getPoolEvictionAgeStats(pid, config.slabProjectionLength);

  RebalanceContext ctx;
  ctx.victimClassId = pickVictim(config, pid, poolStats, poolEvictionAgeStats);
  ctx.receiverClassId = pickReceiver(config, pid, poolStats, ctx.victimClassId,
                                     poolEvictionAgeStats);
  if (ctx.victimClassId == ctx.receiverClassId ||
      ctx.victimClassId == Slab::kInvalidClassId ||
      ctx.receiverClassId == Slab::kInvalidClassId) {
    return kNoOpContext;
  }

  if (!config.getWeight) {
    const auto victimProjectedTailAge =
        poolEvictionAgeStats.getProjectedAge(ctx.victimClassId);
    const auto receiverTailAge =
        poolEvictionAgeStats.getOldestElementAge(ctx.receiverClassId);

    XLOGF(DBG, "Rebalancing: receiver = {}, receiverTailAge = {}, victim = {}",
          static_cast<int>(ctx.receiverClassId), receiverTailAge,
          static_cast<int>(ctx.victimClassId));

    const auto improvement = victimProjectedTailAge - receiverTailAge;
    if (victimProjectedTailAge < receiverTailAge ||
        improvement < config.minTailAgeDifference ||
        improvement < config.tailAgeDifferenceRatio *
                          static_cast<long double>(victimProjectedTailAge)) {
      return kNoOpContext;
    }
  }

  // start a hold off so that the receiver does not become a victim soon
  // enough.
  getPoolState(pid).at(ctx.receiverClassId).startHoldOff();
  return ctx;
}