bool LookupCache::Anchor::factById()

in glean/rts/cache.cpp [160:201]


bool LookupCache::Anchor::factById(
    Id id,
    std::function<void(Pid, Fact::Clause)> f) {
  const auto cached = cache->index.withRLockPtr([&](auto rindex) {
    const auto i = rindex->ids.find(id);
    if (i != rindex->ids.end() && (*i)->tag() == FULL) {
      const auto fact = *i;
      // It is imporant to call f after we (i.e., touch) have released the read
      // lock (since f might use the cache). However, fact needs to exist until
      // after we've called f. Grabbing a read lock for delete_lock makes sure
      // no facts will be deleted until we're done.
      //
      // We might consider finer-grained locking if this becomes an issue.
      folly::SharedMutex::ReadHolder dont_delete(rindex->delete_lock);
      cache->touch(std::move(rindex), fact);
      f(fact->type(), fact->clause());
      return true;
    } else {
      return false;
    }
  });

  if (cached) {
    ++cache->stats->values[Stats::factById_hits];
    return true;
  }

  Fact::unique_ptr fact;
  base->factById(id, [&](auto type, auto clause) {
    fact = Fact::create({id, type, clause}, FULL);
  });
  if (fact) {
    ++cache->stats->values[Stats::factById_misses];
    f(fact->type(), fact->clause());
    // FIXME: probably do this before f
    cache->insert(std::move(fact));
    return true;
  } else {
    ++cache->stats->values[Stats::factById_failures];
    return false;
  }
}