cache_helpers.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. #pragma once
  6. #include <cassert>
  7. #include "rocksdb/advanced_cache.h"
  8. #include "rocksdb/rocksdb_namespace.h"
  9. namespace ROCKSDB_NAMESPACE {
  10. // Returns the cached value given a cache handle.
  11. template <typename T>
  12. T* GetFromCacheHandle(Cache* cache, Cache::Handle* handle) {
  13. assert(cache);
  14. assert(handle);
  15. return static_cast<T*>(cache->Value(handle));
  16. }
  17. // Turns a T* into a Slice so it can be used as a key with Cache.
  18. template <typename T>
  19. Slice GetSliceForKey(const T* t) {
  20. return Slice(reinterpret_cast<const char*>(t), sizeof(T));
  21. }
  22. void ReleaseCacheHandleCleanup(void* arg1, void* arg2);
  23. // Generic resource management object for cache handles that releases the handle
  24. // when destroyed. Has unique ownership of the handle, so copying it is not
  25. // allowed, while moving it transfers ownership.
  26. template <typename T>
  27. class CacheHandleGuard {
  28. public:
  29. CacheHandleGuard() = default;
  30. CacheHandleGuard(Cache* cache, Cache::Handle* handle)
  31. : cache_(cache),
  32. handle_(handle),
  33. value_(GetFromCacheHandle<T>(cache, handle)) {
  34. assert(cache_ && handle_ && value_);
  35. }
  36. CacheHandleGuard(const CacheHandleGuard&) = delete;
  37. CacheHandleGuard& operator=(const CacheHandleGuard&) = delete;
  38. CacheHandleGuard(CacheHandleGuard&& rhs) noexcept
  39. : cache_(rhs.cache_), handle_(rhs.handle_), value_(rhs.value_) {
  40. assert((!cache_ && !handle_ && !value_) || (cache_ && handle_ && value_));
  41. rhs.ResetFields();
  42. }
  43. CacheHandleGuard& operator=(CacheHandleGuard&& rhs) noexcept {
  44. if (this == &rhs) {
  45. return *this;
  46. }
  47. ReleaseHandle();
  48. cache_ = rhs.cache_;
  49. handle_ = rhs.handle_;
  50. value_ = rhs.value_;
  51. assert((!cache_ && !handle_ && !value_) || (cache_ && handle_ && value_));
  52. rhs.ResetFields();
  53. return *this;
  54. }
  55. ~CacheHandleGuard() { ReleaseHandle(); }
  56. bool IsEmpty() const { return !handle_; }
  57. Cache* GetCache() const { return cache_; }
  58. Cache::Handle* GetCacheHandle() const { return handle_; }
  59. T* GetValue() const { return value_; }
  60. void TransferTo(Cleanable* cleanable) {
  61. if (cleanable) {
  62. if (handle_ != nullptr) {
  63. assert(cache_);
  64. cleanable->RegisterCleanup(&ReleaseCacheHandleCleanup, cache_, handle_);
  65. }
  66. }
  67. ResetFields();
  68. }
  69. void Reset() {
  70. ReleaseHandle();
  71. ResetFields();
  72. }
  73. private:
  74. void ReleaseHandle() {
  75. if (IsEmpty()) {
  76. return;
  77. }
  78. assert(cache_);
  79. cache_->Release(handle_);
  80. }
  81. void ResetFields() {
  82. cache_ = nullptr;
  83. handle_ = nullptr;
  84. value_ = nullptr;
  85. }
  86. private:
  87. Cache* cache_ = nullptr;
  88. Cache::Handle* handle_ = nullptr;
  89. T* value_ = nullptr;
  90. };
  91. // Build an aliasing shared_ptr that keeps `handle` in cache while there
  92. // are references, but the pointer is to the value for that cache entry,
  93. // which must be of type T. This is copyable, unlike CacheHandleGuard, but
  94. // does not provide access to caching details.
  95. template <typename T>
  96. std::shared_ptr<T> MakeSharedCacheHandleGuard(Cache* cache,
  97. Cache::Handle* handle) {
  98. auto wrapper = std::make_shared<CacheHandleGuard<T>>(cache, handle);
  99. return std::shared_ptr<T>(wrapper, GetFromCacheHandle<T>(cache, handle));
  100. }
  101. // Given the persistable data (saved) for a block cache entry, parse that
  102. // into a cache entry object and insert it into the given cache. The charge
  103. // of the new entry can be returned to the caller through `out_charge`.
  104. Status WarmInCache(Cache* cache, const Slice& key, const Slice& saved,
  105. Cache::CreateContext* create_context,
  106. const Cache::CacheItemHelper* helper,
  107. Cache::Priority priority = Cache::Priority::LOW,
  108. size_t* out_charge = nullptr);
  109. } // namespace ROCKSDB_NAMESPACE