]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/cache/sharded_cache.cc
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rocksdb / cache / sharded_cache.cc
CommitLineData
7c673cae 1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
11fdf7f2
TL
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).
7c673cae
FG
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 __STDC_FORMAT_MACROS
11#define __STDC_FORMAT_MACROS
12#endif
13
14#include "cache/sharded_cache.h"
15
16#include <string>
17
18#include "util/mutexlock.h"
19
20namespace rocksdb {
21
22ShardedCache::ShardedCache(size_t capacity, int num_shard_bits,
494da23a
TL
23 bool strict_capacity_limit,
24 std::shared_ptr<MemoryAllocator> allocator)
25 : Cache(std::move(allocator)),
26 num_shard_bits_(num_shard_bits),
7c673cae
FG
27 capacity_(capacity),
28 strict_capacity_limit_(strict_capacity_limit),
29 last_id_(1) {}
30
31void ShardedCache::SetCapacity(size_t capacity) {
32 int num_shards = 1 << num_shard_bits_;
33 const size_t per_shard = (capacity + (num_shards - 1)) / num_shards;
34 MutexLock l(&capacity_mutex_);
35 for (int s = 0; s < num_shards; s++) {
36 GetShard(s)->SetCapacity(per_shard);
37 }
38 capacity_ = capacity;
39}
40
41void ShardedCache::SetStrictCapacityLimit(bool strict_capacity_limit) {
42 int num_shards = 1 << num_shard_bits_;
43 MutexLock l(&capacity_mutex_);
44 for (int s = 0; s < num_shards; s++) {
45 GetShard(s)->SetStrictCapacityLimit(strict_capacity_limit);
46 }
47 strict_capacity_limit_ = strict_capacity_limit;
48}
49
50Status ShardedCache::Insert(const Slice& key, void* value, size_t charge,
51 void (*deleter)(const Slice& key, void* value),
52 Handle** handle, Priority priority) {
53 uint32_t hash = HashSlice(key);
54 return GetShard(Shard(hash))
55 ->Insert(key, hash, value, charge, deleter, handle, priority);
56}
57
11fdf7f2 58Cache::Handle* ShardedCache::Lookup(const Slice& key, Statistics* /*stats*/) {
7c673cae
FG
59 uint32_t hash = HashSlice(key);
60 return GetShard(Shard(hash))->Lookup(key, hash);
61}
62
63bool ShardedCache::Ref(Handle* handle) {
64 uint32_t hash = GetHash(handle);
65 return GetShard(Shard(hash))->Ref(handle);
66}
67
68bool ShardedCache::Release(Handle* handle, bool force_erase) {
69 uint32_t hash = GetHash(handle);
70 return GetShard(Shard(hash))->Release(handle, force_erase);
71}
72
73void ShardedCache::Erase(const Slice& key) {
74 uint32_t hash = HashSlice(key);
75 GetShard(Shard(hash))->Erase(key, hash);
76}
77
78uint64_t ShardedCache::NewId() {
79 return last_id_.fetch_add(1, std::memory_order_relaxed);
80}
81
82size_t ShardedCache::GetCapacity() const {
83 MutexLock l(&capacity_mutex_);
84 return capacity_;
85}
86
87bool ShardedCache::HasStrictCapacityLimit() const {
88 MutexLock l(&capacity_mutex_);
89 return strict_capacity_limit_;
90}
91
92size_t ShardedCache::GetUsage() const {
93 // We will not lock the cache when getting the usage from shards.
94 int num_shards = 1 << num_shard_bits_;
95 size_t usage = 0;
96 for (int s = 0; s < num_shards; s++) {
97 usage += GetShard(s)->GetUsage();
98 }
99 return usage;
100}
101
102size_t ShardedCache::GetUsage(Handle* handle) const {
103 return GetCharge(handle);
104}
105
106size_t ShardedCache::GetPinnedUsage() const {
107 // We will not lock the cache when getting the usage from shards.
108 int num_shards = 1 << num_shard_bits_;
109 size_t usage = 0;
110 for (int s = 0; s < num_shards; s++) {
111 usage += GetShard(s)->GetPinnedUsage();
112 }
113 return usage;
114}
115
116void ShardedCache::ApplyToAllCacheEntries(void (*callback)(void*, size_t),
117 bool thread_safe) {
118 int num_shards = 1 << num_shard_bits_;
119 for (int s = 0; s < num_shards; s++) {
120 GetShard(s)->ApplyToAllCacheEntries(callback, thread_safe);
121 }
122}
123
124void ShardedCache::EraseUnRefEntries() {
125 int num_shards = 1 << num_shard_bits_;
126 for (int s = 0; s < num_shards; s++) {
127 GetShard(s)->EraseUnRefEntries();
128 }
129}
130
131std::string ShardedCache::GetPrintableOptions() const {
132 std::string ret;
133 ret.reserve(20000);
134 const int kBufferSize = 200;
135 char buffer[kBufferSize];
136 {
137 MutexLock l(&capacity_mutex_);
138 snprintf(buffer, kBufferSize, " capacity : %" ROCKSDB_PRIszt "\n",
139 capacity_);
140 ret.append(buffer);
141 snprintf(buffer, kBufferSize, " num_shard_bits : %d\n", num_shard_bits_);
142 ret.append(buffer);
143 snprintf(buffer, kBufferSize, " strict_capacity_limit : %d\n",
144 strict_capacity_limit_);
145 ret.append(buffer);
146 }
494da23a
TL
147 snprintf(buffer, kBufferSize, " memory_allocator : %s\n",
148 memory_allocator() ? memory_allocator()->Name() : "None");
149 ret.append(buffer);
7c673cae
FG
150 ret.append(GetShard(0)->GetPrintableOptions());
151 return ret;
152}
153int GetDefaultCacheShardBits(size_t capacity) {
154 int num_shard_bits = 0;
155 size_t min_shard_size = 512L * 1024L; // Every shard is at least 512KB.
156 size_t num_shards = capacity / min_shard_size;
157 while (num_shards >>= 1) {
158 if (++num_shard_bits >= 6) {
159 // No more than 6.
160 return num_shard_bits;
161 }
162 }
163 return num_shard_bits;
164}
165
166} // namespace rocksdb