volatile_tier_impl.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright (c) 2013, 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. #include <atomic>
  8. #include <limits>
  9. #include <sstream>
  10. #include <string>
  11. #include <vector>
  12. #include "rocksdb/cache.h"
  13. #include "utilities/persistent_cache/hash_table.h"
  14. #include "utilities/persistent_cache/hash_table_evictable.h"
  15. #include "utilities/persistent_cache/persistent_cache_tier.h"
  16. // VolatileCacheTier
  17. //
  18. // This file provides persistent cache tier implementation for caching
  19. // key/values in RAM.
  20. //
  21. // key/values
  22. // |
  23. // V
  24. // +-------------------+
  25. // | VolatileCacheTier | Store in an evictable hash table
  26. // +-------------------+
  27. // |
  28. // V
  29. // on eviction
  30. // pushed to next tier
  31. //
  32. // The implementation is designed to be concurrent. The evictable hash table
  33. // implementation is not concurrent at this point though.
  34. //
  35. // The eviction algorithm is LRU
  36. namespace ROCKSDB_NAMESPACE {
  37. class VolatileCacheTier : public PersistentCacheTier {
  38. public:
  39. explicit VolatileCacheTier(
  40. const bool is_compressed = true,
  41. const size_t max_size = std::numeric_limits<size_t>::max())
  42. : is_compressed_(is_compressed), max_size_(max_size) {}
  43. virtual ~VolatileCacheTier();
  44. // insert to cache
  45. Status Insert(const Slice& page_key, const char* data,
  46. const size_t size) override;
  47. // lookup key in cache
  48. Status Lookup(const Slice& page_key, std::unique_ptr<char[]>* data,
  49. size_t* size) override;
  50. // is compressed cache ?
  51. bool IsCompressed() override { return is_compressed_; }
  52. // erase key from cache
  53. bool Erase(const Slice& key) override;
  54. std::string GetPrintableOptions() const override {
  55. return "VolatileCacheTier";
  56. }
  57. // Expose stats as map
  58. PersistentCache::StatsType Stats() override;
  59. private:
  60. //
  61. // Cache data abstraction
  62. //
  63. struct CacheData : LRUElement<CacheData> {
  64. explicit CacheData(CacheData&& rhs) noexcept
  65. : key(std::move(rhs.key)), value(std::move(rhs.value)) {}
  66. explicit CacheData(const std::string& _key, const std::string& _value = "")
  67. : key(_key), value(_value) {}
  68. virtual ~CacheData() {}
  69. const std::string key;
  70. const std::string value;
  71. };
  72. static void DeleteCacheData(CacheData* data);
  73. //
  74. // Index and LRU definition
  75. //
  76. struct CacheDataHash {
  77. uint64_t operator()(const CacheData* obj) const {
  78. assert(obj);
  79. return std::hash<std::string>()(obj->key);
  80. }
  81. };
  82. struct CacheDataEqual {
  83. bool operator()(const CacheData* lhs, const CacheData* rhs) const {
  84. assert(lhs);
  85. assert(rhs);
  86. return lhs->key == rhs->key;
  87. }
  88. };
  89. struct Statistics {
  90. std::atomic<uint64_t> cache_misses_{0};
  91. std::atomic<uint64_t> cache_hits_{0};
  92. std::atomic<uint64_t> cache_inserts_{0};
  93. std::atomic<uint64_t> cache_evicts_{0};
  94. double CacheHitPct() const {
  95. auto lookups = cache_hits_ + cache_misses_;
  96. return lookups ? 100 * cache_hits_ / static_cast<double>(lookups) : 0.0;
  97. }
  98. double CacheMissPct() const {
  99. auto lookups = cache_hits_ + cache_misses_;
  100. return lookups ? 100 * cache_misses_ / static_cast<double>(lookups) : 0.0;
  101. }
  102. };
  103. using IndexType =
  104. EvictableHashTable<CacheData, CacheDataHash, CacheDataEqual>;
  105. // Evict LRU tail
  106. bool Evict();
  107. const bool is_compressed_ = true; // does it store compressed data
  108. IndexType index_; // in-memory cache
  109. std::atomic<uint64_t> max_size_{0}; // Maximum size of the cache
  110. std::atomic<uint64_t> size_{0}; // Size of the cache
  111. Statistics stats_;
  112. };
  113. } // namespace ROCKSDB_NAMESPACE