1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. 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). 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 #pragma once 11 12 #include <atomic> 13 #include <string> 14 15 #include "port/port.h" 16 #include "rocksdb/cache.h" 17 #include "util/hash.h" 18 19 namespace ROCKSDB_NAMESPACE { 20 21 // Single cache shard interface. 22 class CacheShard { 23 public: 24 CacheShard() = default; 25 virtual ~CacheShard() = default; 26 27 virtual Status Insert(const Slice& key, uint32_t hash, void* value, 28 size_t charge, 29 void (*deleter)(const Slice& key, void* value), 30 Cache::Handle** handle, Cache::Priority priority) = 0; 31 virtual Cache::Handle* Lookup(const Slice& key, uint32_t hash) = 0; 32 virtual bool Ref(Cache::Handle* handle) = 0; 33 virtual bool Release(Cache::Handle* handle, bool force_erase = false) = 0; 34 virtual void Erase(const Slice& key, uint32_t hash) = 0; 35 virtual void SetCapacity(size_t capacity) = 0; 36 virtual void SetStrictCapacityLimit(bool strict_capacity_limit) = 0; 37 virtual size_t GetUsage() const = 0; 38 virtual size_t GetPinnedUsage() const = 0; 39 virtual void ApplyToAllCacheEntries(void (*callback)(void*, size_t), 40 bool thread_safe) = 0; 41 virtual void EraseUnRefEntries() = 0; GetPrintableOptions()42 virtual std::string GetPrintableOptions() const { return ""; } set_metadata_charge_policy(CacheMetadataChargePolicy metadata_charge_policy)43 void set_metadata_charge_policy( 44 CacheMetadataChargePolicy metadata_charge_policy) { 45 metadata_charge_policy_ = metadata_charge_policy; 46 } 47 48 protected: 49 CacheMetadataChargePolicy metadata_charge_policy_ = kDontChargeCacheMetadata; 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 Cache { 56 public: 57 ShardedCache(size_t capacity, int num_shard_bits, bool strict_capacity_limit, 58 std::shared_ptr<MemoryAllocator> memory_allocator = nullptr); 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 override = 0; 65 66 virtual uint32_t GetHash(Handle* handle) const = 0; 67 virtual void DisownData() override = 0; 68 69 virtual void SetCapacity(size_t capacity) override; 70 virtual void SetStrictCapacityLimit(bool strict_capacity_limit) override; 71 72 virtual Status Insert(const Slice& key, void* value, size_t charge, 73 void (*deleter)(const Slice& key, void* value), 74 Handle** handle, Priority priority) override; 75 virtual Handle* Lookup(const Slice& key, Statistics* stats) override; 76 virtual bool Ref(Handle* handle) override; 77 virtual bool Release(Handle* handle, bool force_erase = false) override; 78 virtual void Erase(const Slice& key) override; 79 virtual uint64_t NewId() override; 80 virtual size_t GetCapacity() const override; 81 virtual bool HasStrictCapacityLimit() const override; 82 virtual size_t GetUsage() const override; 83 virtual size_t GetUsage(Handle* handle) const override; 84 virtual size_t GetPinnedUsage() const override; 85 virtual void ApplyToAllCacheEntries(void (*callback)(void*, size_t), 86 bool thread_safe) override; 87 virtual void EraseUnRefEntries() override; 88 virtual std::string GetPrintableOptions() const override; 89 GetNumShardBits()90 int GetNumShardBits() const { return num_shard_bits_; } 91 92 private: HashSlice(const Slice & s)93 static inline uint32_t HashSlice(const Slice& s) { 94 return static_cast<uint32_t>(GetSliceNPHash64(s)); 95 } 96 Shard(uint32_t hash)97 uint32_t Shard(uint32_t hash) { 98 // Note, hash >> 32 yields hash in gcc, not the zero we expect! 99 return (num_shard_bits_ > 0) ? (hash >> (32 - num_shard_bits_)) : 0; 100 } 101 102 int num_shard_bits_; 103 mutable port::Mutex capacity_mutex_; 104 size_t capacity_; 105 bool strict_capacity_limit_; 106 std::atomic<uint64_t> last_id_; 107 }; 108 109 extern int GetDefaultCacheShardBits(size_t capacity); 110 111 } // namespace ROCKSDB_NAMESPACE 112