@nxtedition/rocksdb 8.1.3 → 8.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/deps/rocksdb/rocksdb/CMakeLists.txt +13 -1
  2. package/deps/rocksdb/rocksdb/Makefile +2 -2
  3. package/deps/rocksdb/rocksdb/TARGETS +4 -2
  4. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +32 -35
  5. package/deps/rocksdb/rocksdb/cache/cache_entry_roles.cc +0 -30
  6. package/deps/rocksdb/rocksdb/cache/cache_entry_roles.h +0 -83
  7. package/deps/rocksdb/rocksdb/cache/cache_entry_stats.h +13 -14
  8. package/deps/rocksdb/rocksdb/cache/cache_helpers.cc +40 -0
  9. package/deps/rocksdb/rocksdb/cache/cache_helpers.h +14 -20
  10. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager.cc +8 -9
  11. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager.h +5 -4
  12. package/deps/rocksdb/rocksdb/cache/cache_test.cc +124 -156
  13. package/deps/rocksdb/rocksdb/cache/charged_cache.cc +10 -26
  14. package/deps/rocksdb/rocksdb/cache/charged_cache.h +11 -16
  15. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +35 -32
  16. package/deps/rocksdb/rocksdb/cache/clock_cache.h +19 -21
  17. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +42 -30
  18. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +9 -8
  19. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +91 -143
  20. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +54 -60
  21. package/deps/rocksdb/rocksdb/cache/lru_cache.h +37 -63
  22. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +120 -106
  23. package/deps/rocksdb/rocksdb/cache/secondary_cache.cc +14 -5
  24. package/deps/rocksdb/rocksdb/cache/sharded_cache.h +16 -31
  25. package/deps/rocksdb/rocksdb/cache/typed_cache.h +339 -0
  26. package/deps/rocksdb/rocksdb/db/blob/blob_contents.cc +0 -48
  27. package/deps/rocksdb/rocksdb/db/blob/blob_contents.h +18 -15
  28. package/deps/rocksdb/rocksdb/db/blob/blob_counting_iterator.h +0 -11
  29. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.cc +5 -26
  30. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.cc +7 -8
  31. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.h +6 -3
  32. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +2 -7
  33. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +19 -47
  34. package/deps/rocksdb/rocksdb/db/blob/blob_source.h +13 -5
  35. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +15 -22
  36. package/deps/rocksdb/rocksdb/db/builder.cc +17 -12
  37. package/deps/rocksdb/rocksdb/db/column_family.cc +0 -1
  38. package/deps/rocksdb/rocksdb/db/column_family.h +0 -6
  39. package/deps/rocksdb/rocksdb/db/compaction/clipping_iterator.h +0 -5
  40. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +3 -0
  41. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +0 -2
  42. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +28 -27
  43. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +2 -17
  44. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +1 -0
  45. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +254 -139
  46. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +7 -5
  47. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +0 -5
  48. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +98 -9
  49. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +28 -28
  50. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +125 -0
  51. package/deps/rocksdb/rocksdb/db/db_flush_test.cc +65 -4
  52. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +1 -1
  53. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +27 -15
  54. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +78 -49
  55. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +34 -24
  56. package/deps/rocksdb/rocksdb/db/db_iter.cc +8 -2
  57. package/deps/rocksdb/rocksdb/db/db_merge_operand_test.cc +42 -0
  58. package/deps/rocksdb/rocksdb/db/db_merge_operator_test.cc +155 -0
  59. package/deps/rocksdb/rocksdb/db/db_properties_test.cc +12 -12
  60. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +117 -210
  61. package/deps/rocksdb/rocksdb/db/db_test_util.cc +11 -10
  62. package/deps/rocksdb/rocksdb/db/db_test_util.h +36 -24
  63. package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +28 -0
  64. package/deps/rocksdb/rocksdb/db/flush_job.cc +6 -6
  65. package/deps/rocksdb/rocksdb/db/flush_job.h +3 -2
  66. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +29 -29
  67. package/deps/rocksdb/rocksdb/db/history_trimming_iterator.h +0 -4
  68. package/deps/rocksdb/rocksdb/db/internal_stats.cc +11 -11
  69. package/deps/rocksdb/rocksdb/db/internal_stats.h +2 -2
  70. package/deps/rocksdb/rocksdb/db/log_reader.cc +8 -6
  71. package/deps/rocksdb/rocksdb/db/log_test.cc +35 -2
  72. package/deps/rocksdb/rocksdb/db/memtable.cc +30 -5
  73. package/deps/rocksdb/rocksdb/db/merge_helper.cc +47 -33
  74. package/deps/rocksdb/rocksdb/db/merge_helper.h +14 -6
  75. package/deps/rocksdb/rocksdb/db/table_cache.cc +41 -91
  76. package/deps/rocksdb/rocksdb/db/table_cache.h +17 -19
  77. package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +7 -9
  78. package/deps/rocksdb/rocksdb/db/version_builder.cc +12 -9
  79. package/deps/rocksdb/rocksdb/db/version_edit.h +1 -0
  80. package/deps/rocksdb/rocksdb/db/version_set.cc +20 -28
  81. package/deps/rocksdb/rocksdb/db/version_set.h +2 -2
  82. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +1 -1
  83. package/deps/rocksdb/rocksdb/db/write_batch.cc +4 -1
  84. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +1 -0
  85. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +358 -214
  86. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +137 -135
  87. package/deps/rocksdb/rocksdb/include/rocksdb/merge_operator.h +21 -0
  88. package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +8 -6
  89. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +1 -1
  90. package/deps/rocksdb/rocksdb/memory/memory_allocator.h +9 -0
  91. package/deps/rocksdb/rocksdb/options/customizable_test.cc +4 -3
  92. package/deps/rocksdb/rocksdb/port/port_posix.h +2 -0
  93. package/{prebuilds → deps/rocksdb/rocksdb/prebuilds}/linux-x64/node.napi.node +0 -0
  94. package/deps/rocksdb/rocksdb/src.mk +2 -1
  95. package/deps/rocksdb/rocksdb/table/block_based/block.h +3 -0
  96. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +25 -67
  97. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +3 -3
  98. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +18 -13
  99. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +156 -223
  100. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +31 -50
  101. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +46 -18
  102. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +3 -3
  103. package/deps/rocksdb/rocksdb/table/block_based/block_cache.cc +96 -0
  104. package/deps/rocksdb/rocksdb/table/block_based/block_cache.h +132 -0
  105. package/deps/rocksdb/rocksdb/table/block_based/cachable_entry.h +28 -0
  106. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +6 -5
  107. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.h +1 -4
  108. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +6 -7
  109. package/deps/rocksdb/rocksdb/table/block_based/index_reader_common.cc +3 -1
  110. package/deps/rocksdb/rocksdb/table/block_based/parsed_full_filter_block.h +6 -1
  111. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +19 -18
  112. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +9 -5
  113. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +3 -1
  114. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_reader.cc +2 -1
  115. package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.cc +2 -2
  116. package/deps/rocksdb/rocksdb/table/format.h +1 -1
  117. package/deps/rocksdb/rocksdb/table/get_context.cc +12 -3
  118. package/deps/rocksdb/rocksdb/table/internal_iterator.h +0 -2
  119. package/deps/rocksdb/rocksdb/table/merging_iterator.cc +92 -7
  120. package/deps/rocksdb/rocksdb/table/merging_iterator.h +0 -80
  121. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc +66 -1
  122. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +9 -2
  123. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer.cc +5 -0
  124. package/deps/rocksdb/rocksdb/trace_replay/trace_replay.cc +1 -1
  125. package/deps/rocksdb/rocksdb/util/async_file_reader.cc +20 -12
  126. package/deps/rocksdb/rocksdb/util/compression.cc +2 -2
  127. package/deps/rocksdb/rocksdb/util/compression.h +11 -2
  128. package/deps/rocksdb/rocksdb/util/xxhash.h +1901 -887
  129. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +35 -57
  130. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.h +4 -5
  131. package/deps/rocksdb/rocksdb/utilities/fault_injection_secondary_cache.cc +11 -6
  132. package/deps/rocksdb/rocksdb/utilities/fault_injection_secondary_cache.h +6 -5
  133. package/deps/rocksdb/rocksdb/utilities/memory_allocators.h +0 -1
  134. package/deps/rocksdb/rocksdb/utilities/simulator_cache/cache_simulator.cc +10 -11
  135. package/deps/rocksdb/rocksdb/utilities/simulator_cache/sim_cache.cc +31 -31
  136. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_time.h +4 -0
  137. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +52 -0
  138. package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.cc +1 -0
  139. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.cc +12 -3
  140. package/deps/rocksdb/rocksdb.gyp +0 -3
  141. package/index.js +2 -2
  142. package/package.json +1 -1
  143. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  144. package/deps/rocksdb/rocksdb/table/block_based/block_like_traits.h +0 -182
  145. package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.cc +0 -142
  146. package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.h +0 -241
@@ -49,16 +49,12 @@ class CacheShardBase {
49
49
  HashCref GetHash() const;
50
50
  ...
51
51
  };
52
- Status Insert(const Slice& key, HashCref hash, void* value, size_t charge,
53
- DeleterFn deleter, HandleImpl** handle,
54
- Cache::Priority priority) = 0;
55
- Status Insert(const Slice& key, HashCref hash, void* value,
52
+ Status Insert(const Slice& key, HashCref hash, Cache::ObjectPtr value,
56
53
  const Cache::CacheItemHelper* helper, size_t charge,
57
54
  HandleImpl** handle, Cache::Priority priority) = 0;
58
- HandleImpl* Lookup(const Slice& key, HashCref hash) = 0;
59
55
  HandleImpl* Lookup(const Slice& key, HashCref hash,
60
56
  const Cache::CacheItemHelper* helper,
61
- const Cache::CreateCallback& create_cb,
57
+ Cache::CreateContext* create_context,
62
58
  Cache::Priority priority, bool wait,
63
59
  Statistics* stats) = 0;
64
60
  bool Release(HandleImpl* handle, bool useful, bool erase_if_last_ref) = 0;
@@ -77,8 +73,9 @@ class CacheShardBase {
77
73
  // *state == 0 and implementation sets *state = SIZE_MAX to indicate
78
74
  // completion.
79
75
  void ApplyToSomeEntries(
80
- const std::function<void(const Slice& key, void* value, size_t charge,
81
- DeleterFn deleter)>& callback,
76
+ const std::function<void(const Slice& key, ObjectPtr value,
77
+ size_t charge,
78
+ const Cache::CacheItemHelper* helper)>& callback,
82
79
  size_t average_entries_per_lock, size_t* state) = 0;
83
80
  void EraseUnRefEntries() = 0;
84
81
  */
@@ -172,36 +169,24 @@ class ShardedCache : public ShardedCacheBase {
172
169
  [s_c_l](CacheShard* cs) { cs->SetStrictCapacityLimit(s_c_l); });
173
170
  }
174
171
 
175
- Status Insert(const Slice& key, void* value, size_t charge, DeleterFn deleter,
176
- Handle** handle, Priority priority) override {
177
- HashVal hash = CacheShard::ComputeHash(key);
178
- auto h_out = reinterpret_cast<HandleImpl**>(handle);
179
- return GetShard(hash).Insert(key, hash, value, charge, deleter, h_out,
180
- priority);
181
- }
182
- Status Insert(const Slice& key, void* value, const CacheItemHelper* helper,
183
- size_t charge, Handle** handle = nullptr,
172
+ Status Insert(const Slice& key, ObjectPtr value,
173
+ const CacheItemHelper* helper, size_t charge,
174
+ Handle** handle = nullptr,
184
175
  Priority priority = Priority::LOW) override {
185
- if (!helper) {
186
- return Status::InvalidArgument();
187
- }
176
+ assert(helper);
188
177
  HashVal hash = CacheShard::ComputeHash(key);
189
178
  auto h_out = reinterpret_cast<HandleImpl**>(handle);
190
179
  return GetShard(hash).Insert(key, hash, value, helper, charge, h_out,
191
180
  priority);
192
181
  }
193
182
 
194
- Handle* Lookup(const Slice& key, Statistics* /*stats*/) override {
195
- HashVal hash = CacheShard::ComputeHash(key);
196
- HandleImpl* result = GetShard(hash).Lookup(key, hash);
197
- return reinterpret_cast<Handle*>(result);
198
- }
199
- Handle* Lookup(const Slice& key, const CacheItemHelper* helper,
200
- const CreateCallback& create_cb, Priority priority, bool wait,
183
+ Handle* Lookup(const Slice& key, const CacheItemHelper* helper = nullptr,
184
+ CreateContext* create_context = nullptr,
185
+ Priority priority = Priority::LOW, bool wait = true,
201
186
  Statistics* stats = nullptr) override {
202
187
  HashVal hash = CacheShard::ComputeHash(key);
203
- HandleImpl* result = GetShard(hash).Lookup(key, hash, helper, create_cb,
204
- priority, wait, stats);
188
+ HandleImpl* result = GetShard(hash).Lookup(
189
+ key, hash, helper, create_context, priority, wait, stats);
205
190
  return reinterpret_cast<Handle*>(result);
206
191
  }
207
192
 
@@ -244,8 +229,8 @@ class ShardedCache : public ShardedCacheBase {
244
229
  return SumOverShards2(&CacheShard::GetTableAddressCount);
245
230
  }
246
231
  void ApplyToAllEntries(
247
- const std::function<void(const Slice& key, void* value, size_t charge,
248
- DeleterFn deleter)>& callback,
232
+ const std::function<void(const Slice& key, ObjectPtr value, size_t charge,
233
+ const CacheItemHelper* helper)>& callback,
249
234
  const ApplyToAllEntriesOptions& opts) override {
250
235
  uint32_t num_shards = GetNumShards();
251
236
  // Iterate over part of each shard, rotating between shards, to
@@ -0,0 +1,339 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
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
+ // APIs for accessing Cache in a type-safe and convenient way. Cache is kept
7
+ // at a low, thin level of abstraction so that different implementations can
8
+ // be plugged in, but these wrappers provide clean, convenient access to the
9
+ // most common operations.
10
+ //
11
+ // A number of template classes are needed for sharing common structure. The
12
+ // key classes are these:
13
+ //
14
+ // * PlaceholderCacheInterface - Used for making cache reservations, with
15
+ // entries that have a charge but no value.
16
+ // * BasicTypedCacheInterface<TValue> - Used for primary cache storage of
17
+ // objects of type TValue.
18
+ // * FullTypedCacheHelper<TValue, TCreateContext> - Used for secondary cache
19
+ // compatible storage of objects of type TValue.
20
+ // * For each of these, there's a "Shared" version
21
+ // (e.g. FullTypedSharedCacheInterface) that holds a shared_ptr to the Cache,
22
+ // rather than assuming external ownership by holding only a raw `Cache*`.
23
+
24
+ #pragma once
25
+
26
+ #include <algorithm>
27
+ #include <cstdint>
28
+ #include <memory>
29
+ #include <type_traits>
30
+
31
+ #include "cache/cache_helpers.h"
32
+ #include "rocksdb/advanced_options.h"
33
+ #include "rocksdb/cache.h"
34
+
35
+ namespace ROCKSDB_NAMESPACE {
36
+
37
+ // For future consideration:
38
+ // * Pass in value to Insert with std::unique_ptr& to simplify ownership
39
+ // transfer logic in callers
40
+ // * Make key type a template parameter (e.g. useful for table cache)
41
+ // * Closer integration with CacheHandleGuard (opt-in, so not always
42
+ // paying the extra overhead)
43
+
44
+ #define CACHE_TYPE_DEFS() \
45
+ using Priority = Cache::Priority; \
46
+ using Handle = Cache::Handle; \
47
+ using ObjectPtr = Cache::ObjectPtr; \
48
+ using CreateContext = Cache::CreateContext; \
49
+ using CacheItemHelper = Cache::CacheItemHelper /* caller ; */
50
+
51
+ template <typename CachePtr>
52
+ class BaseCacheInterface {
53
+ public:
54
+ CACHE_TYPE_DEFS();
55
+
56
+ /*implicit*/ BaseCacheInterface(CachePtr cache) : cache_(std::move(cache)) {}
57
+
58
+ inline void Release(Handle* handle) { cache_->Release(handle); }
59
+
60
+ inline void ReleaseAndEraseIfLastRef(Handle* handle) {
61
+ cache_->Release(handle, /*erase_if_last_ref*/ true);
62
+ }
63
+
64
+ inline void RegisterReleaseAsCleanup(Handle* handle, Cleanable& cleanable) {
65
+ cleanable.RegisterCleanup(&ReleaseCacheHandleCleanup, get(), handle);
66
+ }
67
+
68
+ inline Cache* get() const { return &*cache_; }
69
+
70
+ explicit inline operator bool() const noexcept { return cache_ != nullptr; }
71
+
72
+ protected:
73
+ CachePtr cache_;
74
+ };
75
+
76
+ // PlaceholderCacheInterface - Used for making cache reservations, with
77
+ // entries that have a charge but no value. CacheEntryRole is required as
78
+ // a template parameter.
79
+ template <CacheEntryRole kRole, typename CachePtr = Cache*>
80
+ class PlaceholderCacheInterface : public BaseCacheInterface<CachePtr> {
81
+ public:
82
+ CACHE_TYPE_DEFS();
83
+ using BaseCacheInterface<CachePtr>::BaseCacheInterface;
84
+
85
+ inline Status Insert(const Slice& key, size_t charge, Handle** handle) {
86
+ return this->cache_->Insert(key, /*value=*/nullptr, &kHelper, charge,
87
+ handle);
88
+ }
89
+
90
+ static constexpr Cache::CacheItemHelper kHelper{kRole};
91
+ };
92
+
93
+ template <CacheEntryRole kRole>
94
+ using PlaceholderSharedCacheInterface =
95
+ PlaceholderCacheInterface<kRole, std::shared_ptr<Cache>>;
96
+
97
+ template <class TValue>
98
+ class BasicTypedCacheHelperFns {
99
+ public:
100
+ CACHE_TYPE_DEFS();
101
+ // E.g. char* for char[]
102
+ using TValuePtr = std::remove_extent_t<TValue>*;
103
+
104
+ protected:
105
+ inline static ObjectPtr UpCastValue(TValuePtr value) { return value; }
106
+ inline static TValuePtr DownCastValue(ObjectPtr value) {
107
+ return static_cast<TValuePtr>(value);
108
+ }
109
+
110
+ static void Delete(ObjectPtr value, MemoryAllocator* allocator) {
111
+ // FIXME: Currently, no callers actually allocate the ObjectPtr objects
112
+ // using the custom allocator, just subobjects that keep a reference to
113
+ // the allocator themselves (with CacheAllocationPtr).
114
+ if (/*DISABLED*/ false && allocator) {
115
+ if constexpr (std::is_destructible_v<TValue>) {
116
+ DownCastValue(value)->~TValue();
117
+ }
118
+ allocator->Deallocate(value);
119
+ } else {
120
+ // Like delete but properly handles TValue=char[] etc.
121
+ std::default_delete<TValue>{}(DownCastValue(value));
122
+ }
123
+ }
124
+ };
125
+
126
+ // In its own class to try to minimize the number of distinct CacheItemHelper
127
+ // instances (e.g. don't vary by CachePtr)
128
+ template <class TValue, CacheEntryRole kRole>
129
+ class BasicTypedCacheHelper : public BasicTypedCacheHelperFns<TValue> {
130
+ public:
131
+ static constexpr Cache::CacheItemHelper kBasicHelper{
132
+ kRole, &BasicTypedCacheHelper::Delete};
133
+ };
134
+
135
+ // BasicTypedCacheInterface - Used for primary cache storage of objects of
136
+ // type TValue, which can be cleaned up with std::default_delete<TValue>. The
137
+ // role is provided by TValue::kCacheEntryRole or given in an optional
138
+ // template parameter.
139
+ template <class TValue, CacheEntryRole kRole = TValue::kCacheEntryRole,
140
+ typename CachePtr = Cache*>
141
+ class BasicTypedCacheInterface : public BaseCacheInterface<CachePtr>,
142
+ public BasicTypedCacheHelper<TValue, kRole> {
143
+ public:
144
+ CACHE_TYPE_DEFS();
145
+ using typename BasicTypedCacheHelperFns<TValue>::TValuePtr;
146
+ struct TypedHandle : public Handle {};
147
+ using BasicTypedCacheHelper<TValue, kRole>::kBasicHelper;
148
+ // ctor
149
+ using BaseCacheInterface<CachePtr>::BaseCacheInterface;
150
+
151
+ inline Status Insert(const Slice& key, TValuePtr value, size_t charge,
152
+ TypedHandle** handle = nullptr,
153
+ Priority priority = Priority::LOW) {
154
+ auto untyped_handle = reinterpret_cast<Handle**>(handle);
155
+ return this->cache_->Insert(
156
+ key, BasicTypedCacheHelperFns<TValue>::UpCastValue(value),
157
+ &kBasicHelper, charge, untyped_handle, priority);
158
+ }
159
+
160
+ inline TypedHandle* Lookup(const Slice& key, Statistics* stats = nullptr) {
161
+ return reinterpret_cast<TypedHandle*>(
162
+ this->cache_->BasicLookup(key, stats));
163
+ }
164
+
165
+ inline CacheHandleGuard<TValue> Guard(TypedHandle* handle) {
166
+ if (handle) {
167
+ return CacheHandleGuard<TValue>(&*this->cache_, handle);
168
+ } else {
169
+ return {};
170
+ }
171
+ }
172
+
173
+ inline std::shared_ptr<TValue> SharedGuard(TypedHandle* handle) {
174
+ if (handle) {
175
+ return MakeSharedCacheHandleGuard<TValue>(&*this->cache_, handle);
176
+ } else {
177
+ return {};
178
+ }
179
+ }
180
+
181
+ inline TValuePtr Value(TypedHandle* handle) {
182
+ return BasicTypedCacheHelperFns<TValue>::DownCastValue(
183
+ this->cache_->Value(handle));
184
+ }
185
+ };
186
+
187
+ // BasicTypedSharedCacheInterface - Like BasicTypedCacheInterface but with a
188
+ // shared_ptr<Cache> for keeping Cache alive.
189
+ template <class TValue, CacheEntryRole kRole = TValue::kCacheEntryRole>
190
+ using BasicTypedSharedCacheInterface =
191
+ BasicTypedCacheInterface<TValue, kRole, std::shared_ptr<Cache>>;
192
+
193
+ // TValue must implement ContentSlice() and ~TValue
194
+ // TCreateContext must implement Create(std::unique_ptr<TValue>*, ...)
195
+ template <class TValue, class TCreateContext>
196
+ class FullTypedCacheHelperFns : public BasicTypedCacheHelperFns<TValue> {
197
+ public:
198
+ CACHE_TYPE_DEFS();
199
+
200
+ protected:
201
+ using typename BasicTypedCacheHelperFns<TValue>::TValuePtr;
202
+ using BasicTypedCacheHelperFns<TValue>::DownCastValue;
203
+ using BasicTypedCacheHelperFns<TValue>::UpCastValue;
204
+
205
+ static size_t Size(ObjectPtr v) {
206
+ TValuePtr value = DownCastValue(v);
207
+ auto slice = value->ContentSlice();
208
+ return slice.size();
209
+ }
210
+
211
+ static Status SaveTo(ObjectPtr v, size_t from_offset, size_t length,
212
+ char* out) {
213
+ TValuePtr value = DownCastValue(v);
214
+ auto slice = value->ContentSlice();
215
+ assert(from_offset < slice.size());
216
+ assert(from_offset + length <= slice.size());
217
+ std::copy_n(slice.data() + from_offset, length, out);
218
+ return Status::OK();
219
+ }
220
+
221
+ static Status Create(const Slice& data, CreateContext* context,
222
+ MemoryAllocator* allocator, ObjectPtr* out_obj,
223
+ size_t* out_charge) {
224
+ std::unique_ptr<TValue> value = nullptr;
225
+ if constexpr (sizeof(TCreateContext) > 0) {
226
+ TCreateContext* tcontext = static_cast<TCreateContext*>(context);
227
+ tcontext->Create(&value, out_charge, data, allocator);
228
+ } else {
229
+ TCreateContext::Create(&value, out_charge, data, allocator);
230
+ }
231
+ *out_obj = UpCastValue(value.release());
232
+ return Status::OK();
233
+ }
234
+ };
235
+
236
+ // In its own class to try to minimize the number of distinct CacheItemHelper
237
+ // instances (e.g. don't vary by CachePtr)
238
+ template <class TValue, class TCreateContext, CacheEntryRole kRole>
239
+ class FullTypedCacheHelper
240
+ : public FullTypedCacheHelperFns<TValue, TCreateContext> {
241
+ public:
242
+ static constexpr Cache::CacheItemHelper kFullHelper{
243
+ kRole, &FullTypedCacheHelper::Delete, &FullTypedCacheHelper::Size,
244
+ &FullTypedCacheHelper::SaveTo, &FullTypedCacheHelper::Create};
245
+ };
246
+
247
+ // FullTypedCacheHelper - Used for secondary cache compatible storage of
248
+ // objects of type TValue. In addition to BasicTypedCacheInterface constraints,
249
+ // we require TValue::ContentSlice() to return persistable data. This
250
+ // simplifies usage for the normal case of simple secondary cache compatibility
251
+ // (can give you a Slice to the data already in memory). In addition to
252
+ // TCreateContext performing the role of Cache::CreateContext, it is also
253
+ // expected to provide a function Create(std::unique_ptr<TValue>* value,
254
+ // size_t* out_charge, const Slice& data, MemoryAllocator* allocator) for
255
+ // creating new TValue.
256
+ template <class TValue, class TCreateContext,
257
+ CacheEntryRole kRole = TValue::kCacheEntryRole,
258
+ typename CachePtr = Cache*>
259
+ class FullTypedCacheInterface
260
+ : public BasicTypedCacheInterface<TValue, kRole, CachePtr>,
261
+ public FullTypedCacheHelper<TValue, TCreateContext, kRole> {
262
+ public:
263
+ CACHE_TYPE_DEFS();
264
+ using typename BasicTypedCacheInterface<TValue, kRole, CachePtr>::TypedHandle;
265
+ using typename BasicTypedCacheHelperFns<TValue>::TValuePtr;
266
+ using BasicTypedCacheHelper<TValue, kRole>::kBasicHelper;
267
+ using FullTypedCacheHelper<TValue, TCreateContext, kRole>::kFullHelper;
268
+ using BasicTypedCacheHelperFns<TValue>::UpCastValue;
269
+ using BasicTypedCacheHelperFns<TValue>::DownCastValue;
270
+ // ctor
271
+ using BasicTypedCacheInterface<TValue, kRole,
272
+ CachePtr>::BasicTypedCacheInterface;
273
+
274
+ // Insert with SecondaryCache compatibility (subject to CacheTier).
275
+ // (Basic Insert() also inherited.)
276
+ inline Status InsertFull(
277
+ const Slice& key, TValuePtr value, size_t charge,
278
+ TypedHandle** handle = nullptr, Priority priority = Priority::LOW,
279
+ CacheTier lowest_used_cache_tier = CacheTier::kNonVolatileBlockTier) {
280
+ auto untyped_handle = reinterpret_cast<Handle**>(handle);
281
+ auto helper = lowest_used_cache_tier == CacheTier::kNonVolatileBlockTier
282
+ ? &kFullHelper
283
+ : &kBasicHelper;
284
+ return this->cache_->Insert(key, UpCastValue(value), helper, charge,
285
+ untyped_handle, priority);
286
+ }
287
+
288
+ // Like SecondaryCache::InsertSaved, with SecondaryCache compatibility
289
+ // (subject to CacheTier).
290
+ inline Status InsertSaved(
291
+ const Slice& key, const Slice& data, TCreateContext* create_context,
292
+ Priority priority = Priority::LOW,
293
+ CacheTier lowest_used_cache_tier = CacheTier::kNonVolatileBlockTier,
294
+ size_t* out_charge = nullptr) {
295
+ ObjectPtr value;
296
+ size_t charge;
297
+ Status st = kFullHelper.create_cb(data, create_context,
298
+ this->cache_->memory_allocator(), &value,
299
+ &charge);
300
+ if (out_charge) {
301
+ *out_charge = charge;
302
+ }
303
+ if (st.ok()) {
304
+ st = InsertFull(key, DownCastValue(value), charge, nullptr /*handle*/,
305
+ priority, lowest_used_cache_tier);
306
+ } else {
307
+ kFullHelper.del_cb(value, this->cache_->memory_allocator());
308
+ }
309
+ return st;
310
+ }
311
+
312
+ // Lookup with SecondaryCache support (subject to CacheTier).
313
+ // (Basic Lookup() also inherited.)
314
+ inline TypedHandle* LookupFull(
315
+ const Slice& key, TCreateContext* create_context = nullptr,
316
+ Priority priority = Priority::LOW, bool wait = true,
317
+ Statistics* stats = nullptr,
318
+ CacheTier lowest_used_cache_tier = CacheTier::kNonVolatileBlockTier) {
319
+ if (lowest_used_cache_tier == CacheTier::kNonVolatileBlockTier) {
320
+ return reinterpret_cast<TypedHandle*>(this->cache_->Lookup(
321
+ key, &kFullHelper, create_context, priority, wait, stats));
322
+ } else {
323
+ return BasicTypedCacheInterface<TValue, kRole, CachePtr>::Lookup(key,
324
+ stats);
325
+ }
326
+ }
327
+ };
328
+
329
+ // FullTypedSharedCacheInterface - Like FullTypedCacheInterface but with a
330
+ // shared_ptr<Cache> for keeping Cache alive.
331
+ template <class TValue, class TCreateContext,
332
+ CacheEntryRole kRole = TValue::kCacheEntryRole>
333
+ using FullTypedSharedCacheInterface =
334
+ FullTypedCacheInterface<TValue, TCreateContext, kRole,
335
+ std::shared_ptr<Cache>>;
336
+
337
+ #undef CACHE_TYPE_DEFS
338
+
339
+ } // namespace ROCKSDB_NAMESPACE
@@ -13,12 +13,6 @@
13
13
 
14
14
  namespace ROCKSDB_NAMESPACE {
15
15
 
16
- std::unique_ptr<BlobContents> BlobContents::Create(
17
- CacheAllocationPtr&& allocation, size_t size) {
18
- return std::unique_ptr<BlobContents>(
19
- new BlobContents(std::move(allocation), size));
20
- }
21
-
22
16
  size_t BlobContents::ApproximateMemoryUsage() const {
23
17
  size_t usage = 0;
24
18
 
@@ -45,46 +39,4 @@ size_t BlobContents::ApproximateMemoryUsage() const {
45
39
  return usage;
46
40
  }
47
41
 
48
- size_t BlobContents::SizeCallback(void* obj) {
49
- assert(obj);
50
-
51
- return static_cast<const BlobContents*>(obj)->size();
52
- }
53
-
54
- Status BlobContents::SaveToCallback(void* from_obj, size_t from_offset,
55
- size_t length, void* out) {
56
- assert(from_obj);
57
-
58
- const BlobContents* buf = static_cast<const BlobContents*>(from_obj);
59
- assert(buf->size() >= from_offset + length);
60
-
61
- memcpy(out, buf->data().data() + from_offset, length);
62
-
63
- return Status::OK();
64
- }
65
-
66
- Cache::CacheItemHelper* BlobContents::GetCacheItemHelper() {
67
- static Cache::CacheItemHelper cache_helper(
68
- &SizeCallback, &SaveToCallback,
69
- GetCacheEntryDeleterForRole<BlobContents, CacheEntryRole::kBlobValue>());
70
-
71
- return &cache_helper;
72
- }
73
-
74
- Status BlobContents::CreateCallback(CacheAllocationPtr&& allocation,
75
- const void* buf, size_t size,
76
- void** out_obj, size_t* charge) {
77
- assert(allocation);
78
-
79
- memcpy(allocation.get(), buf, size);
80
-
81
- std::unique_ptr<BlobContents> obj = Create(std::move(allocation), size);
82
- BlobContents* const contents = obj.release();
83
-
84
- *out_obj = contents;
85
- *charge = contents->ApproximateMemoryUsage();
86
-
87
- return Status::OK();
88
- }
89
-
90
42
  } // namespace ROCKSDB_NAMESPACE
@@ -18,8 +18,8 @@ namespace ROCKSDB_NAMESPACE {
18
18
  // A class representing a single uncompressed value read from a blob file.
19
19
  class BlobContents {
20
20
  public:
21
- static std::unique_ptr<BlobContents> Create(CacheAllocationPtr&& allocation,
22
- size_t size);
21
+ BlobContents(CacheAllocationPtr&& allocation, size_t size)
22
+ : allocation_(std::move(allocation)), data_(allocation_.get(), size) {}
23
23
 
24
24
  BlobContents(const BlobContents&) = delete;
25
25
  BlobContents& operator=(const BlobContents&) = delete;
@@ -34,23 +34,26 @@ class BlobContents {
34
34
 
35
35
  size_t ApproximateMemoryUsage() const;
36
36
 
37
- // Callbacks for secondary cache
38
- static size_t SizeCallback(void* obj);
39
-
40
- static Status SaveToCallback(void* from_obj, size_t from_offset,
41
- size_t length, void* out);
42
-
43
- static Cache::CacheItemHelper* GetCacheItemHelper();
44
-
45
- static Status CreateCallback(CacheAllocationPtr&& allocation, const void* buf,
46
- size_t size, void** out_obj, size_t* charge);
37
+ // For TypedCacheInterface
38
+ const Slice& ContentSlice() const { return data_; }
39
+ static constexpr CacheEntryRole kCacheEntryRole = CacheEntryRole::kBlobValue;
47
40
 
48
41
  private:
49
- BlobContents(CacheAllocationPtr&& allocation, size_t size)
50
- : allocation_(std::move(allocation)), data_(allocation_.get(), size) {}
51
-
52
42
  CacheAllocationPtr allocation_;
53
43
  Slice data_;
54
44
  };
55
45
 
46
+ class BlobContentsCreator : public Cache::CreateContext {
47
+ public:
48
+ static void Create(std::unique_ptr<BlobContents>* out, size_t* out_charge,
49
+ const Slice& contents, MemoryAllocator* alloc) {
50
+ auto raw = new BlobContents(AllocateAndCopyBlock(contents, alloc),
51
+ contents.size());
52
+ out->reset(raw);
53
+ if (out_charge) {
54
+ *out_charge = raw->ApproximateMemoryUsage();
55
+ }
56
+ }
57
+ };
58
+
56
59
  } // namespace ROCKSDB_NAMESPACE
@@ -123,10 +123,6 @@ class BlobCountingIterator : public InternalIterator {
123
123
  return iter_->GetProperty(prop_name, prop);
124
124
  }
125
125
 
126
- bool IsDeleteRangeSentinelKey() const override {
127
- return iter_->IsDeleteRangeSentinelKey();
128
- }
129
-
130
126
  private:
131
127
  void UpdateAndCountBlobIfNeeded() {
132
128
  assert(!iter_->Valid() || iter_->status().ok());
@@ -134,13 +130,6 @@ class BlobCountingIterator : public InternalIterator {
134
130
  if (!iter_->Valid()) {
135
131
  status_ = iter_->status();
136
132
  return;
137
- } else if (iter_->IsDeleteRangeSentinelKey()) {
138
- // CompactionMergingIterator emits range tombstones, and range tombstone
139
- // keys can be truncated at file boundaries. This means the range
140
- // tombstone keys can have op_type kTypeBlobIndex.
141
- // This could crash the ProcessInFlow() call below since
142
- // value is empty for these keys.
143
- return;
144
133
  }
145
134
 
146
135
  TEST_SYNC_POINT(
@@ -13,6 +13,7 @@
13
13
  #include "db/blob/blob_index.h"
14
14
  #include "db/blob/blob_log_format.h"
15
15
  #include "db/blob/blob_log_writer.h"
16
+ #include "db/blob/blob_source.h"
16
17
  #include "db/event_helpers.h"
17
18
  #include "db/version_set.h"
18
19
  #include "file/filename.h"
@@ -393,7 +394,7 @@ Status BlobFileBuilder::PutBlobIntoCacheIfNeeded(const Slice& blob,
393
394
  uint64_t blob_offset) const {
394
395
  Status s = Status::OK();
395
396
 
396
- auto blob_cache = immutable_options_->blob_cache;
397
+ BlobSource::SharedCacheInterface blob_cache{immutable_options_->blob_cache};
397
398
  auto statistics = immutable_options_->statistics.get();
398
399
  bool warm_cache =
399
400
  prepopulate_blob_cache_ == PrepopulateBlobCache::kFlushOnly &&
@@ -407,34 +408,12 @@ Status BlobFileBuilder::PutBlobIntoCacheIfNeeded(const Slice& blob,
407
408
 
408
409
  const Cache::Priority priority = Cache::Priority::BOTTOM;
409
410
 
410
- // Objects to be put into the cache have to be heap-allocated and
411
- // self-contained, i.e. own their contents. The Cache has to be able to
412
- // take unique ownership of them.
413
- CacheAllocationPtr allocation =
414
- AllocateBlock(blob.size(), blob_cache->memory_allocator());
415
- memcpy(allocation.get(), blob.data(), blob.size());
416
- std::unique_ptr<BlobContents> buf =
417
- BlobContents::Create(std::move(allocation), blob.size());
418
-
419
- Cache::CacheItemHelper* const cache_item_helper =
420
- BlobContents::GetCacheItemHelper();
421
- assert(cache_item_helper);
422
-
423
- if (immutable_options_->lowest_used_cache_tier ==
424
- CacheTier::kNonVolatileBlockTier) {
425
- s = blob_cache->Insert(key, buf.get(), cache_item_helper,
426
- buf->ApproximateMemoryUsage(),
427
- nullptr /* cache_handle */, priority);
428
- } else {
429
- s = blob_cache->Insert(key, buf.get(), buf->ApproximateMemoryUsage(),
430
- cache_item_helper->del_cb,
431
- nullptr /* cache_handle */, priority);
432
- }
411
+ s = blob_cache.InsertSaved(key, blob, nullptr /*context*/, priority,
412
+ immutable_options_->lowest_used_cache_tier);
433
413
 
434
414
  if (s.ok()) {
435
415
  RecordTick(statistics, BLOB_DB_CACHE_ADD);
436
- RecordTick(statistics, BLOB_DB_CACHE_BYTES_WRITE, buf->size());
437
- buf.release();
416
+ RecordTick(statistics, BLOB_DB_CACHE_BYTES_WRITE, blob.size());
438
417
  } else {
439
418
  RecordTick(statistics, BLOB_DB_CACHE_ADD_FAILURES);
440
419
  }
@@ -42,13 +42,13 @@ Status BlobFileCache::GetBlobFileReader(
42
42
  assert(blob_file_reader);
43
43
  assert(blob_file_reader->IsEmpty());
44
44
 
45
- const Slice key = GetSlice(&blob_file_number);
45
+ const Slice key = GetSliceForKey(&blob_file_number);
46
46
 
47
47
  assert(cache_);
48
48
 
49
- Cache::Handle* handle = cache_->Lookup(key);
49
+ TypedHandle* handle = cache_.Lookup(key);
50
50
  if (handle) {
51
- *blob_file_reader = CacheHandleGuard<BlobFileReader>(cache_, handle);
51
+ *blob_file_reader = cache_.Guard(handle);
52
52
  return Status::OK();
53
53
  }
54
54
 
@@ -57,9 +57,9 @@ Status BlobFileCache::GetBlobFileReader(
57
57
  // Check again while holding mutex
58
58
  MutexLock lock(mutex_.get(key));
59
59
 
60
- handle = cache_->Lookup(key);
60
+ handle = cache_.Lookup(key);
61
61
  if (handle) {
62
- *blob_file_reader = CacheHandleGuard<BlobFileReader>(cache_, handle);
62
+ *blob_file_reader = cache_.Guard(handle);
63
63
  return Status::OK();
64
64
  }
65
65
 
@@ -84,8 +84,7 @@ Status BlobFileCache::GetBlobFileReader(
84
84
  {
85
85
  constexpr size_t charge = 1;
86
86
 
87
- const Status s = cache_->Insert(key, reader.get(), charge,
88
- &DeleteCacheEntry<BlobFileReader>, &handle);
87
+ const Status s = cache_.Insert(key, reader.get(), charge, &handle);
89
88
  if (!s.ok()) {
90
89
  RecordTick(statistics, NO_FILE_ERRORS);
91
90
  return s;
@@ -94,7 +93,7 @@ Status BlobFileCache::GetBlobFileReader(
94
93
 
95
94
  reader.release();
96
95
 
97
- *blob_file_reader = CacheHandleGuard<BlobFileReader>(cache_, handle);
96
+ *blob_file_reader = cache_.Guard(handle);
98
97
 
99
98
  return Status::OK();
100
99
  }