/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 |