]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/cache/compressed_secondary_cache.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / cache / compressed_secondary_cache.h
CommitLineData
1e59de90
TL
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#pragma once
7
8#include <array>
9#include <cstddef>
10#include <memory>
11
12#include "cache/lru_cache.h"
13#include "memory/memory_allocator.h"
14#include "rocksdb/secondary_cache.h"
15#include "rocksdb/slice.h"
16#include "rocksdb/status.h"
17#include "util/compression.h"
18#include "util/mutexlock.h"
19
20namespace ROCKSDB_NAMESPACE {
21
22class CompressedSecondaryCacheResultHandle : public SecondaryCacheResultHandle {
23 public:
24 CompressedSecondaryCacheResultHandle(void* value, size_t size)
25 : value_(value), size_(size) {}
26 ~CompressedSecondaryCacheResultHandle() override = default;
27
28 CompressedSecondaryCacheResultHandle(
29 const CompressedSecondaryCacheResultHandle&) = delete;
30 CompressedSecondaryCacheResultHandle& operator=(
31 const CompressedSecondaryCacheResultHandle&) = delete;
32
33 bool IsReady() override { return true; }
34
35 void Wait() override {}
36
37 void* Value() override { return value_; }
38
39 size_t Size() override { return size_; }
40
41 private:
42 void* value_;
43 size_t size_;
44};
45
46// The CompressedSecondaryCache is a concrete implementation of
47// rocksdb::SecondaryCache.
48//
49// When a block is found from CompressedSecondaryCache::Lookup, we check whether
50// there is a dummy block with the same key in the primary cache.
51// 1. If the dummy block exits, we erase the block from
52// CompressedSecondaryCache and insert it into the primary cache.
53// 2. If not, we just insert a dummy block into the primary cache
54// (charging the actual size of the block) and don not erase the block from
55// CompressedSecondaryCache. A standalone handle is returned to the caller.
56//
57// When a block is evicted from the primary cache, we check whether
58// there is a dummy block with the same key in CompressedSecondaryCache.
59// 1. If the dummy block exits, the block is inserted into
60// CompressedSecondaryCache.
61// 2. If not, we just insert a dummy block (size 0) in CompressedSecondaryCache.
62//
63// Users can also cast a pointer to CompressedSecondaryCache and call methods on
64// it directly, especially custom methods that may be added
65// in the future. For example -
66// std::unique_ptr<rocksdb::SecondaryCache> cache =
67// NewCompressedSecondaryCache(opts);
68// static_cast<CompressedSecondaryCache*>(cache.get())->Erase(key);
69
70class CompressedSecondaryCache : public SecondaryCache {
71 public:
72 CompressedSecondaryCache(
73 size_t capacity, int num_shard_bits, bool strict_capacity_limit,
74 double high_pri_pool_ratio, double low_pri_pool_ratio,
75 std::shared_ptr<MemoryAllocator> memory_allocator = nullptr,
76 bool use_adaptive_mutex = kDefaultToAdaptiveMutex,
77 CacheMetadataChargePolicy metadata_charge_policy =
78 kDefaultCacheMetadataChargePolicy,
79 CompressionType compression_type = CompressionType::kLZ4Compression,
80 uint32_t compress_format_version = 2,
81 bool enable_custom_split_merge = false);
82 ~CompressedSecondaryCache() override;
83
84 const char* Name() const override { return "CompressedSecondaryCache"; }
85
86 Status Insert(const Slice& key, void* value,
87 const Cache::CacheItemHelper* helper) override;
88
89 std::unique_ptr<SecondaryCacheResultHandle> Lookup(
90 const Slice& key, const Cache::CreateCallback& create_cb, bool /*wait*/,
91 bool advise_erase, bool& is_in_sec_cache) override;
92
93 bool SupportForceErase() const override { return true; }
94
95 void Erase(const Slice& key) override;
96
97 void WaitAll(std::vector<SecondaryCacheResultHandle*> /*handles*/) override {}
98
99 Status SetCapacity(size_t capacity) override;
100
101 Status GetCapacity(size_t& capacity) override;
102
103 std::string GetPrintableOptions() const override;
104
105 private:
106 friend class CompressedSecondaryCacheTest;
107 static constexpr std::array<uint16_t, 8> malloc_bin_sizes_{
108 128, 256, 512, 1024, 2048, 4096, 8192, 16384};
109
110 struct CacheValueChunk {
111 // TODO try "CacheAllocationPtr next;".
112 CacheValueChunk* next;
113 size_t size;
114 // Beginning of the chunk data (MUST BE THE LAST FIELD IN THIS STRUCT!)
115 char data[1];
116
117 void Free() { delete[] reinterpret_cast<char*>(this); }
118 };
119
120 // Split value into chunks to better fit into jemalloc bins. The chunks
121 // are stored in CacheValueChunk and extra charge is needed for each chunk,
122 // so the cache charge is recalculated here.
123 CacheValueChunk* SplitValueIntoChunks(const Slice& value,
124 CompressionType compression_type,
125 size_t& charge);
126
127 // After merging chunks, the extra charge for each chunk is removed, so
128 // the charge is recalculated.
129 CacheAllocationPtr MergeChunksIntoValue(const void* chunks_head,
130 size_t& charge);
131
132 // An implementation of Cache::DeleterFn.
133 static Cache::DeleterFn GetDeletionCallback(bool enable_custom_split_merge);
134 std::shared_ptr<Cache> cache_;
135 CompressedSecondaryCacheOptions cache_options_;
136 mutable port::Mutex capacity_mutex_;
137};
138
139} // namespace ROCKSDB_NAMESPACE