in cachelib/allocator/Reaper-inl.h [44:116]
void Reaper<CacheT>::reapSlabWalkMode() {
util::Throttler t(throttlerConfig_);
const auto begin = util::getCurrentTimeMs();
auto currentTimeSec = util::getCurrentTimeSec();
// use a local to accumulate counts since the lambda could be executed
// millions of times per sec.
uint64_t visits = 0;
uint64_t reaps = 0;
// unlike the iterator mode, in this mode, we traverse all the way
ReaperAPIWrapper<CacheT>::traverseAndExpireItems(
cache_, [&](void* ptr, facebook::cachelib::AllocInfo allocInfo) -> bool {
XDCHECK(ptr);
// see if we need to stop the traversal and accumulate counts to
// global
if (visits++ == kCheckThreshold) {
numVisitedItems_.fetch_add(visits, std::memory_order_relaxed);
numReapedItems_.fetch_add(reaps, std::memory_order_relaxed);
visits = 0;
reaps = 0;
// abort the current iteration since we have to stop
if (shouldStopWork()) {
return false;
}
currentTimeSec = util::getCurrentTimeSec();
}
// if we throttle, then we should check for stop condition after
// the throttler has actually throttled us.
if (t.throttle() && shouldStopWork()) {
return false;
}
// get an item and check if it is expired and is in the access
// container before we actually grab the
// handle to the item and proceed to expire it.
const auto& item = *reinterpret_cast<const Item*>(ptr);
if (!item.isExpired(currentTimeSec) || !item.isAccessible()) {
return true;
}
// Item has to be smaller than the alloc size to be a valid item.
auto key = item.getKey();
if (Item::getRequiredSize(key, 0 /* value size*/) >
allocInfo.allocSize) {
return true;
}
try {
// obtain a valid handle without disturbing the state of the item in
// cache.
auto handle = cache_.peek(key);
auto reaped =
ReaperAPIWrapper<CacheT>::removeIfExpired(cache_, handle);
if (reaped) {
reaps++;
}
} catch (const std::exception& e) {
numErrs_.fetch_add(1, std::memory_order_relaxed);
XLOGF(DBG, "Error while reaping. Msg = {}", e.what());
}
return true;
});
// accumulate any left over visits, reaps.
numVisitedItems_.fetch_add(visits, std::memory_order_relaxed);
numReapedItems_.fetch_add(reaps, std::memory_order_relaxed);
auto end = util::getCurrentTimeMs();
traversalStats_.recordTraversalTime(end > begin ? end - begin : 0);
}