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