]>
Commit | Line | Data |
---|---|---|
91327a77 AA |
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 "hash.h" | |
20 | ||
21 | #ifndef CACHE_LINE_SIZE | |
22 | #define CACHE_LINE_SIZE 64 // XXX arch-specific define | |
23 | #endif | |
24 | #define ROCKSDB_PRIszt "zu" | |
25 | ||
26 | namespace rocksdb_cache { | |
27 | ||
28 | // Single cache shard interface. | |
29 | class CacheShard { | |
30 | public: | |
31 | CacheShard() = default; | |
32 | virtual ~CacheShard() = default; | |
33 | ||
34 | virtual rocksdb::Status Insert(const rocksdb::Slice& key, uint32_t hash, void* value, | |
35 | size_t charge, | |
36 | void (*deleter)(const rocksdb::Slice& key, void* value), | |
37 | rocksdb::Cache::Handle** handle, rocksdb::Cache::Priority priority) = 0; | |
38 | virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key, uint32_t hash) = 0; | |
39 | virtual bool Ref(rocksdb::Cache::Handle* handle) = 0; | |
40 | virtual bool Release(rocksdb::Cache::Handle* handle, bool force_erase = false) = 0; | |
41 | virtual void Erase(const rocksdb::Slice& key, uint32_t hash) = 0; | |
42 | virtual void SetCapacity(size_t capacity) = 0; | |
43 | virtual void SetStrictCapacityLimit(bool strict_capacity_limit) = 0; | |
44 | virtual size_t GetUsage() const = 0; | |
45 | virtual size_t GetPinnedUsage() const = 0; | |
46 | virtual void ApplyToAllCacheEntries(void (*callback)(void*, size_t), | |
47 | bool thread_safe) = 0; | |
48 | virtual void EraseUnRefEntries() = 0; | |
49 | virtual std::string GetPrintableOptions() const { return ""; } | |
50 | }; | |
51 | ||
52 | // Generic cache interface which shards cache by hash of keys. 2^num_shard_bits | |
53 | // shards will be created, with capacity split evenly to each of the shards. | |
54 | // Keys are sharded by the highest num_shard_bits bits of hash value. | |
55 | class ShardedCache : public rocksdb::Cache { | |
56 | public: | |
57 | ShardedCache(size_t capacity, int num_shard_bits, bool strict_capacity_limit); | |
58 | virtual ~ShardedCache() = default; | |
59 | virtual const char* Name() const override = 0; | |
60 | virtual CacheShard* GetShard(int shard) = 0; | |
61 | virtual const CacheShard* GetShard(int shard) const = 0; | |
62 | virtual void* Value(Handle* handle) override = 0; | |
63 | virtual size_t GetCharge(Handle* handle) const = 0; | |
64 | virtual uint32_t GetHash(Handle* handle) const = 0; | |
65 | virtual void DisownData() override = 0; | |
66 | ||
67 | virtual void SetCapacity(size_t capacity) override; | |
68 | virtual void SetStrictCapacityLimit(bool strict_capacity_limit) override; | |
69 | ||
70 | virtual rocksdb::Status Insert(const rocksdb::Slice& key, void* value, size_t charge, | |
71 | void (*deleter)(const rocksdb::Slice& key, void* value), | |
72 | rocksdb::Cache::Handle** handle, Priority priority) override; | |
73 | virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key, rocksdb::Statistics* stats) override; | |
74 | virtual bool Ref(rocksdb::Cache::Handle* handle) override; | |
75 | virtual bool Release(rocksdb::Cache::Handle* handle, bool force_erase = false) override; | |
76 | virtual void Erase(const rocksdb::Slice& key) override; | |
77 | virtual uint64_t NewId() override; | |
78 | virtual size_t GetCapacity() const override; | |
79 | virtual bool HasStrictCapacityLimit() const override; | |
80 | virtual size_t GetUsage() const override; | |
81 | virtual size_t GetUsage(rocksdb::Cache::Handle* handle) const override; | |
82 | virtual size_t GetPinnedUsage() const override; | |
83 | virtual void ApplyToAllCacheEntries(void (*callback)(void*, size_t), | |
84 | bool thread_safe) override; | |
85 | virtual void EraseUnRefEntries() override; | |
86 | virtual std::string GetPrintableOptions() const override; | |
87 | ||
88 | int GetNumShardBits() const { return num_shard_bits_; } | |
89 | ||
90 | private: | |
91 | static inline uint32_t HashSlice(const rocksdb::Slice& s) { | |
92 | return ceph_str_hash(CEPH_STR_HASH_RJENKINS, s.data(), s.size()); | |
93 | // return Hash(s.data(), s.size(), 0); | |
94 | } | |
95 | ||
96 | uint32_t Shard(uint32_t hash) { | |
97 | // Note, hash >> 32 yields hash in gcc, not the zero we expect! | |
98 | return (num_shard_bits_ > 0) ? (hash >> (32 - num_shard_bits_)) : 0; | |
99 | } | |
100 | ||
101 | int num_shard_bits_; | |
102 | mutable std::mutex capacity_mutex_; | |
103 | size_t capacity_; | |
104 | bool strict_capacity_limit_; | |
105 | std::atomic<uint64_t> last_id_; | |
106 | }; | |
107 | ||
108 | extern int GetDefaultCacheShardBits(size_t capacity); | |
109 | ||
110 | } // namespace rocksdb_cache | |
111 | #endif // ROCKSDB_SHARDED_CACHE |