From e6918187568dbd01842d8d1d2c808ce16a894239 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 21 Apr 2024 13:54:28 +0200 Subject: Adding upstream version 18.2.2. Signed-off-by: Daniel Baumann --- src/kv/rocksdb_cache/ShardedCache.h | 197 ++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 src/kv/rocksdb_cache/ShardedCache.h (limited to 'src/kv/rocksdb_cache/ShardedCache.h') diff --git a/src/kv/rocksdb_cache/ShardedCache.h b/src/kv/rocksdb_cache/ShardedCache.h new file mode 100644 index 000000000..ef4b10d8f --- /dev/null +++ b/src/kv/rocksdb_cache/ShardedCache.h @@ -0,0 +1,197 @@ +// Copyright (c) 2018-Present Red Hat Inc. All rights reserved. +// +// Copyright (c) 2011-2018, Facebook, Inc. All rights reserved. +// This source code is licensed under both the GPLv2 and Apache 2.0 License +// +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef ROCKSDB_SHARDED_CACHE +#define ROCKSDB_SHARDED_CACHE + +#include +#include +#include + +#include "rocksdb/version.h" +#include "rocksdb/cache.h" +#include "include/ceph_hash.h" +#include "common/PriorityCache.h" +//#include "hash.h" + +#ifndef CACHE_LINE_SIZE +#define CACHE_LINE_SIZE 64 // XXX arch-specific define +#endif + +namespace rocksdb_cache { + +using DeleterFn = void (*)(const rocksdb::Slice& key, void* value); + +// Single cache shard interface. +class CacheShard { + public: + CacheShard() = default; + virtual ~CacheShard() = default; + + virtual rocksdb::Status Insert(const rocksdb::Slice& key, uint32_t hash, void* value, + size_t charge, + DeleterFn deleter, + rocksdb::Cache::Handle** handle, rocksdb::Cache::Priority priority) = 0; + virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key, uint32_t hash) = 0; + virtual bool Ref(rocksdb::Cache::Handle* handle) = 0; + virtual bool Release(rocksdb::Cache::Handle* handle, bool force_erase = false) = 0; + virtual void Erase(const rocksdb::Slice& key, uint32_t hash) = 0; + virtual void SetCapacity(size_t capacity) = 0; + virtual void SetStrictCapacityLimit(bool strict_capacity_limit) = 0; + virtual size_t GetUsage() const = 0; + virtual size_t GetPinnedUsage() const = 0; + virtual void ApplyToAllCacheEntries( + const std::function& callback, + bool thread_safe) = 0; + virtual void EraseUnRefEntries() = 0; + virtual std::string GetPrintableOptions() const { return ""; } + virtual DeleterFn GetDeleter(rocksdb::Cache::Handle* handle) const = 0; +}; + +// Generic cache interface which shards cache by hash of keys. 2^num_shard_bits +// shards will be created, with capacity split evenly to each of the shards. +// Keys are sharded by the highest num_shard_bits bits of hash value. +class ShardedCache : public rocksdb::Cache, public PriorityCache::PriCache { + public: + ShardedCache(size_t capacity, int num_shard_bits, bool strict_capacity_limit); + virtual ~ShardedCache() = default; + // rocksdb::Cache + virtual const char* Name() const override = 0; + virtual rocksdb::Status Insert(const rocksdb::Slice& key, void* value, size_t charge, + DeleterFn, + rocksdb::Cache::Handle** handle, Priority priority) override; + virtual rocksdb::Cache::Handle* Lookup(const rocksdb::Slice& key, rocksdb::Statistics* stats) override; + virtual bool Ref(rocksdb::Cache::Handle* handle) override; + virtual bool Release(rocksdb::Cache::Handle* handle, bool force_erase = false) override; + virtual void* Value(Handle* handle) override = 0; + virtual void Erase(const rocksdb::Slice& key) override; + virtual uint64_t NewId() override; + virtual void SetCapacity(size_t capacity) override; + virtual void SetStrictCapacityLimit(bool strict_capacity_limit) override; + virtual bool HasStrictCapacityLimit() const override; + virtual size_t GetCapacity() const override; + virtual size_t GetUsage() const override; + virtual size_t GetUsage(rocksdb::Cache::Handle* handle) const override; + virtual size_t GetPinnedUsage() const override; + virtual size_t GetCharge(Handle* handle) const = 0; +#if (ROCKSDB_MAJOR >= 7 || (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR >= 22)) + virtual DeleterFn GetDeleter(Handle* handle) const override; +#endif + virtual void DisownData() override = 0; +#if (ROCKSDB_MAJOR >= 7 || (ROCKSDB_MAJOR == 6 && ROCKSDB_MINOR >= 22)) + virtual void ApplyToAllEntries( + const std::function& callback, + const ApplyToAllEntriesOptions& opts) override; +#else + virtual void ApplyToAllCacheEntries(void (*callback)(void*, size_t), + bool thread_safe) override; +#endif + virtual void EraseUnRefEntries() override; + virtual std::string GetPrintableOptions() const override; + virtual CacheShard* GetShard(int shard) = 0; + virtual const CacheShard* GetShard(int shard) const = 0; + virtual uint32_t GetHash(Handle* handle) const = 0; + + int GetNumShardBits() const { return num_shard_bits_; } + + virtual uint32_t get_bin_count() const = 0; + virtual void set_bin_count(uint32_t count) = 0; + + // PriCache + virtual int64_t get_cache_bytes(PriorityCache::Priority pri) const { + return cache_bytes[pri]; + } + virtual int64_t get_cache_bytes() const { + int64_t total = 0; + for (int i = 0; i < PriorityCache::Priority::LAST + 1; i++) { + PriorityCache::Priority pri = static_cast(i); + total += get_cache_bytes(pri); + } + return total; + } + virtual void set_cache_bytes(PriorityCache::Priority pri, int64_t bytes) { + cache_bytes[pri] = bytes; + } + virtual void add_cache_bytes(PriorityCache::Priority pri, int64_t bytes) { + cache_bytes[pri] += bytes; + } + virtual double get_cache_ratio() const { + return cache_ratio; + } + virtual void set_cache_ratio(double ratio) { + cache_ratio = ratio; + } + virtual uint64_t get_bins(PriorityCache::Priority pri) const { + if (pri > PriorityCache::Priority::PRI0 && + pri < PriorityCache::Priority::LAST) { + return bins[pri]; + } + return 0; + } + virtual void set_bins(PriorityCache::Priority pri, uint64_t end_bin) { + if (pri <= PriorityCache::Priority::PRI0 || + pri >= PriorityCache::Priority::LAST) { + return; + } + bins[pri] = end_bin; + uint64_t max = 0; + for (int pri = 1; pri < PriorityCache::Priority::LAST; pri++) { + if (bins[pri] > max) { + max = bins[pri]; + } + } + set_bin_count(max); + } + virtual void import_bins(const std::vector &bins_v) { + uint64_t max = 0; + for (int pri = 1; pri < PriorityCache::Priority::LAST; pri++) { + unsigned i = (unsigned) pri - 1; + if (i < bins_v.size()) { + bins[pri] = bins_v[i]; + if (bins[pri] > max) { + max = bins[pri]; + } + } else { + bins[pri] = 0; + } + } + set_bin_count(max); + } + virtual std::string get_cache_name() const = 0; + + private: + static inline uint32_t HashSlice(const rocksdb::Slice& s) { + return ceph_str_hash(CEPH_STR_HASH_RJENKINS, s.data(), s.size()); +// return Hash(s.data(), s.size(), 0); + } + + uint32_t Shard(uint32_t hash) const { + // Note, hash >> 32 yields hash in gcc, not the zero we expect! + return (num_shard_bits_ > 0) ? (hash >> (32 - num_shard_bits_)) : 0; + } + + uint64_t bins[PriorityCache::Priority::LAST+1] = {0}; + int64_t cache_bytes[PriorityCache::Priority::LAST+1] = {0}; + double cache_ratio = 0; + + int num_shard_bits_; + mutable std::mutex capacity_mutex_; + size_t capacity_; + bool strict_capacity_limit_; + std::atomic last_id_; +}; + +extern int GetDefaultCacheShardBits(size_t capacity); + +} // namespace rocksdb_cache +#endif // ROCKSDB_SHARDED_CACHE -- cgit v1.2.3