]>
git.proxmox.com Git - ceph.git/blob - ceph/src/kv/rocksdb_cache/ShardedCache.cc
1 // Copyright (c) 2018-Present Red Hat Inc. All rights reserved.
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
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.
10 #ifndef __STDC_FORMAT_MACROS
11 #define __STDC_FORMAT_MACROS
14 #include "ShardedCache.h"
18 namespace rocksdb_cache
{
20 ShardedCache::ShardedCache(size_t capacity
, int num_shard_bits
,
21 bool strict_capacity_limit
)
22 : num_shard_bits_(num_shard_bits
),
24 strict_capacity_limit_(strict_capacity_limit
),
27 void ShardedCache::SetCapacity(size_t capacity
) {
28 int num_shards
= 1 << num_shard_bits_
;
29 const size_t per_shard
= (capacity
+ (num_shards
- 1)) / num_shards
;
30 std::lock_guard
<std::mutex
> l(capacity_mutex_
);
31 for (int s
= 0; s
< num_shards
; s
++) {
32 GetShard(s
)->SetCapacity(per_shard
);
37 void ShardedCache::SetStrictCapacityLimit(bool strict_capacity_limit
) {
38 int num_shards
= 1 << num_shard_bits_
;
39 std::lock_guard
<std::mutex
> l(capacity_mutex_
);
40 for (int s
= 0; s
< num_shards
; s
++) {
41 GetShard(s
)->SetStrictCapacityLimit(strict_capacity_limit
);
43 strict_capacity_limit_
= strict_capacity_limit
;
46 rocksdb::Status
ShardedCache::Insert(const rocksdb::Slice
& key
, void* value
, size_t charge
,
48 rocksdb::Cache::Handle
** handle
, Priority priority
) {
49 uint32_t hash
= HashSlice(key
);
50 return GetShard(Shard(hash
))
51 ->Insert(key
, hash
, value
, charge
, deleter
, handle
, priority
);
54 rocksdb::Cache::Handle
* ShardedCache::Lookup(const rocksdb::Slice
& key
, rocksdb::Statistics
* /*stats*/) {
55 uint32_t hash
= HashSlice(key
);
56 return GetShard(Shard(hash
))->Lookup(key
, hash
);
59 bool ShardedCache::Ref(rocksdb::Cache::Handle
* handle
) {
60 uint32_t hash
= GetHash(handle
);
61 return GetShard(Shard(hash
))->Ref(handle
);
64 bool ShardedCache::Release(rocksdb::Cache::Handle
* handle
, bool force_erase
) {
65 uint32_t hash
= GetHash(handle
);
66 return GetShard(Shard(hash
))->Release(handle
, force_erase
);
69 void ShardedCache::Erase(const rocksdb::Slice
& key
) {
70 uint32_t hash
= HashSlice(key
);
71 GetShard(Shard(hash
))->Erase(key
, hash
);
74 uint64_t ShardedCache::NewId() {
75 return last_id_
.fetch_add(1, std::memory_order_relaxed
);
78 size_t ShardedCache::GetCapacity() const {
79 std::lock_guard
<std::mutex
> l(capacity_mutex_
);
83 bool ShardedCache::HasStrictCapacityLimit() const {
84 std::lock_guard
<std::mutex
> l(capacity_mutex_
);
85 return strict_capacity_limit_
;
88 size_t ShardedCache::GetUsage() const {
89 // We will not lock the cache when getting the usage from shards.
90 int num_shards
= 1 << num_shard_bits_
;
92 for (int s
= 0; s
< num_shards
; s
++) {
93 usage
+= GetShard(s
)->GetUsage();
98 size_t ShardedCache::GetUsage(rocksdb::Cache::Handle
* handle
) const {
99 return GetCharge(handle
);
102 size_t ShardedCache::GetPinnedUsage() const {
103 // We will not lock the cache when getting the usage from shards.
104 int num_shards
= 1 << num_shard_bits_
;
106 for (int s
= 0; s
< num_shards
; s
++) {
107 usage
+= GetShard(s
)->GetPinnedUsage();
112 #if (ROCKSDB_MAJOR >= 6 && ROCKSDB_MINOR >= 22)
113 DeleterFn
ShardedCache::GetDeleter(Handle
* handle
) const
115 uint32_t hash
= GetHash(handle
);
116 return GetShard(Shard(hash
))->GetDeleter(handle
);
119 void ShardedCache::ApplyToAllEntries(
120 const std::function
<void(const rocksdb::Slice
& key
, void* value
, size_t charge
,
121 DeleterFn deleter
)>& callback
,
122 const ApplyToAllEntriesOptions
& opts
)
124 int num_shards
= 1 << num_shard_bits_
;
125 for (int s
= 0; s
< num_shards
; s
++) {
126 GetShard(s
)->ApplyToAllCacheEntries(callback
, true /* thread_safe */);
130 void ShardedCache::ApplyToAllCacheEntries(void (*callback
)(void*, size_t),
132 int num_shards
= 1 << num_shard_bits_
;
133 for (int s
= 0; s
< num_shards
; s
++) {
134 GetShard(s
)->ApplyToAllCacheEntries(
135 [callback
](const rocksdb::Slice
&, void* value
, size_t charge
, DeleterFn
) {
136 callback(value
, charge
);
143 void ShardedCache::EraseUnRefEntries() {
144 int num_shards
= 1 << num_shard_bits_
;
145 for (int s
= 0; s
< num_shards
; s
++) {
146 GetShard(s
)->EraseUnRefEntries();
150 std::string
ShardedCache::GetPrintableOptions() const {
153 const int kBufferSize
= 200;
154 char buffer
[kBufferSize
];
156 std::lock_guard
<std::mutex
> l(capacity_mutex_
);
157 snprintf(buffer
, kBufferSize
, " capacity : %zu\n",
160 snprintf(buffer
, kBufferSize
, " num_shard_bits : %d\n", num_shard_bits_
);
162 snprintf(buffer
, kBufferSize
, " strict_capacity_limit : %d\n",
163 strict_capacity_limit_
);
166 ret
.append(GetShard(0)->GetPrintableOptions());
169 int GetDefaultCacheShardBits(size_t capacity
) {
170 int num_shard_bits
= 0;
171 size_t min_shard_size
= 512L * 1024L; // Every shard is at least 512KB.
172 size_t num_shards
= capacity
/ min_shard_size
;
173 while (num_shards
>>= 1) {
174 if (++num_shard_bits
>= 6) {
176 return num_shard_bits
;
179 return num_shard_bits
;
182 } // namespace rocksdb_cache