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