2016-07-15 19:41:36 +02:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
2017-07-16 01:03:42 +02:00
|
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
|
|
// (found in the LICENSE.Apache file in the root directory).
|
2016-07-15 19:41:36 +02:00
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <atomic>
|
2016-12-22 23:44:01 +01:00
|
|
|
#include <string>
|
2016-07-15 19:41:36 +02:00
|
|
|
|
|
|
|
#include "port/port.h"
|
|
|
|
#include "rocksdb/cache.h"
|
|
|
|
#include "util/hash.h"
|
|
|
|
|
2020-02-20 21:07:53 +01:00
|
|
|
namespace ROCKSDB_NAMESPACE {
|
2016-07-15 19:41:36 +02:00
|
|
|
|
|
|
|
// Single cache shard interface.
|
|
|
|
class CacheShard {
|
|
|
|
public:
|
|
|
|
CacheShard() = default;
|
|
|
|
virtual ~CacheShard() = default;
|
|
|
|
|
|
|
|
virtual Status Insert(const Slice& key, uint32_t hash, void* value,
|
|
|
|
size_t charge,
|
|
|
|
void (*deleter)(const Slice& key, void* value),
|
2016-08-20 01:43:31 +02:00
|
|
|
Cache::Handle** handle, Cache::Priority priority) = 0;
|
2016-07-15 19:41:36 +02:00
|
|
|
virtual Cache::Handle* Lookup(const Slice& key, uint32_t hash) = 0;
|
2017-01-11 01:48:23 +01:00
|
|
|
virtual bool Ref(Cache::Handle* handle) = 0;
|
2017-04-24 20:21:47 +02:00
|
|
|
virtual bool Release(Cache::Handle* handle, bool force_erase = false) = 0;
|
2016-07-15 19:41:36 +02:00
|
|
|
virtual void Erase(const 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(void (*callback)(void*, size_t),
|
|
|
|
bool thread_safe) = 0;
|
|
|
|
virtual void EraseUnRefEntries() = 0;
|
2016-12-22 23:44:01 +01:00
|
|
|
virtual std::string GetPrintableOptions() const { return ""; }
|
2019-09-17 00:14:51 +02:00
|
|
|
void set_metadata_charge_policy(
|
|
|
|
CacheMetadataChargePolicy metadata_charge_policy) {
|
|
|
|
metadata_charge_policy_ = metadata_charge_policy;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
CacheMetadataChargePolicy metadata_charge_policy_ = kDontChargeCacheMetadata;
|
2016-07-15 19:41:36 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// 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 Cache {
|
|
|
|
public:
|
2018-11-21 20:28:02 +01:00
|
|
|
ShardedCache(size_t capacity, int num_shard_bits, bool strict_capacity_limit,
|
|
|
|
std::shared_ptr<MemoryAllocator> memory_allocator = nullptr);
|
2016-07-15 19:41:36 +02:00
|
|
|
virtual ~ShardedCache() = default;
|
2016-08-12 23:16:57 +02:00
|
|
|
virtual const char* Name() const override = 0;
|
2016-07-15 19:41:36 +02:00
|
|
|
virtual CacheShard* GetShard(int shard) = 0;
|
|
|
|
virtual const CacheShard* GetShard(int shard) const = 0;
|
|
|
|
virtual void* Value(Handle* handle) override = 0;
|
2019-06-19 02:32:44 +02:00
|
|
|
virtual size_t GetCharge(Handle* handle) const override = 0;
|
|
|
|
|
2016-07-15 19:41:36 +02:00
|
|
|
virtual uint32_t GetHash(Handle* handle) const = 0;
|
|
|
|
virtual void DisownData() override = 0;
|
|
|
|
|
|
|
|
virtual void SetCapacity(size_t capacity) override;
|
|
|
|
virtual void SetStrictCapacityLimit(bool strict_capacity_limit) override;
|
|
|
|
|
|
|
|
virtual Status Insert(const Slice& key, void* value, size_t charge,
|
|
|
|
void (*deleter)(const Slice& key, void* value),
|
2016-08-20 01:43:31 +02:00
|
|
|
Handle** handle, Priority priority) override;
|
2016-09-01 22:50:39 +02:00
|
|
|
virtual Handle* Lookup(const Slice& key, Statistics* stats) override;
|
2017-01-11 01:48:23 +01:00
|
|
|
virtual bool Ref(Handle* handle) override;
|
2017-04-24 20:21:47 +02:00
|
|
|
virtual bool Release(Handle* handle, bool force_erase = false) override;
|
2016-07-15 19:41:36 +02:00
|
|
|
virtual void Erase(const Slice& key) override;
|
|
|
|
virtual uint64_t NewId() override;
|
|
|
|
virtual size_t GetCapacity() const override;
|
|
|
|
virtual bool HasStrictCapacityLimit() const override;
|
|
|
|
virtual size_t GetUsage() const override;
|
|
|
|
virtual size_t GetUsage(Handle* handle) const override;
|
|
|
|
virtual size_t GetPinnedUsage() const override;
|
|
|
|
virtual void ApplyToAllCacheEntries(void (*callback)(void*, size_t),
|
|
|
|
bool thread_safe) override;
|
|
|
|
virtual void EraseUnRefEntries() override;
|
2016-12-22 23:44:01 +01:00
|
|
|
virtual std::string GetPrintableOptions() const override;
|
2016-07-15 19:41:36 +02:00
|
|
|
|
2017-01-27 15:35:41 +01:00
|
|
|
int GetNumShardBits() const { return num_shard_bits_; }
|
|
|
|
|
2016-07-15 19:41:36 +02:00
|
|
|
private:
|
|
|
|
static inline uint32_t HashSlice(const Slice& s) {
|
2019-04-08 22:24:29 +02:00
|
|
|
return static_cast<uint32_t>(GetSliceNPHash64(s));
|
2016-07-15 19:41:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Shard(uint32_t hash) {
|
|
|
|
// Note, hash >> 32 yields hash in gcc, not the zero we expect!
|
|
|
|
return (num_shard_bits_ > 0) ? (hash >> (32 - num_shard_bits_)) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int num_shard_bits_;
|
|
|
|
mutable port::Mutex capacity_mutex_;
|
|
|
|
size_t capacity_;
|
|
|
|
bool strict_capacity_limit_;
|
|
|
|
std::atomic<uint64_t> last_id_;
|
|
|
|
};
|
|
|
|
|
2017-01-27 15:35:41 +01:00
|
|
|
extern int GetDefaultCacheShardBits(size_t capacity);
|
|
|
|
|
2020-02-20 21:07:53 +01:00
|
|
|
} // namespace ROCKSDB_NAMESPACE
|