@nxtedition/rocksdb 8.0.1 → 8.0.3
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.
- package/deps/rocksdb/rocksdb/CMakeLists.txt +2 -1
- package/deps/rocksdb/rocksdb/Makefile +2 -2
- package/deps/rocksdb/rocksdb/TARGETS +4 -2
- package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +0 -5
- package/deps/rocksdb/rocksdb/cache/cache_test.cc +8 -29
- package/deps/rocksdb/rocksdb/cache/clock_cache.cc +146 -0
- package/deps/rocksdb/rocksdb/cache/clock_cache.h +13 -1
- package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +20 -146
- package/deps/rocksdb/rocksdb/cache/secondary_cache.cc +32 -0
- package/deps/rocksdb/rocksdb/db/blob/blob_counting_iterator.h +11 -0
- package/deps/rocksdb/rocksdb/db/column_family.cc +11 -9
- package/deps/rocksdb/rocksdb/db/column_family.h +20 -0
- package/deps/rocksdb/rocksdb/db/compaction/clipping_iterator.h +5 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +13 -33
- package/deps/rocksdb/rocksdb/db/compaction/compaction.h +5 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +27 -8
- package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +17 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +2 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +4 -2
- package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +8 -6
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +65 -7
- package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +5 -0
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +10 -32
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +28 -47
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +28 -22
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +8 -14
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +8 -8
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +5 -4
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +170 -140
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +5 -1
- package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +5 -4
- package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +8 -2
- package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +8 -0
- package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +266 -138
- package/deps/rocksdb/rocksdb/db/corruption_test.cc +86 -1
- package/deps/rocksdb/rocksdb/db/db_basic_test.cc +72 -5
- package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +119 -10
- package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +585 -264
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +46 -18
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +5 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +6 -15
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +1 -1
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +3 -0
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +8 -8
- package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +10 -0
- package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +250 -2
- package/deps/rocksdb/rocksdb/db/db_test.cc +3 -0
- package/deps/rocksdb/rocksdb/db/db_test2.cc +307 -8
- package/deps/rocksdb/rocksdb/db/db_wal_test.cc +129 -0
- package/deps/rocksdb/rocksdb/db/db_with_timestamp_compaction_test.cc +21 -0
- package/deps/rocksdb/rocksdb/db/dbformat.cc +25 -0
- package/deps/rocksdb/rocksdb/db/dbformat.h +2 -0
- package/deps/rocksdb/rocksdb/db/experimental.cc +1 -1
- package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +5 -2
- package/deps/rocksdb/rocksdb/db/flush_job.cc +5 -2
- package/deps/rocksdb/rocksdb/db/history_trimming_iterator.h +4 -0
- package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +56 -53
- package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +3 -4
- package/deps/rocksdb/rocksdb/db/merge_helper.cc +4 -0
- package/deps/rocksdb/rocksdb/db/periodic_task_scheduler_test.cc +10 -10
- package/deps/rocksdb/rocksdb/db/repair.cc +64 -22
- package/deps/rocksdb/rocksdb/db/repair_test.cc +54 -0
- package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +26 -26
- package/deps/rocksdb/rocksdb/db/table_cache.cc +2 -0
- package/deps/rocksdb/rocksdb/db/table_properties_collector.h +3 -1
- package/deps/rocksdb/rocksdb/db/version_builder.cc +90 -43
- package/deps/rocksdb/rocksdb/db/version_builder.h +20 -0
- package/deps/rocksdb/rocksdb/db/version_builder_test.cc +190 -67
- package/deps/rocksdb/rocksdb/db/version_edit.cc +15 -1
- package/deps/rocksdb/rocksdb/db/version_edit.h +16 -4
- package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +41 -11
- package/deps/rocksdb/rocksdb/db/version_edit_handler.h +27 -12
- package/deps/rocksdb/rocksdb/db/version_edit_test.cc +18 -16
- package/deps/rocksdb/rocksdb/db/version_set.cc +212 -35
- package/deps/rocksdb/rocksdb/db/version_set.h +34 -4
- package/deps/rocksdb/rocksdb/db/version_set_test.cc +45 -25
- package/deps/rocksdb/rocksdb/db/write_thread.cc +5 -2
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +0 -1
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +0 -4
- package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +12 -17
- package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +6 -4
- package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +1 -0
- package/deps/rocksdb/rocksdb/file/prefetch_test.cc +0 -48
- package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +8 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +196 -171
- package/deps/rocksdb/rocksdb/include/rocksdb/db.h +6 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/metadata.h +9 -3
- package/deps/rocksdb/rocksdb/include/rocksdb/options.h +25 -18
- package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +27 -5
- package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +5 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/status.h +3 -0
- package/deps/rocksdb/rocksdb/include/rocksdb/version.h +1 -1
- package/deps/rocksdb/rocksdb/logging/logging.h +13 -19
- package/deps/rocksdb/rocksdb/memory/arena.cc +4 -3
- package/deps/rocksdb/rocksdb/memory/arena_test.cc +30 -0
- package/deps/rocksdb/rocksdb/monitoring/statistics.cc +3 -1
- package/deps/rocksdb/rocksdb/monitoring/stats_history_test.cc +26 -26
- package/deps/rocksdb/rocksdb/src.mk +2 -1
- package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.cc +3 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +3 -2
- package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +1 -1
- package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +3 -3
- package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.cc +142 -0
- package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.h +241 -0
- package/deps/rocksdb/rocksdb/table/format.cc +24 -20
- package/deps/rocksdb/rocksdb/table/format.h +5 -2
- package/deps/rocksdb/rocksdb/table/merging_iterator.cc +97 -115
- package/deps/rocksdb/rocksdb/table/merging_iterator.h +82 -1
- package/deps/rocksdb/rocksdb/table/meta_blocks.cc +2 -2
- package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +1 -1
- package/deps/rocksdb/rocksdb/table/table_test.cc +7 -6
- package/deps/rocksdb/rocksdb/test_util/testutil.h +10 -0
- package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +0 -6
- package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer.h +2 -2
- package/deps/rocksdb/rocksdb/util/bloom_test.cc +1 -1
- package/deps/rocksdb/rocksdb/util/status.cc +7 -0
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +5 -0
- package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +4 -0
- package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +7 -67
- package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.h +1 -3
- package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.cc +1 -0
- package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +59 -0
- package/deps/rocksdb/rocksdb.gyp +2 -1
- package/package.json +1 -1
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.node +0 -0
- package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +0 -580
- package/deps/rocksdb/rocksdb/cache/fast_lru_cache.h +0 -476
|
@@ -653,8 +653,8 @@ set(SOURCES
|
|
|
653
653
|
cache/charged_cache.cc
|
|
654
654
|
cache/clock_cache.cc
|
|
655
655
|
cache/compressed_secondary_cache.cc
|
|
656
|
-
cache/fast_lru_cache.cc
|
|
657
656
|
cache/lru_cache.cc
|
|
657
|
+
cache/secondary_cache.cc
|
|
658
658
|
cache/sharded_cache.cc
|
|
659
659
|
db/arena_wrapped_db_iter.cc
|
|
660
660
|
db/blob/blob_contents.cc
|
|
@@ -831,6 +831,7 @@ set(SOURCES
|
|
|
831
831
|
table/get_context.cc
|
|
832
832
|
table/iterator.cc
|
|
833
833
|
table/merging_iterator.cc
|
|
834
|
+
table/compaction_merging_iterator.cc
|
|
834
835
|
table/meta_blocks.cc
|
|
835
836
|
table/persistent_cache_helper.cc
|
|
836
837
|
table/plain/plain_table_bloom.cc
|
|
@@ -2092,8 +2092,8 @@ ROCKSDB_JAVADOCS_JAR = rocksdbjni-$(ROCKSDB_JAVA_VERSION)-javadoc.jar
|
|
|
2092
2092
|
ROCKSDB_SOURCES_JAR = rocksdbjni-$(ROCKSDB_JAVA_VERSION)-sources.jar
|
|
2093
2093
|
SHA256_CMD = sha256sum
|
|
2094
2094
|
|
|
2095
|
-
ZLIB_VER ?= 1.2.
|
|
2096
|
-
ZLIB_SHA256 ?=
|
|
2095
|
+
ZLIB_VER ?= 1.2.13
|
|
2096
|
+
ZLIB_SHA256 ?= b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30
|
|
2097
2097
|
ZLIB_DOWNLOAD_BASE ?= http://zlib.net
|
|
2098
2098
|
BZIP2_VER ?= 1.0.8
|
|
2099
2099
|
BZIP2_SHA256 ?= ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269
|
|
@@ -16,8 +16,8 @@ cpp_library_wrapper(name="rocksdb_lib", srcs=[
|
|
|
16
16
|
"cache/charged_cache.cc",
|
|
17
17
|
"cache/clock_cache.cc",
|
|
18
18
|
"cache/compressed_secondary_cache.cc",
|
|
19
|
-
"cache/fast_lru_cache.cc",
|
|
20
19
|
"cache/lru_cache.cc",
|
|
20
|
+
"cache/secondary_cache.cc",
|
|
21
21
|
"cache/sharded_cache.cc",
|
|
22
22
|
"db/arena_wrapped_db_iter.cc",
|
|
23
23
|
"db/blob/blob_contents.cc",
|
|
@@ -198,6 +198,7 @@ cpp_library_wrapper(name="rocksdb_lib", srcs=[
|
|
|
198
198
|
"table/block_based/reader_common.cc",
|
|
199
199
|
"table/block_based/uncompression_dict_reader.cc",
|
|
200
200
|
"table/block_fetcher.cc",
|
|
201
|
+
"table/compaction_merging_iterator.cc",
|
|
201
202
|
"table/cuckoo/cuckoo_table_builder.cc",
|
|
202
203
|
"table/cuckoo/cuckoo_table_factory.cc",
|
|
203
204
|
"table/cuckoo/cuckoo_table_reader.cc",
|
|
@@ -356,8 +357,8 @@ cpp_library_wrapper(name="rocksdb_whole_archive_lib", srcs=[
|
|
|
356
357
|
"cache/charged_cache.cc",
|
|
357
358
|
"cache/clock_cache.cc",
|
|
358
359
|
"cache/compressed_secondary_cache.cc",
|
|
359
|
-
"cache/fast_lru_cache.cc",
|
|
360
360
|
"cache/lru_cache.cc",
|
|
361
|
+
"cache/secondary_cache.cc",
|
|
361
362
|
"cache/sharded_cache.cc",
|
|
362
363
|
"db/arena_wrapped_db_iter.cc",
|
|
363
364
|
"db/blob/blob_contents.cc",
|
|
@@ -538,6 +539,7 @@ cpp_library_wrapper(name="rocksdb_whole_archive_lib", srcs=[
|
|
|
538
539
|
"table/block_based/reader_common.cc",
|
|
539
540
|
"table/block_based/uncompression_dict_reader.cc",
|
|
540
541
|
"table/block_fetcher.cc",
|
|
542
|
+
"table/compaction_merging_iterator.cc",
|
|
541
543
|
"table/cuckoo/cuckoo_table_builder.cc",
|
|
542
544
|
"table/cuckoo/cuckoo_table_factory.cc",
|
|
543
545
|
"table/cuckoo/cuckoo_table_reader.cc",
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
#include <set>
|
|
14
14
|
#include <sstream>
|
|
15
15
|
|
|
16
|
-
#include "cache/fast_lru_cache.h"
|
|
17
16
|
#include "db/db_impl/db_impl.h"
|
|
18
17
|
#include "monitoring/histogram.h"
|
|
19
18
|
#include "port/port.h"
|
|
@@ -297,10 +296,6 @@ class CacheBench {
|
|
|
297
296
|
cache_ = HyperClockCacheOptions(FLAGS_cache_size, FLAGS_value_bytes,
|
|
298
297
|
FLAGS_num_shard_bits)
|
|
299
298
|
.MakeSharedCache();
|
|
300
|
-
} else if (FLAGS_cache_type == "fast_lru_cache") {
|
|
301
|
-
cache_ = NewFastLRUCache(
|
|
302
|
-
FLAGS_cache_size, FLAGS_value_bytes, FLAGS_num_shard_bits,
|
|
303
|
-
false /*strict_capacity_limit*/, kDefaultCacheMetadataChargePolicy);
|
|
304
299
|
} else if (FLAGS_cache_type == "lru_cache") {
|
|
305
300
|
LRUCacheOptions opts(FLAGS_cache_size, FLAGS_num_shard_bits,
|
|
306
301
|
false /* strict_capacity_limit */,
|
|
@@ -15,15 +15,14 @@
|
|
|
15
15
|
#include <string>
|
|
16
16
|
#include <vector>
|
|
17
17
|
|
|
18
|
-
#include "cache/fast_lru_cache.h"
|
|
19
18
|
#include "cache/lru_cache.h"
|
|
20
19
|
#include "port/stack_trace.h"
|
|
21
20
|
#include "test_util/testharness.h"
|
|
22
21
|
#include "util/coding.h"
|
|
23
22
|
#include "util/string_util.h"
|
|
24
23
|
|
|
25
|
-
//
|
|
26
|
-
//
|
|
24
|
+
// HyperClockCache only supports 16-byte keys, so some of the tests
|
|
25
|
+
// originally written for LRUCache do not work on the other caches.
|
|
27
26
|
// Those tests were adapted to use 16-byte keys. We kept the original ones.
|
|
28
27
|
// TODO: Remove the original tests if they ever become unused.
|
|
29
28
|
|
|
@@ -76,7 +75,6 @@ void EraseDeleter2(const Slice& /*key*/, void* value) {
|
|
|
76
75
|
|
|
77
76
|
const std::string kLRU = "lru";
|
|
78
77
|
const std::string kHyperClock = "hyper_clock";
|
|
79
|
-
const std::string kFast = "fast";
|
|
80
78
|
|
|
81
79
|
} // anonymous namespace
|
|
82
80
|
|
|
@@ -86,7 +84,7 @@ class CacheTest : public testing::TestWithParam<std::string> {
|
|
|
86
84
|
static std::string type_;
|
|
87
85
|
|
|
88
86
|
static void Deleter(const Slice& key, void* v) {
|
|
89
|
-
if (type_ ==
|
|
87
|
+
if (type_ == kHyperClock) {
|
|
90
88
|
current_->deleted_keys_.push_back(DecodeKey16Bytes(key));
|
|
91
89
|
} else {
|
|
92
90
|
current_->deleted_keys_.push_back(DecodeKey32Bits(key));
|
|
@@ -126,11 +124,6 @@ class CacheTest : public testing::TestWithParam<std::string> {
|
|
|
126
124
|
capacity, estimated_value_size_ /*estimated_value_size*/)
|
|
127
125
|
.MakeSharedCache();
|
|
128
126
|
}
|
|
129
|
-
if (type == kFast) {
|
|
130
|
-
return NewFastLRUCache(
|
|
131
|
-
capacity, estimated_value_size_, -1 /*num_shard_bits*/,
|
|
132
|
-
false /*strict_capacity_limit*/, kDefaultCacheMetadataChargePolicy);
|
|
133
|
-
}
|
|
134
127
|
return nullptr;
|
|
135
128
|
}
|
|
136
129
|
|
|
@@ -153,11 +146,6 @@ class CacheTest : public testing::TestWithParam<std::string> {
|
|
|
153
146
|
nullptr /*allocator*/, charge_policy)
|
|
154
147
|
.MakeSharedCache();
|
|
155
148
|
}
|
|
156
|
-
if (type == kFast) {
|
|
157
|
-
return NewFastLRUCache(capacity, 1 /*estimated_value_size*/,
|
|
158
|
-
num_shard_bits, strict_capacity_limit,
|
|
159
|
-
charge_policy);
|
|
160
|
-
}
|
|
161
149
|
return nullptr;
|
|
162
150
|
}
|
|
163
151
|
|
|
@@ -167,7 +155,7 @@ class CacheTest : public testing::TestWithParam<std::string> {
|
|
|
167
155
|
// LRUCache doesn't, so the encoding depends on the cache type.
|
|
168
156
|
std::string EncodeKey(int k) {
|
|
169
157
|
auto type = GetParam();
|
|
170
|
-
if (type ==
|
|
158
|
+
if (type == kHyperClock) {
|
|
171
159
|
return EncodeKey16Bytes(k);
|
|
172
160
|
} else {
|
|
173
161
|
return EncodeKey32Bits(k);
|
|
@@ -176,7 +164,7 @@ class CacheTest : public testing::TestWithParam<std::string> {
|
|
|
176
164
|
|
|
177
165
|
int DecodeKey(const Slice& k) {
|
|
178
166
|
auto type = GetParam();
|
|
179
|
-
if (type ==
|
|
167
|
+
if (type == kHyperClock) {
|
|
180
168
|
return DecodeKey16Bytes(k);
|
|
181
169
|
} else {
|
|
182
170
|
return DecodeKey32Bits(k);
|
|
@@ -733,7 +721,7 @@ TEST_P(CacheTest, ReleaseWithoutErase) {
|
|
|
733
721
|
|
|
734
722
|
TEST_P(CacheTest, SetCapacity) {
|
|
735
723
|
auto type = GetParam();
|
|
736
|
-
if (type ==
|
|
724
|
+
if (type == kHyperClock) {
|
|
737
725
|
ROCKSDB_GTEST_BYPASS(
|
|
738
726
|
"FastLRUCache and HyperClockCache don't support arbitrary capacity "
|
|
739
727
|
"adjustments.");
|
|
@@ -787,14 +775,6 @@ TEST_P(CacheTest, SetCapacity) {
|
|
|
787
775
|
}
|
|
788
776
|
|
|
789
777
|
TEST_P(LRUCacheTest, SetStrictCapacityLimit) {
|
|
790
|
-
auto type = GetParam();
|
|
791
|
-
if (type == kFast) {
|
|
792
|
-
ROCKSDB_GTEST_BYPASS(
|
|
793
|
-
"FastLRUCache only supports a limited number of "
|
|
794
|
-
"inserts beyond "
|
|
795
|
-
"capacity.");
|
|
796
|
-
return;
|
|
797
|
-
}
|
|
798
778
|
// test1: set the flag to false. Insert more keys than capacity. See if they
|
|
799
779
|
// all go through.
|
|
800
780
|
std::shared_ptr<Cache> cache = NewCache(5, 0, false);
|
|
@@ -1045,9 +1025,8 @@ TEST_P(CacheTest, GetChargeAndDeleter) {
|
|
|
1045
1025
|
}
|
|
1046
1026
|
|
|
1047
1027
|
INSTANTIATE_TEST_CASE_P(CacheTestInstance, CacheTest,
|
|
1048
|
-
testing::Values(kLRU, kHyperClock
|
|
1049
|
-
INSTANTIATE_TEST_CASE_P(CacheTestInstance, LRUCacheTest,
|
|
1050
|
-
testing::Values(kLRU, kFast));
|
|
1028
|
+
testing::Values(kLRU, kHyperClock));
|
|
1029
|
+
INSTANTIATE_TEST_CASE_P(CacheTestInstance, LRUCacheTest, testing::Values(kLRU));
|
|
1051
1030
|
|
|
1052
1031
|
} // namespace ROCKSDB_NAMESPACE
|
|
1053
1032
|
|
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
|
|
12
12
|
#include <cassert>
|
|
13
13
|
#include <functional>
|
|
14
|
+
#include <numeric>
|
|
14
15
|
|
|
15
16
|
#include "cache/cache_key.h"
|
|
17
|
+
#include "logging/logging.h"
|
|
16
18
|
#include "monitoring/perf_context_imp.h"
|
|
17
19
|
#include "monitoring/statistics.h"
|
|
18
20
|
#include "port/lang.h"
|
|
@@ -1152,6 +1154,16 @@ size_t ClockCacheShard<Table>::GetUsage() const {
|
|
|
1152
1154
|
return table_.GetUsage();
|
|
1153
1155
|
}
|
|
1154
1156
|
|
|
1157
|
+
template <class Table>
|
|
1158
|
+
size_t ClockCacheShard<Table>::GetDetachedUsage() const {
|
|
1159
|
+
return table_.GetDetachedUsage();
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
template <class Table>
|
|
1163
|
+
size_t ClockCacheShard<Table>::GetCapacity() const {
|
|
1164
|
+
return capacity_;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1155
1167
|
template <class Table>
|
|
1156
1168
|
size_t ClockCacheShard<Table>::GetPinnedUsage() const {
|
|
1157
1169
|
// Computes the pinned usage by scanning the whole hash table. This
|
|
@@ -1186,6 +1198,11 @@ size_t ClockCacheShard<Table>::GetOccupancyCount() const {
|
|
|
1186
1198
|
return table_.GetOccupancy();
|
|
1187
1199
|
}
|
|
1188
1200
|
|
|
1201
|
+
template <class Table>
|
|
1202
|
+
size_t ClockCacheShard<Table>::GetOccupancyLimit() const {
|
|
1203
|
+
return table_.GetOccupancyLimit();
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1189
1206
|
template <class Table>
|
|
1190
1207
|
size_t ClockCacheShard<Table>::GetTableAddressCount() const {
|
|
1191
1208
|
return table_.GetTableSize();
|
|
@@ -1227,6 +1244,135 @@ Cache::DeleterFn HyperClockCache::GetDeleter(Handle* handle) const {
|
|
|
1227
1244
|
return h->deleter;
|
|
1228
1245
|
}
|
|
1229
1246
|
|
|
1247
|
+
namespace {
|
|
1248
|
+
|
|
1249
|
+
// For each cache shard, estimate what the table load factor would be if
|
|
1250
|
+
// cache filled to capacity with average entries. This is considered
|
|
1251
|
+
// indicative of a potential problem if the shard is essentially operating
|
|
1252
|
+
// "at limit", which we define as high actual usage (>80% of capacity)
|
|
1253
|
+
// or actual occupancy very close to limit (>95% of limit).
|
|
1254
|
+
// Also, for each shard compute the recommended estimated_entry_charge,
|
|
1255
|
+
// and keep the minimum one for use as overall recommendation.
|
|
1256
|
+
void AddShardEvaluation(const HyperClockCache::Shard& shard,
|
|
1257
|
+
std::vector<double>& predicted_load_factors,
|
|
1258
|
+
size_t& min_recommendation) {
|
|
1259
|
+
size_t usage = shard.GetUsage() - shard.GetDetachedUsage();
|
|
1260
|
+
size_t capacity = shard.GetCapacity();
|
|
1261
|
+
double usage_ratio = 1.0 * usage / capacity;
|
|
1262
|
+
|
|
1263
|
+
size_t occupancy = shard.GetOccupancyCount();
|
|
1264
|
+
size_t occ_limit = shard.GetOccupancyLimit();
|
|
1265
|
+
double occ_ratio = 1.0 * occupancy / occ_limit;
|
|
1266
|
+
if (usage == 0 || occupancy == 0 || (usage_ratio < 0.8 && occ_ratio < 0.95)) {
|
|
1267
|
+
// Skip as described above
|
|
1268
|
+
return;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
// If filled to capacity, what would the occupancy ratio be?
|
|
1272
|
+
double ratio = occ_ratio / usage_ratio;
|
|
1273
|
+
// Given max load factor, what that load factor be?
|
|
1274
|
+
double lf = ratio * kStrictLoadFactor;
|
|
1275
|
+
predicted_load_factors.push_back(lf);
|
|
1276
|
+
|
|
1277
|
+
// Update min_recommendation also
|
|
1278
|
+
size_t recommendation = usage / occupancy;
|
|
1279
|
+
min_recommendation = std::min(min_recommendation, recommendation);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
} // namespace
|
|
1283
|
+
|
|
1284
|
+
void HyperClockCache::ReportProblems(
|
|
1285
|
+
const std::shared_ptr<Logger>& info_log) const {
|
|
1286
|
+
uint32_t shard_count = GetNumShards();
|
|
1287
|
+
std::vector<double> predicted_load_factors;
|
|
1288
|
+
size_t min_recommendation = SIZE_MAX;
|
|
1289
|
+
const_cast<HyperClockCache*>(this)->ForEachShard(
|
|
1290
|
+
[&](HyperClockCache::Shard* shard) {
|
|
1291
|
+
AddShardEvaluation(*shard, predicted_load_factors, min_recommendation);
|
|
1292
|
+
});
|
|
1293
|
+
|
|
1294
|
+
if (predicted_load_factors.empty()) {
|
|
1295
|
+
// None operating "at limit" -> nothing to report
|
|
1296
|
+
return;
|
|
1297
|
+
}
|
|
1298
|
+
std::sort(predicted_load_factors.begin(), predicted_load_factors.end());
|
|
1299
|
+
|
|
1300
|
+
// First, if the average load factor is within spec, we aren't going to
|
|
1301
|
+
// complain about a few shards being out of spec.
|
|
1302
|
+
// NOTE: this is only the average among cache shards operating "at limit,"
|
|
1303
|
+
// which should be representative of what we care about. It it normal, even
|
|
1304
|
+
// desirable, for a cache to operate "at limit" so this should not create
|
|
1305
|
+
// selection bias. See AddShardEvaluation().
|
|
1306
|
+
// TODO: Consider detecting cases where decreasing the number of shards
|
|
1307
|
+
// would be good, e.g. serious imbalance among shards.
|
|
1308
|
+
double average_load_factor =
|
|
1309
|
+
std::accumulate(predicted_load_factors.begin(),
|
|
1310
|
+
predicted_load_factors.end(), 0.0) /
|
|
1311
|
+
shard_count;
|
|
1312
|
+
|
|
1313
|
+
constexpr double kLowSpecLoadFactor = kLoadFactor / 2;
|
|
1314
|
+
constexpr double kMidSpecLoadFactor = kLoadFactor / 1.414;
|
|
1315
|
+
if (average_load_factor > kLoadFactor) {
|
|
1316
|
+
// Out of spec => Consider reporting load factor too high
|
|
1317
|
+
// Estimate effective overall capacity loss due to enforcing occupancy limit
|
|
1318
|
+
double lost_portion = 0.0;
|
|
1319
|
+
int over_count = 0;
|
|
1320
|
+
for (double lf : predicted_load_factors) {
|
|
1321
|
+
if (lf > kStrictLoadFactor) {
|
|
1322
|
+
++over_count;
|
|
1323
|
+
lost_portion += (lf - kStrictLoadFactor) / lf / shard_count;
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
// >= 20% loss -> error
|
|
1327
|
+
// >= 10% loss -> consistent warning
|
|
1328
|
+
// >= 1% loss -> intermittent warning
|
|
1329
|
+
InfoLogLevel level = InfoLogLevel::INFO_LEVEL;
|
|
1330
|
+
bool report = true;
|
|
1331
|
+
if (lost_portion > 0.2) {
|
|
1332
|
+
level = InfoLogLevel::ERROR_LEVEL;
|
|
1333
|
+
} else if (lost_portion > 0.1) {
|
|
1334
|
+
level = InfoLogLevel::WARN_LEVEL;
|
|
1335
|
+
} else if (lost_portion > 0.01) {
|
|
1336
|
+
int report_percent = static_cast<int>(lost_portion * 100.0);
|
|
1337
|
+
if (Random::GetTLSInstance()->PercentTrue(report_percent)) {
|
|
1338
|
+
level = InfoLogLevel::WARN_LEVEL;
|
|
1339
|
+
}
|
|
1340
|
+
} else {
|
|
1341
|
+
// don't report
|
|
1342
|
+
report = false;
|
|
1343
|
+
}
|
|
1344
|
+
if (report) {
|
|
1345
|
+
ROCKS_LOG_AT_LEVEL(
|
|
1346
|
+
info_log, level,
|
|
1347
|
+
"HyperClockCache@%p unable to use estimated %.1f%% capacity because "
|
|
1348
|
+
"of "
|
|
1349
|
+
"full occupancy in %d/%u cache shards (estimated_entry_charge too "
|
|
1350
|
+
"high). Recommend estimated_entry_charge=%zu",
|
|
1351
|
+
this, lost_portion * 100.0, over_count, (unsigned)shard_count,
|
|
1352
|
+
min_recommendation);
|
|
1353
|
+
}
|
|
1354
|
+
} else if (average_load_factor < kLowSpecLoadFactor) {
|
|
1355
|
+
// Out of spec => Consider reporting load factor too low
|
|
1356
|
+
// But cautiously because low is not as big of a problem.
|
|
1357
|
+
|
|
1358
|
+
// Only report if highest occupancy shard is also below
|
|
1359
|
+
// spec and only if average is substantially out of spec
|
|
1360
|
+
if (predicted_load_factors.back() < kLowSpecLoadFactor &&
|
|
1361
|
+
average_load_factor < kLowSpecLoadFactor / 1.414) {
|
|
1362
|
+
InfoLogLevel level = InfoLogLevel::INFO_LEVEL;
|
|
1363
|
+
if (average_load_factor < kLowSpecLoadFactor / 2) {
|
|
1364
|
+
level = InfoLogLevel::WARN_LEVEL;
|
|
1365
|
+
}
|
|
1366
|
+
ROCKS_LOG_AT_LEVEL(
|
|
1367
|
+
info_log, level,
|
|
1368
|
+
"HyperClockCache@%p table has low occupancy at full capacity. Higher "
|
|
1369
|
+
"estimated_entry_charge (about %.1fx) would likely improve "
|
|
1370
|
+
"performance. Recommend estimated_entry_charge=%zu",
|
|
1371
|
+
this, kMidSpecLoadFactor / average_load_factor, min_recommendation);
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1230
1376
|
} // namespace clock_cache
|
|
1231
1377
|
|
|
1232
1378
|
// DEPRECATED (see public API)
|
|
@@ -32,7 +32,8 @@ namespace clock_cache {
|
|
|
32
32
|
// Forward declaration of friend class.
|
|
33
33
|
class ClockCacheTest;
|
|
34
34
|
|
|
35
|
-
// HyperClockCache is an
|
|
35
|
+
// HyperClockCache is an alternative to LRUCache specifically tailored for
|
|
36
|
+
// use as BlockBasedTableOptions::block_cache
|
|
36
37
|
//
|
|
37
38
|
// Benefits
|
|
38
39
|
// --------
|
|
@@ -439,6 +440,8 @@ class HyperClockTable {
|
|
|
439
440
|
return occupancy_.load(std::memory_order_relaxed);
|
|
440
441
|
}
|
|
441
442
|
|
|
443
|
+
size_t GetOccupancyLimit() const { return occupancy_limit_; }
|
|
444
|
+
|
|
442
445
|
size_t GetUsage() const { return usage_.load(std::memory_order_relaxed); }
|
|
443
446
|
|
|
444
447
|
size_t GetDetachedUsage() const {
|
|
@@ -611,12 +614,18 @@ class ALIGN_AS(CACHE_LINE_SIZE) ClockCacheShard final : public CacheShardBase {
|
|
|
611
614
|
|
|
612
615
|
void Erase(const Slice& key, const UniqueId64x2& hashed_key);
|
|
613
616
|
|
|
617
|
+
size_t GetCapacity() const;
|
|
618
|
+
|
|
614
619
|
size_t GetUsage() const;
|
|
615
620
|
|
|
621
|
+
size_t GetDetachedUsage() const;
|
|
622
|
+
|
|
616
623
|
size_t GetPinnedUsage() const;
|
|
617
624
|
|
|
618
625
|
size_t GetOccupancyCount() const;
|
|
619
626
|
|
|
627
|
+
size_t GetOccupancyLimit() const;
|
|
628
|
+
|
|
620
629
|
size_t GetTableAddressCount() const;
|
|
621
630
|
|
|
622
631
|
void ApplyToSomeEntries(
|
|
@@ -682,6 +691,9 @@ class HyperClockCache
|
|
|
682
691
|
size_t GetCharge(Handle* handle) const override;
|
|
683
692
|
|
|
684
693
|
DeleterFn GetDeleter(Handle* handle) const override;
|
|
694
|
+
|
|
695
|
+
void ReportProblems(
|
|
696
|
+
const std::shared_ptr<Logger>& /*info_log*/) const override;
|
|
685
697
|
}; // class HyperClockCache
|
|
686
698
|
|
|
687
699
|
} // namespace clock_cache
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
|
|
11
11
|
#include "cache/cache_key.h"
|
|
12
12
|
#include "cache/clock_cache.h"
|
|
13
|
-
#include "cache/fast_lru_cache.h"
|
|
14
13
|
#include "db/db_test_util.h"
|
|
15
14
|
#include "file/sst_file_manager_impl.h"
|
|
16
15
|
#include "port/port.h"
|
|
@@ -364,148 +363,6 @@ TEST_F(LRUCacheTest, EntriesWithPriority) {
|
|
|
364
363
|
ValidateLRUList({"x", "y", "g", "z", "d", "m"}, 2, 2, 2);
|
|
365
364
|
}
|
|
366
365
|
|
|
367
|
-
// TODO: FastLRUCache and ClockCache use the same tests. We can probably remove
|
|
368
|
-
// them from FastLRUCache after ClockCache becomes productive, and we don't plan
|
|
369
|
-
// to use or maintain FastLRUCache any more.
|
|
370
|
-
namespace fast_lru_cache {
|
|
371
|
-
|
|
372
|
-
// TODO(guido) Replicate LRU policy tests from LRUCache here.
|
|
373
|
-
class FastLRUCacheTest : public testing::Test {
|
|
374
|
-
public:
|
|
375
|
-
FastLRUCacheTest() {}
|
|
376
|
-
~FastLRUCacheTest() override { DeleteCache(); }
|
|
377
|
-
|
|
378
|
-
void DeleteCache() {
|
|
379
|
-
if (cache_ != nullptr) {
|
|
380
|
-
cache_->~LRUCacheShard();
|
|
381
|
-
port::cacheline_aligned_free(cache_);
|
|
382
|
-
cache_ = nullptr;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
void NewCache(size_t capacity) {
|
|
387
|
-
DeleteCache();
|
|
388
|
-
cache_ = reinterpret_cast<LRUCacheShard*>(
|
|
389
|
-
port::cacheline_aligned_alloc(sizeof(LRUCacheShard)));
|
|
390
|
-
new (cache_) LRUCacheShard(capacity, 1 /*estimated_value_size*/,
|
|
391
|
-
false /*strict_capacity_limit*/,
|
|
392
|
-
kDontChargeCacheMetadata);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
Status Insert(const std::string& key) {
|
|
396
|
-
return cache_->Insert(key, 0 /*hash*/, nullptr /*value*/, 1 /*charge*/,
|
|
397
|
-
nullptr /*deleter*/, nullptr /*handle*/,
|
|
398
|
-
Cache::Priority::LOW);
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
Status Insert(char key, size_t len) { return Insert(std::string(len, key)); }
|
|
402
|
-
|
|
403
|
-
size_t CalcEstimatedHandleChargeWrapper(
|
|
404
|
-
size_t estimated_value_size,
|
|
405
|
-
CacheMetadataChargePolicy metadata_charge_policy) {
|
|
406
|
-
return LRUCacheShard::CalcEstimatedHandleCharge(estimated_value_size,
|
|
407
|
-
metadata_charge_policy);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
int CalcHashBitsWrapper(size_t capacity, size_t estimated_value_size,
|
|
411
|
-
CacheMetadataChargePolicy metadata_charge_policy) {
|
|
412
|
-
return LRUCacheShard::CalcHashBits(capacity, estimated_value_size,
|
|
413
|
-
metadata_charge_policy);
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
// Maximum number of items that a shard can hold.
|
|
417
|
-
double CalcMaxOccupancy(size_t capacity, size_t estimated_value_size,
|
|
418
|
-
CacheMetadataChargePolicy metadata_charge_policy) {
|
|
419
|
-
size_t handle_charge = LRUCacheShard::CalcEstimatedHandleCharge(
|
|
420
|
-
estimated_value_size, metadata_charge_policy);
|
|
421
|
-
return capacity / (kLoadFactor * handle_charge);
|
|
422
|
-
}
|
|
423
|
-
bool TableSizeIsAppropriate(int hash_bits, double max_occupancy) {
|
|
424
|
-
if (hash_bits == 0) {
|
|
425
|
-
return max_occupancy <= 1;
|
|
426
|
-
} else {
|
|
427
|
-
return (1 << hash_bits >= max_occupancy) &&
|
|
428
|
-
(1 << (hash_bits - 1) <= max_occupancy);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
private:
|
|
433
|
-
LRUCacheShard* cache_ = nullptr;
|
|
434
|
-
};
|
|
435
|
-
|
|
436
|
-
TEST_F(FastLRUCacheTest, ValidateKeySize) {
|
|
437
|
-
NewCache(3);
|
|
438
|
-
EXPECT_OK(Insert('a', 16));
|
|
439
|
-
EXPECT_NOK(Insert('b', 15));
|
|
440
|
-
EXPECT_OK(Insert('b', 16));
|
|
441
|
-
EXPECT_NOK(Insert('c', 17));
|
|
442
|
-
EXPECT_NOK(Insert('d', 1000));
|
|
443
|
-
EXPECT_NOK(Insert('e', 11));
|
|
444
|
-
EXPECT_NOK(Insert('f', 0));
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
TEST_F(FastLRUCacheTest, CalcHashBitsTest) {
|
|
448
|
-
size_t capacity;
|
|
449
|
-
size_t estimated_value_size;
|
|
450
|
-
double max_occupancy;
|
|
451
|
-
int hash_bits;
|
|
452
|
-
CacheMetadataChargePolicy metadata_charge_policy;
|
|
453
|
-
// Vary the cache capacity, fix the element charge.
|
|
454
|
-
for (int i = 0; i < 2048; i++) {
|
|
455
|
-
capacity = i;
|
|
456
|
-
estimated_value_size = 0;
|
|
457
|
-
metadata_charge_policy = kFullChargeCacheMetadata;
|
|
458
|
-
max_occupancy = CalcMaxOccupancy(capacity, estimated_value_size,
|
|
459
|
-
metadata_charge_policy);
|
|
460
|
-
hash_bits = CalcHashBitsWrapper(capacity, estimated_value_size,
|
|
461
|
-
metadata_charge_policy);
|
|
462
|
-
EXPECT_TRUE(TableSizeIsAppropriate(hash_bits, max_occupancy));
|
|
463
|
-
}
|
|
464
|
-
// Fix the cache capacity, vary the element charge.
|
|
465
|
-
for (int i = 0; i < 1024; i++) {
|
|
466
|
-
capacity = 1024;
|
|
467
|
-
estimated_value_size = i;
|
|
468
|
-
metadata_charge_policy = kFullChargeCacheMetadata;
|
|
469
|
-
max_occupancy = CalcMaxOccupancy(capacity, estimated_value_size,
|
|
470
|
-
metadata_charge_policy);
|
|
471
|
-
hash_bits = CalcHashBitsWrapper(capacity, estimated_value_size,
|
|
472
|
-
metadata_charge_policy);
|
|
473
|
-
EXPECT_TRUE(TableSizeIsAppropriate(hash_bits, max_occupancy));
|
|
474
|
-
}
|
|
475
|
-
// Zero-capacity cache, and only values have charge.
|
|
476
|
-
capacity = 0;
|
|
477
|
-
estimated_value_size = 1;
|
|
478
|
-
metadata_charge_policy = kDontChargeCacheMetadata;
|
|
479
|
-
hash_bits = CalcHashBitsWrapper(capacity, estimated_value_size,
|
|
480
|
-
metadata_charge_policy);
|
|
481
|
-
EXPECT_TRUE(TableSizeIsAppropriate(hash_bits, 0 /* max_occupancy */));
|
|
482
|
-
// Zero-capacity cache, and only metadata has charge.
|
|
483
|
-
capacity = 0;
|
|
484
|
-
estimated_value_size = 0;
|
|
485
|
-
metadata_charge_policy = kFullChargeCacheMetadata;
|
|
486
|
-
hash_bits = CalcHashBitsWrapper(capacity, estimated_value_size,
|
|
487
|
-
metadata_charge_policy);
|
|
488
|
-
EXPECT_TRUE(TableSizeIsAppropriate(hash_bits, 0 /* max_occupancy */));
|
|
489
|
-
// Small cache, large elements.
|
|
490
|
-
capacity = 1024;
|
|
491
|
-
estimated_value_size = 8192;
|
|
492
|
-
metadata_charge_policy = kFullChargeCacheMetadata;
|
|
493
|
-
hash_bits = CalcHashBitsWrapper(capacity, estimated_value_size,
|
|
494
|
-
metadata_charge_policy);
|
|
495
|
-
EXPECT_TRUE(TableSizeIsAppropriate(hash_bits, 0 /* max_occupancy */));
|
|
496
|
-
// Large capacity.
|
|
497
|
-
capacity = 31924172;
|
|
498
|
-
estimated_value_size = 8192;
|
|
499
|
-
metadata_charge_policy = kFullChargeCacheMetadata;
|
|
500
|
-
max_occupancy =
|
|
501
|
-
CalcMaxOccupancy(capacity, estimated_value_size, metadata_charge_policy);
|
|
502
|
-
hash_bits = CalcHashBitsWrapper(capacity, estimated_value_size,
|
|
503
|
-
metadata_charge_policy);
|
|
504
|
-
EXPECT_TRUE(TableSizeIsAppropriate(hash_bits, max_occupancy));
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
} // namespace fast_lru_cache
|
|
508
|
-
|
|
509
366
|
namespace clock_cache {
|
|
510
367
|
|
|
511
368
|
class ClockCacheTest : public testing::Test {
|
|
@@ -1275,14 +1132,19 @@ TEST_F(LRUCacheSecondaryCacheTest, BasicTest) {
|
|
|
1275
1132
|
nullptr /* memory_allocator */, kDefaultToAdaptiveMutex,
|
|
1276
1133
|
kDontChargeCacheMetadata);
|
|
1277
1134
|
std::shared_ptr<TestSecondaryCache> secondary_cache =
|
|
1278
|
-
std::make_shared<TestSecondaryCache>(
|
|
1135
|
+
std::make_shared<TestSecondaryCache>(4096);
|
|
1279
1136
|
opts.secondary_cache = secondary_cache;
|
|
1280
1137
|
std::shared_ptr<Cache> cache = NewLRUCache(opts);
|
|
1281
1138
|
std::shared_ptr<Statistics> stats = CreateDBStatistics();
|
|
1282
1139
|
CacheKey k1 = CacheKey::CreateUniqueForCacheLifetime(cache.get());
|
|
1283
1140
|
CacheKey k2 = CacheKey::CreateUniqueForCacheLifetime(cache.get());
|
|
1141
|
+
CacheKey k3 = CacheKey::CreateUniqueForCacheLifetime(cache.get());
|
|
1284
1142
|
|
|
1285
1143
|
Random rnd(301);
|
|
1144
|
+
// Start with warming k3
|
|
1145
|
+
std::string str3 = rnd.RandomString(1021);
|
|
1146
|
+
ASSERT_OK(secondary_cache->InsertSaved(k3.AsSlice(), str3));
|
|
1147
|
+
|
|
1286
1148
|
std::string str1 = rnd.RandomString(1020);
|
|
1287
1149
|
TestItem* item1 = new TestItem(str1.data(), str1.length());
|
|
1288
1150
|
ASSERT_OK(cache->Insert(k1.AsSlice(), item1,
|
|
@@ -1299,15 +1161,27 @@ TEST_F(LRUCacheSecondaryCacheTest, BasicTest) {
|
|
|
1299
1161
|
cache->Lookup(k2.AsSlice(), &LRUCacheSecondaryCacheTest::helper_,
|
|
1300
1162
|
test_item_creator, Cache::Priority::LOW, true, stats.get());
|
|
1301
1163
|
ASSERT_NE(handle, nullptr);
|
|
1164
|
+
ASSERT_EQ(static_cast<TestItem*>(cache->Value(handle))->Size(), str2.size());
|
|
1302
1165
|
cache->Release(handle);
|
|
1166
|
+
|
|
1303
1167
|
// This lookup should promote k1 and demote k2
|
|
1304
1168
|
handle =
|
|
1305
1169
|
cache->Lookup(k1.AsSlice(), &LRUCacheSecondaryCacheTest::helper_,
|
|
1306
1170
|
test_item_creator, Cache::Priority::LOW, true, stats.get());
|
|
1307
1171
|
ASSERT_NE(handle, nullptr);
|
|
1172
|
+
ASSERT_EQ(static_cast<TestItem*>(cache->Value(handle))->Size(), str1.size());
|
|
1308
1173
|
cache->Release(handle);
|
|
1309
|
-
|
|
1310
|
-
|
|
1174
|
+
|
|
1175
|
+
// This lookup should promote k3 and demote k1
|
|
1176
|
+
handle =
|
|
1177
|
+
cache->Lookup(k3.AsSlice(), &LRUCacheSecondaryCacheTest::helper_,
|
|
1178
|
+
test_item_creator, Cache::Priority::LOW, true, stats.get());
|
|
1179
|
+
ASSERT_NE(handle, nullptr);
|
|
1180
|
+
ASSERT_EQ(static_cast<TestItem*>(cache->Value(handle))->Size(), str3.size());
|
|
1181
|
+
cache->Release(handle);
|
|
1182
|
+
|
|
1183
|
+
ASSERT_EQ(secondary_cache->num_inserts(), 3u);
|
|
1184
|
+
ASSERT_EQ(secondary_cache->num_lookups(), 2u);
|
|
1311
1185
|
ASSERT_EQ(stats->getTickerCount(SECONDARY_CACHE_HITS),
|
|
1312
1186
|
secondary_cache->num_lookups());
|
|
1313
1187
|
PerfContext perf_ctx = *get_perf_context();
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
#include "rocksdb/secondary_cache.h"
|
|
7
|
+
|
|
8
|
+
#include "cache/cache_entry_roles.h"
|
|
9
|
+
|
|
10
|
+
namespace ROCKSDB_NAMESPACE {
|
|
11
|
+
|
|
12
|
+
namespace {
|
|
13
|
+
|
|
14
|
+
size_t SliceSize(void* obj) { return static_cast<Slice*>(obj)->size(); }
|
|
15
|
+
|
|
16
|
+
Status SliceSaveTo(void* from_obj, size_t from_offset, size_t length,
|
|
17
|
+
void* out) {
|
|
18
|
+
const Slice& slice = *static_cast<Slice*>(from_obj);
|
|
19
|
+
std::memcpy(out, slice.data() + from_offset, length);
|
|
20
|
+
return Status::OK();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
} // namespace
|
|
24
|
+
|
|
25
|
+
Status SecondaryCache::InsertSaved(const Slice& key, const Slice& saved) {
|
|
26
|
+
static Cache::CacheItemHelper helper{
|
|
27
|
+
&SliceSize, &SliceSaveTo, GetNoopDeleterForRole<CacheEntryRole::kMisc>()};
|
|
28
|
+
// NOTE: depends on Insert() being synchronous, not keeping pointer `&saved`
|
|
29
|
+
return Insert(key, const_cast<Slice*>(&saved), &helper);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
} // namespace ROCKSDB_NAMESPACE
|
|
@@ -123,6 +123,10 @@ 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
|
+
|
|
126
130
|
private:
|
|
127
131
|
void UpdateAndCountBlobIfNeeded() {
|
|
128
132
|
assert(!iter_->Valid() || iter_->status().ok());
|
|
@@ -130,6 +134,13 @@ class BlobCountingIterator : public InternalIterator {
|
|
|
130
134
|
if (!iter_->Valid()) {
|
|
131
135
|
status_ = iter_->status();
|
|
132
136
|
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;
|
|
133
144
|
}
|
|
134
145
|
|
|
135
146
|
TEST_SYNC_POINT(
|