@nxtedition/rocksdb 8.0.1 → 8.0.2

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 (129) hide show
  1. package/deps/rocksdb/rocksdb/CMakeLists.txt +2 -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 +0 -5
  5. package/deps/rocksdb/rocksdb/cache/cache_test.cc +8 -29
  6. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +146 -0
  7. package/deps/rocksdb/rocksdb/cache/clock_cache.h +13 -1
  8. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +20 -146
  9. package/deps/rocksdb/rocksdb/cache/secondary_cache.cc +32 -0
  10. package/deps/rocksdb/rocksdb/db/blob/blob_counting_iterator.h +11 -0
  11. package/deps/rocksdb/rocksdb/db/column_family.cc +11 -9
  12. package/deps/rocksdb/rocksdb/db/column_family.h +20 -0
  13. package/deps/rocksdb/rocksdb/db/compaction/clipping_iterator.h +5 -0
  14. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +13 -33
  15. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +5 -0
  16. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +27 -8
  17. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +17 -1
  18. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +2 -1
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +4 -2
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +8 -6
  21. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +65 -7
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +5 -0
  23. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +10 -32
  24. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +28 -47
  25. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +28 -22
  26. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +8 -14
  27. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +8 -8
  28. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +5 -4
  29. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +170 -140
  30. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +5 -1
  31. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +5 -4
  32. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +8 -2
  33. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +8 -0
  34. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +266 -138
  35. package/deps/rocksdb/rocksdb/db/corruption_test.cc +86 -1
  36. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +72 -5
  37. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +119 -10
  38. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +585 -264
  39. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +46 -18
  40. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +5 -1
  41. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +6 -15
  42. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +1 -1
  43. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +1 -1
  44. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +3 -0
  45. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +8 -8
  46. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +10 -0
  47. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +250 -2
  48. package/deps/rocksdb/rocksdb/db/db_test.cc +3 -0
  49. package/deps/rocksdb/rocksdb/db/db_test2.cc +307 -8
  50. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +129 -0
  51. package/deps/rocksdb/rocksdb/db/db_with_timestamp_compaction_test.cc +21 -0
  52. package/deps/rocksdb/rocksdb/db/dbformat.cc +25 -0
  53. package/deps/rocksdb/rocksdb/db/dbformat.h +2 -0
  54. package/deps/rocksdb/rocksdb/db/experimental.cc +1 -1
  55. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +5 -2
  56. package/deps/rocksdb/rocksdb/db/flush_job.cc +5 -2
  57. package/deps/rocksdb/rocksdb/db/history_trimming_iterator.h +4 -0
  58. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +56 -53
  59. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +3 -4
  60. package/deps/rocksdb/rocksdb/db/merge_helper.cc +4 -0
  61. package/deps/rocksdb/rocksdb/db/periodic_task_scheduler_test.cc +10 -10
  62. package/deps/rocksdb/rocksdb/db/repair.cc +64 -22
  63. package/deps/rocksdb/rocksdb/db/repair_test.cc +54 -0
  64. package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +26 -26
  65. package/deps/rocksdb/rocksdb/db/table_cache.cc +2 -0
  66. package/deps/rocksdb/rocksdb/db/table_properties_collector.h +3 -1
  67. package/deps/rocksdb/rocksdb/db/version_builder.cc +90 -43
  68. package/deps/rocksdb/rocksdb/db/version_builder.h +20 -0
  69. package/deps/rocksdb/rocksdb/db/version_builder_test.cc +190 -67
  70. package/deps/rocksdb/rocksdb/db/version_edit.cc +15 -1
  71. package/deps/rocksdb/rocksdb/db/version_edit.h +16 -4
  72. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +41 -11
  73. package/deps/rocksdb/rocksdb/db/version_edit_handler.h +27 -12
  74. package/deps/rocksdb/rocksdb/db/version_edit_test.cc +18 -16
  75. package/deps/rocksdb/rocksdb/db/version_set.cc +212 -35
  76. package/deps/rocksdb/rocksdb/db/version_set.h +34 -4
  77. package/deps/rocksdb/rocksdb/db/version_set_test.cc +45 -25
  78. package/deps/rocksdb/rocksdb/db/write_thread.cc +5 -2
  79. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +0 -1
  80. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +0 -4
  81. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +12 -17
  82. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +6 -4
  83. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +1 -0
  84. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +0 -48
  85. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +8 -0
  86. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +196 -171
  87. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +6 -0
  88. package/deps/rocksdb/rocksdb/include/rocksdb/metadata.h +9 -3
  89. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +25 -18
  90. package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +27 -5
  91. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +5 -0
  92. package/deps/rocksdb/rocksdb/include/rocksdb/status.h +3 -0
  93. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +1 -1
  94. package/deps/rocksdb/rocksdb/logging/logging.h +13 -19
  95. package/deps/rocksdb/rocksdb/memory/arena.cc +4 -3
  96. package/deps/rocksdb/rocksdb/memory/arena_test.cc +30 -0
  97. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +3 -1
  98. package/deps/rocksdb/rocksdb/monitoring/stats_history_test.cc +26 -26
  99. package/deps/rocksdb/rocksdb/src.mk +2 -1
  100. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.cc +3 -2
  101. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +3 -2
  102. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +1 -1
  103. package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +3 -3
  104. package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.cc +142 -0
  105. package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.h +241 -0
  106. package/deps/rocksdb/rocksdb/table/format.cc +24 -20
  107. package/deps/rocksdb/rocksdb/table/format.h +5 -2
  108. package/deps/rocksdb/rocksdb/table/merging_iterator.cc +97 -115
  109. package/deps/rocksdb/rocksdb/table/merging_iterator.h +82 -1
  110. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +2 -2
  111. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +1 -1
  112. package/deps/rocksdb/rocksdb/table/table_test.cc +7 -6
  113. package/deps/rocksdb/rocksdb/test_util/testutil.h +10 -0
  114. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +0 -6
  115. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer.h +2 -2
  116. package/deps/rocksdb/rocksdb/util/bloom_test.cc +1 -1
  117. package/deps/rocksdb/rocksdb/util/status.cc +7 -0
  118. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +5 -0
  119. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +4 -0
  120. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +7 -67
  121. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.h +1 -3
  122. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.cc +1 -0
  123. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +59 -0
  124. package/deps/rocksdb/rocksdb.gyp +2 -1
  125. package/package.json +1 -1
  126. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  127. package/prebuilds/linux-x64/node.napi.node +0 -0
  128. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +0 -580
  129. 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.12
2096
- ZLIB_SHA256 ?= 91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9
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
- // FastLRUCache and HyperClockCache only support 16-byte keys, so some of
26
- // the tests originally wrote for LRUCache do not work on the other caches.
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_ == kFast || type_ == kHyperClock) {
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 == kFast || type == kHyperClock) {
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 == kFast || type == kHyperClock) {
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 == kFast || type == kHyperClock) {
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, kFast));
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 experimental alternative to LRUCache.
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>(2048);
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
- ASSERT_EQ(secondary_cache->num_inserts(), 2u);
1310
- ASSERT_EQ(secondary_cache->num_lookups(), 1u);
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(