]> git.proxmox.com Git - ceph.git/blob - ceph/src/kv/rocksdb_cache/ShardedCache.h
4d64893ab1c7bc889d646f66ee84374e8626f1e5
[ceph.git] / ceph / src / kv / rocksdb_cache / ShardedCache.h
1 // Copyright (c) 2018-Present Red Hat Inc. All rights reserved.
2 //
3 // Copyright (c) 2011-2018, Facebook, Inc. All rights reserved.
4 // This source code is licensed under both the GPLv2 and Apache 2.0 License
5 //
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9
10 #ifndef ROCKSDB_SHARDED_CACHE
11 #define ROCKSDB_SHARDED_CACHE
12
13 #include <atomic>
14 #include <string>
15 #include <mutex>
16
17 #include "rocksdb/cache.h"
18 #include "include/ceph_hash.h"
19 #include "common/PriorityCache.h"
20 //#include "hash.h"
21
22 #ifndef CACHE_LINE_SIZE
23 #define CACHE_LINE_SIZE 64 // XXX arch-specific define
24 #endif
25 #define ROCKSDB_PRIszt "zu"
26
27 namespace rocksdb_cache {
28
29 // Single cache shard interface.
30 class CacheShard {
31 public:
32 CacheShard() = default;
33 virtual ~CacheShard() = default;
34
35 virtual rocksdb::Status Insert(const rocksdb::Slice& key, uint32_t hash, void* value,
36 size_t charge,
37 void (*deleter)(const rocksdb::Slice& key, void* value),
38 rocksdb::Cache::Handle** handle, rocksdb::Cache::Priority priority) = 0;
39 virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key, uint32_t hash) = 0;
40 virtual bool Ref(rocksdb::Cache::Handle* handle) = 0;
41 virtual bool Release(rocksdb::Cache::Handle* handle, bool force_erase = false) = 0;
42 virtual void Erase(const rocksdb::Slice& key, uint32_t hash) = 0;
43 virtual void SetCapacity(size_t capacity) = 0;
44 virtual void SetStrictCapacityLimit(bool strict_capacity_limit) = 0;
45 virtual size_t GetUsage() const = 0;
46 virtual size_t GetPinnedUsage() const = 0;
47 virtual void ApplyToAllCacheEntries(void (*callback)(void*, size_t),
48 bool thread_safe) = 0;
49 virtual void EraseUnRefEntries() = 0;
50 virtual std::string GetPrintableOptions() const { return ""; }
51 };
52
53 // Generic cache interface which shards cache by hash of keys. 2^num_shard_bits
54 // shards will be created, with capacity split evenly to each of the shards.
55 // Keys are sharded by the highest num_shard_bits bits of hash value.
56 class ShardedCache : public rocksdb::Cache, public PriorityCache::PriCache {
57 public:
58 ShardedCache(size_t capacity, int num_shard_bits, bool strict_capacity_limit);
59 virtual ~ShardedCache() = default;
60 virtual const char* Name() const override = 0;
61 virtual CacheShard* GetShard(int shard) = 0;
62 virtual const CacheShard* GetShard(int shard) const = 0;
63 virtual void* Value(Handle* handle) override = 0;
64 virtual size_t GetCharge(Handle* handle) const = 0;
65 virtual uint32_t GetHash(Handle* handle) const = 0;
66 virtual void DisownData() override = 0;
67
68 virtual void SetCapacity(size_t capacity) override;
69 virtual void SetStrictCapacityLimit(bool strict_capacity_limit) override;
70
71 virtual rocksdb::Status Insert(const rocksdb::Slice& key, void* value, size_t charge,
72 void (*deleter)(const rocksdb::Slice& key, void* value),
73 rocksdb::Cache::Handle** handle, Priority priority) override;
74 virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key, rocksdb::Statistics* stats) override;
75 virtual bool Ref(rocksdb::Cache::Handle* handle) override;
76 virtual bool Release(rocksdb::Cache::Handle* handle, bool force_erase = false) override;
77 virtual void Erase(const rocksdb::Slice& key) override;
78 virtual uint64_t NewId() override;
79 virtual size_t GetCapacity() const override;
80 virtual bool HasStrictCapacityLimit() const override;
81 virtual size_t GetUsage() const override;
82 virtual size_t GetUsage(rocksdb::Cache::Handle* handle) const override;
83 virtual size_t GetPinnedUsage() const override;
84 virtual void ApplyToAllCacheEntries(void (*callback)(void*, size_t),
85 bool thread_safe) override;
86 virtual void EraseUnRefEntries() override;
87 virtual std::string GetPrintableOptions() const override;
88
89 int GetNumShardBits() const { return num_shard_bits_; }
90
91 // PriCache
92 virtual int64_t get_cache_bytes(PriorityCache::Priority pri) const {
93 return cache_bytes[pri];
94 }
95 virtual int64_t get_cache_bytes() const {
96 int64_t total = 0;
97 for (int i = 0; i < PriorityCache::Priority::LAST + 1; i++) {
98 PriorityCache::Priority pri = static_cast<PriorityCache::Priority>(i);
99 total += get_cache_bytes(pri);
100 }
101 return total;
102 }
103 virtual void set_cache_bytes(PriorityCache::Priority pri, int64_t bytes) {
104 cache_bytes[pri] = bytes;
105 }
106 virtual void add_cache_bytes(PriorityCache::Priority pri, int64_t bytes) {
107 cache_bytes[pri] += bytes;
108 }
109 virtual double get_cache_ratio() const {
110 return cache_ratio;
111 }
112 virtual void set_cache_ratio(double ratio) {
113 cache_ratio = ratio;
114 }
115 virtual std::string get_cache_name() const = 0;
116
117 private:
118 static inline uint32_t HashSlice(const rocksdb::Slice& s) {
119 return ceph_str_hash(CEPH_STR_HASH_RJENKINS, s.data(), s.size());
120 // return Hash(s.data(), s.size(), 0);
121 }
122
123 uint32_t Shard(uint32_t hash) {
124 // Note, hash >> 32 yields hash in gcc, not the zero we expect!
125 return (num_shard_bits_ > 0) ? (hash >> (32 - num_shard_bits_)) : 0;
126 }
127
128 int64_t cache_bytes[PriorityCache::Priority::LAST+1] = {0};
129 double cache_ratio = 0;
130
131 int num_shard_bits_;
132 mutable std::mutex capacity_mutex_;
133 size_t capacity_;
134 bool strict_capacity_limit_;
135 std::atomic<uint64_t> last_id_;
136 };
137
138 extern int GetDefaultCacheShardBits(size_t capacity);
139
140 } // namespace rocksdb_cache
141 #endif // ROCKSDB_SHARDED_CACHE