Coverage Report

Created: 2026-08-14 08:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rocksdb/cache/cache_helpers.h
Line
Count
Source
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under both the GPLv2 (found in the
3
//  COPYING file in the root directory) and Apache 2.0 License
4
//  (found in the LICENSE.Apache file in the root directory).
5
6
#pragma once
7
8
#include <cassert>
9
10
#include "rocksdb/advanced_cache.h"
11
#include "rocksdb/rocksdb_namespace.h"
12
13
namespace ROCKSDB_NAMESPACE {
14
15
// Returns the cached value given a cache handle.
16
template <typename T>
17
214k
T* GetFromCacheHandle(Cache* cache, Cache::Handle* handle) {
18
214k
  assert(cache);
19
214k
  assert(handle);
20
214k
  return static_cast<T*>(cache->Value(handle));
21
214k
}
Unexecuted instantiation: rocksdb::BlobFileReader* rocksdb::GetFromCacheHandle<rocksdb::BlobFileReader>(rocksdb::Cache*, rocksdb::Cache::Handle*)
Unexecuted instantiation: rocksdb::BlobContents* rocksdb::GetFromCacheHandle<rocksdb::BlobContents>(rocksdb::Cache*, rocksdb::Cache::Handle*)
rocksdb::CacheEntryStatsCollector<rocksdb::InternalStats::CacheEntryRoleStats>* rocksdb::GetFromCacheHandle<rocksdb::CacheEntryStatsCollector<rocksdb::InternalStats::CacheEntryRoleStats> >(rocksdb::Cache*, rocksdb::Cache::Handle*)
Line
Count
Source
17
214k
T* GetFromCacheHandle(Cache* cache, Cache::Handle* handle) {
18
214k
  assert(cache);
19
  assert(handle);
20
214k
  return static_cast<T*>(cache->Value(handle));
21
214k
}
22
23
// Turns a T* into a Slice so it can be used as a key with Cache.
24
template <typename T>
25
0
Slice GetSliceForKey(const T* t) {
26
0
  return Slice(reinterpret_cast<const char*>(t), sizeof(T));
27
0
}
28
29
void ReleaseCacheHandleCleanup(void* arg1, void* arg2);
30
31
// Generic resource management object for cache handles that releases the handle
32
// when destroyed. Has unique ownership of the handle, so copying it is not
33
// allowed, while moving it transfers ownership.
34
template <typename T>
35
class CacheHandleGuard {
36
 public:
37
0
  CacheHandleGuard() = default;
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobFileReader>::CacheHandleGuard()
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobContents>::CacheHandleGuard()
38
39
  CacheHandleGuard(Cache* cache, Cache::Handle* handle)
40
107k
      : cache_(cache),
41
107k
        handle_(handle),
42
107k
        value_(GetFromCacheHandle<T>(cache, handle)) {
43
107k
    assert(cache_ && handle_ && value_);
44
107k
  }
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobFileReader>::CacheHandleGuard(rocksdb::Cache*, rocksdb::Cache::Handle*)
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobContents>::CacheHandleGuard(rocksdb::Cache*, rocksdb::Cache::Handle*)
rocksdb::CacheHandleGuard<rocksdb::CacheEntryStatsCollector<rocksdb::InternalStats::CacheEntryRoleStats> >::CacheHandleGuard(rocksdb::Cache*, rocksdb::Cache::Handle*)
Line
Count
Source
40
107k
      : cache_(cache),
41
107k
        handle_(handle),
42
107k
        value_(GetFromCacheHandle<T>(cache, handle)) {
43
    assert(cache_ && handle_ && value_);
44
107k
  }
45
46
  CacheHandleGuard(const CacheHandleGuard&) = delete;
47
  CacheHandleGuard& operator=(const CacheHandleGuard&) = delete;
48
49
  CacheHandleGuard(CacheHandleGuard&& rhs) noexcept
50
      : cache_(rhs.cache_), handle_(rhs.handle_), value_(rhs.value_) {
51
    assert((!cache_ && !handle_ && !value_) || (cache_ && handle_ && value_));
52
53
    rhs.ResetFields();
54
  }
55
56
0
  CacheHandleGuard& operator=(CacheHandleGuard&& rhs) noexcept {
57
0
    if (this == &rhs) {
58
0
      return *this;
59
0
    }
60
61
0
    ReleaseHandle();
62
63
0
    cache_ = rhs.cache_;
64
0
    handle_ = rhs.handle_;
65
0
    value_ = rhs.value_;
66
67
0
    assert((!cache_ && !handle_ && !value_) || (cache_ && handle_ && value_));
68
69
0
    rhs.ResetFields();
70
71
0
    return *this;
72
0
  }
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobFileReader>::operator=(rocksdb::CacheHandleGuard<rocksdb::BlobFileReader>&&)
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobContents>::operator=(rocksdb::CacheHandleGuard<rocksdb::BlobContents>&&)
73
74
107k
  ~CacheHandleGuard() { ReleaseHandle(); }
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobFileReader>::~CacheHandleGuard()
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobContents>::~CacheHandleGuard()
rocksdb::CacheHandleGuard<rocksdb::CacheEntryStatsCollector<rocksdb::InternalStats::CacheEntryRoleStats> >::~CacheHandleGuard()
Line
Count
Source
74
107k
  ~CacheHandleGuard() { ReleaseHandle(); }
75
76
107k
  bool IsEmpty() const { return !handle_; }
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobFileReader>::IsEmpty() const
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobContents>::IsEmpty() const
rocksdb::CacheHandleGuard<rocksdb::CacheEntryStatsCollector<rocksdb::InternalStats::CacheEntryRoleStats> >::IsEmpty() const
Line
Count
Source
76
107k
  bool IsEmpty() const { return !handle_; }
77
78
0
  Cache* GetCache() const { return cache_; }
79
0
  Cache::Handle* GetCacheHandle() const { return handle_; }
80
0
  T* GetValue() const { return value_; }
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobContents>::GetValue() const
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobFileReader>::GetValue() const
81
82
0
  void TransferTo(Cleanable* cleanable) {
83
0
    if (cleanable) {
84
0
      if (handle_ != nullptr) {
85
0
        assert(cache_);
86
0
        cleanable->RegisterCleanup(&ReleaseCacheHandleCleanup, cache_, handle_);
87
0
      }
88
0
    }
89
0
    ResetFields();
90
0
  }
91
92
0
  void Reset() {
93
0
    ReleaseHandle();
94
0
    ResetFields();
95
0
  }
96
97
 private:
98
107k
  void ReleaseHandle() {
99
107k
    if (IsEmpty()) {
100
0
      return;
101
0
    }
102
103
107k
    assert(cache_);
104
107k
    cache_->Release(handle_);
105
107k
  }
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobFileReader>::ReleaseHandle()
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobContents>::ReleaseHandle()
rocksdb::CacheHandleGuard<rocksdb::CacheEntryStatsCollector<rocksdb::InternalStats::CacheEntryRoleStats> >::ReleaseHandle()
Line
Count
Source
98
107k
  void ReleaseHandle() {
99
107k
    if (IsEmpty()) {
100
0
      return;
101
0
    }
102
103
107k
    assert(cache_);
104
107k
    cache_->Release(handle_);
105
107k
  }
106
107
0
  void ResetFields() {
108
0
    cache_ = nullptr;
109
0
    handle_ = nullptr;
110
0
    value_ = nullptr;
111
0
  }
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobFileReader>::ResetFields()
Unexecuted instantiation: rocksdb::CacheHandleGuard<rocksdb::BlobContents>::ResetFields()
112
113
 private:
114
  Cache* cache_ = nullptr;
115
  Cache::Handle* handle_ = nullptr;
116
  T* value_ = nullptr;
117
};
118
119
// Build an aliasing shared_ptr that keeps `handle` in cache while there
120
// are references, but the pointer is to the value for that cache entry,
121
// which must be of type T. This is copyable, unlike CacheHandleGuard, but
122
// does not provide access to caching details.
123
template <typename T>
124
std::shared_ptr<T> MakeSharedCacheHandleGuard(Cache* cache,
125
107k
                                              Cache::Handle* handle) {
126
107k
  auto wrapper = std::make_shared<CacheHandleGuard<T>>(cache, handle);
127
107k
  return std::shared_ptr<T>(wrapper, GetFromCacheHandle<T>(cache, handle));
128
107k
}
129
130
// Given the persistable data (saved) for a block cache entry, parse that
131
// into a cache entry object and insert it into the given cache. The charge
132
// of the new entry can be returned to the caller through `out_charge`.
133
Status WarmInCache(Cache* cache, const Slice& key, const Slice& saved,
134
                   Cache::CreateContext* create_context,
135
                   const Cache::CacheItemHelper* helper,
136
                   Cache::Priority priority = Cache::Priority::LOW,
137
                   size_t* out_charge = nullptr);
138
139
}  // namespace ROCKSDB_NAMESPACE