void CacheShard::evict()

in velox/common/caching/AsyncDataCache.cpp [320:399]


void CacheShard::evict(uint64_t bytesToFree, bool evictAllUnpinned) {
  int64_t tinyFreed = 0;
  int64_t largeFreed = 0;
  int32_t evictSaveableSkipped = 0;
  auto ssdCache = cache_->ssdCache();
  bool skipSsdSaveable = ssdCache && ssdCache->writeInProgress();
  auto now = accessTime();
  std::vector<MappedMemory::Allocation> toFree;
  {
    std::lock_guard<std::mutex> l(mutex_);
    int size = entries_.size();
    if (!size) {
      return;
    }
    int32_t counter = 0;
    int32_t numChecked = 0;
    auto entryIndex = (clockHand_ % size);
    auto iter = entries_.begin() + entryIndex;
    while (++counter <= size) {
      if (++iter == entries_.end()) {
        iter = entries_.begin();
        entryIndex = 0;
      } else {
        ++entryIndex;
      }
      ++numEvictChecks_;
      auto candidate = iter->get();
      if (!candidate) {
        continue;
      }
      ++numChecked;
      ++clockHand_;
      if (evictionThreshold_ == kNoThreshold ||
          eventCounter_ > entries_.size() / 4 ||
          numChecked > entries_.size() / 8) {
        now = accessTime();
        calibrateThreshold();
        numChecked = 0;
        eventCounter_ = 0;
      }
      int32_t score = 0;
      if (candidate->numPins_ == 0 &&
          (!candidate->key_.fileNum.hasValue() || evictAllUnpinned ||
           (score = candidate->score(now)) >= evictionThreshold_)) {
        if (skipSsdSaveable && candidate->ssdSaveable_ && !evictAllUnpinned) {
          ++evictSaveableSkipped;
          continue;
        }
        largeFreed += candidate->data_.byteSize();
        toFree.push_back(std::move(candidate->data()));
        removeEntryLocked(candidate);
        freeEntries_.push_back(std::move(*iter));
        emptySlots_.push_back(entryIndex);
        tinyFreed += candidate->tinyData_.size();
        candidate->tinyData_.clear();
        candidate->size_ = 0;
        ++numEvict_;
        if (score) {
          sumEvictScore_ += score;
        }
        if (largeFreed + tinyFreed > bytesToFree) {
          break;
        }
      }
    }
  }
  ClockTimer t(allocClocks_);
  toFree.clear();
  cache_->incrementCachedPages(
      -largeFreed / static_cast<int32_t>(MappedMemory::kPageSize));
  if (evictSaveableSkipped && ssdCache && ssdCache->startWrite()) {
    // Rare. May occur if SSD is unusually slow. Useful for  diagnostics.
    LOG(INFO) << "SSDCA: Start save for old saveable, skipped "
              << cache_->numSkippedSaves();
    cache_->numSkippedSaves() = 0;
    cache_->saveToSsd();
  } else if (evictSaveableSkipped) {
    ++cache_->numSkippedSaves();
  }
}