Skip to content

Commit

Permalink
Implement a way to invoke a callback for a Cache handle
Browse files Browse the repository at this point in the history
  • Loading branch information
anand1976 committed Sep 3, 2024
1 parent 92ad4a8 commit 1d7ed05
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 0 deletions.
26 changes: 26 additions & 0 deletions cache/cache_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,32 @@ TEST_P(CacheTest, ApplyToAllEntriesDuringResize) {
ASSERT_EQ(special_count, kSpecialCount);
}

TEST_P(CacheTest, ApplyToHandleTest) {
std::string callback_state;
const auto callback = [&](const Slice& key, Cache::ObjectPtr value,
size_t charge,
const Cache::CacheItemHelper* helper) {
callback_state = std::to_string(DecodeKey(key)) + "," +
std::to_string(DecodeValue(value)) + "," +
std::to_string(charge);
assert(helper == &CacheTest::kHelper);
};

std::vector<std::string> inserted;

for (int i = 0; i < 10; ++i) {
Insert(i, i * 2, i + 1);
inserted.push_back(std::to_string(i) + "," + std::to_string(i * 2) + "," +
std::to_string(i + 1));
}
for (int i = 0; i < 10; ++i) {
Cache::Handle* handle = cache_->Lookup(EncodeKey(i));
cache_->ApplyToHandle(cache_.get(), handle, callback);
EXPECT_EQ(inserted[i], callback_state);
cache_->Release(handle);
}
}

TEST_P(CacheTest, DefaultShardBits) {
// Prevent excessive allocation (to save time & space)
estimated_value_size_ = 100000;
Expand Down
16 changes: 16 additions & 0 deletions cache/clock_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,22 @@ const Cache::CacheItemHelper* BaseHyperClockCache<Table>::GetCacheItemHelper(
return h->helper;
}

template <class Table>
void BaseHyperClockCache<Table>::ApplyToHandle(
Cache* cache, Handle* handle,
const std::function<void(const Slice& key, Cache::ObjectPtr value,
size_t charge, const CacheItemHelper* helper)>&
callback) {
BaseHyperClockCache<Table>* cache_ptr =
static_cast<BaseHyperClockCache<Table>*>(cache);
auto h = static_cast<const typename Table::HandleImpl*>(handle);
UniqueId64x2 unhashed;
auto hash_seed = cache_ptr->GetShard(h->GetHash()).GetTable().GetHashSeed();
callback(
ClockCacheShard<Table>::ReverseHash(h->hashed_key, &unhashed, hash_seed),
h->value, h->GetTotalCharge(), h->helper);
}

namespace {

// For each cache shard, estimate what the table load factor would be if
Expand Down
6 changes: 6 additions & 0 deletions cache/clock_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,12 @@ class BaseHyperClockCache : public ShardedCache<ClockCacheShard<Table>> {

const CacheItemHelper* GetCacheItemHelper(Handle* handle) const override;

void ApplyToHandle(
Cache* cache, Handle* handle,
const std::function<void(const Slice& key, Cache::ObjectPtr obj,
size_t charge, const CacheItemHelper* helper)>&
callback) override;

void ReportProblems(
const std::shared_ptr<Logger>& /*info_log*/) const override;
};
Expand Down
11 changes: 11 additions & 0 deletions cache/lru_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,17 @@ const Cache::CacheItemHelper* LRUCache::GetCacheItemHelper(
return h->helper;
}

void LRUCache::ApplyToHandle(
Cache* cache, Handle* handle,
const std::function<void(const Slice& key, ObjectPtr value, size_t charge,
const CacheItemHelper* helper)>& callback) {
auto cache_ptr = static_cast<LRUCache*>(cache);
auto h = static_cast<const LRUHandle*>(handle);
callback(h->key(), h->value,
h->GetCharge(cache_ptr->GetShard(0).metadata_charge_policy_),
h->helper);
}

size_t LRUCache::TEST_GetLRUSize() {
return SumOverShards([](LRUCacheShard& cs) { return cs.TEST_GetLRUSize(); });
}
Expand Down
6 changes: 6 additions & 0 deletions cache/lru_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,12 @@ class LRUCache
size_t GetCharge(Handle* handle) const override;
const CacheItemHelper* GetCacheItemHelper(Handle* handle) const override;

void ApplyToHandle(
Cache* cache, Handle* handle,
const std::function<void(const Slice& key, ObjectPtr obj, size_t charge,
const CacheItemHelper* helper)>& callback)
override;

// Retrieves number of elements in LRU, for unit test purpose only.
size_t TEST_GetLRUSize();
// Retrieves high pri pool ratio.
Expand Down
17 changes: 17 additions & 0 deletions include/rocksdb/advanced_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,14 @@ class Cache {
const CacheItemHelper* helper)>& callback,
const ApplyToAllEntriesOptions& opts) = 0;

// Apply a callback to a cache handle. The Cache must ensure the lifetime
// of the key passed to the callback is valid for the duration of the
// callback. The handle may not belong to the cache, but is guaranteed to
// be type compatible.
virtual void ApplyToHandle(
Cache* cache, Handle* handle,
const std::function<void(const Slice& key, ObjectPtr obj, size_t charge,
const CacheItemHelper* helper)>& callback) = 0;
// Remove all entries.
// Prerequisite: no entry is referenced.
virtual void EraseUnRefEntries() = 0;
Expand Down Expand Up @@ -636,6 +644,15 @@ class CacheWrapper : public Cache {
target_->ApplyToAllEntries(callback, opts);
}

virtual void ApplyToHandle(
Cache* cache, Handle* handle,
const std::function<void(const Slice& key, ObjectPtr obj, size_t charge,
const CacheItemHelper* helper)>& callback)
override {
auto cache_ptr = static_cast<CacheWrapper*>(cache);
target_->ApplyToHandle(cache_ptr->target_.get(), handle, callback);
}

void EraseUnRefEntries() override { target_->EraseUnRefEntries(); }

void StartAsyncLookup(AsyncLookupHandle& async_handle) override {
Expand Down

0 comments on commit 1d7ed05

Please sign in to comment.