@nxtedition/rocksdb 8.1.17 → 8.2.0-alpha.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 (147) hide show
  1. package/binding.cc +32 -2
  2. package/binding.gyp +8 -0
  3. package/deps/liburing/liburing.gyp +20 -0
  4. package/deps/rocksdb/rocksdb/CMakeLists.txt +4 -0
  5. package/deps/rocksdb/rocksdb/TARGETS +7 -0
  6. package/deps/rocksdb/rocksdb/cache/cache.cc +43 -0
  7. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +8 -5
  8. package/deps/rocksdb/rocksdb/cache/cache_entry_stats.h +1 -1
  9. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager.cc +1 -1
  10. package/deps/rocksdb/rocksdb/cache/cache_test.cc +12 -48
  11. package/deps/rocksdb/rocksdb/cache/charged_cache.cc +26 -18
  12. package/deps/rocksdb/rocksdb/cache/charged_cache.h +5 -62
  13. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +119 -44
  14. package/deps/rocksdb/rocksdb/cache/clock_cache.h +34 -29
  15. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +3 -3
  16. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +2 -2
  17. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +148 -209
  18. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +118 -284
  19. package/deps/rocksdb/rocksdb/cache/lru_cache.h +23 -71
  20. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +351 -392
  21. package/deps/rocksdb/rocksdb/cache/secondary_cache.cc +5 -2
  22. package/deps/rocksdb/rocksdb/cache/secondary_cache_adapter.cc +296 -0
  23. package/deps/rocksdb/rocksdb/cache/secondary_cache_adapter.h +52 -0
  24. package/deps/rocksdb/rocksdb/cache/sharded_cache.h +22 -19
  25. package/deps/rocksdb/rocksdb/cache/typed_cache.h +56 -20
  26. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.cc +3 -0
  27. package/deps/rocksdb/rocksdb/db/blob/blob_counting_iterator.h +4 -0
  28. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +3 -3
  29. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +19 -25
  30. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +216 -0
  31. package/deps/rocksdb/rocksdb/db/c.cc +90 -1
  32. package/deps/rocksdb/rocksdb/db/column_family.cc +8 -7
  33. package/deps/rocksdb/rocksdb/db/column_family.h +0 -6
  34. package/deps/rocksdb/rocksdb/db/compaction/clipping_iterator.h +5 -0
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +24 -7
  36. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +17 -1
  37. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +18 -12
  38. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +3 -1
  39. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +245 -302
  40. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +13 -2
  41. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +5 -0
  42. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +75 -15
  43. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +2 -3
  44. package/deps/rocksdb/rocksdb/db/db_filesnapshot.cc +1 -5
  45. package/deps/rocksdb/rocksdb/db/db_flush_test.cc +91 -1
  46. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +5 -12
  47. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +16 -4
  48. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +47 -24
  49. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +4 -2
  50. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +1 -1
  51. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +32 -3
  52. package/deps/rocksdb/rocksdb/db/db_iter.cc +28 -29
  53. package/deps/rocksdb/rocksdb/db/db_iter.h +0 -3
  54. package/deps/rocksdb/rocksdb/db/db_properties_test.cc +176 -0
  55. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +391 -2
  56. package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +26 -0
  57. package/deps/rocksdb/rocksdb/db/db_write_test.cc +13 -5
  58. package/deps/rocksdb/rocksdb/db/dbformat.h +3 -1
  59. package/deps/rocksdb/rocksdb/db/error_handler_fs_test.cc +0 -1
  60. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +0 -6
  61. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +3 -0
  62. package/deps/rocksdb/rocksdb/db/forward_iterator.h +1 -1
  63. package/deps/rocksdb/rocksdb/db/history_trimming_iterator.h +4 -0
  64. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +68 -40
  65. package/deps/rocksdb/rocksdb/db/import_column_family_job.h +3 -3
  66. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +115 -0
  67. package/deps/rocksdb/rocksdb/db/internal_stats.cc +169 -72
  68. package/deps/rocksdb/rocksdb/db/internal_stats.h +36 -7
  69. package/deps/rocksdb/rocksdb/db/memtable.cc +6 -4
  70. package/deps/rocksdb/rocksdb/db/merge_helper.cc +4 -0
  71. package/deps/rocksdb/rocksdb/db/perf_context_test.cc +151 -0
  72. package/deps/rocksdb/rocksdb/db/range_del_aggregator.cc +47 -16
  73. package/deps/rocksdb/rocksdb/db/range_del_aggregator.h +10 -8
  74. package/deps/rocksdb/rocksdb/db/range_del_aggregator_test.cc +91 -93
  75. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.h +1 -2
  76. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +1 -1
  77. package/deps/rocksdb/rocksdb/db/version_set.cc +30 -14
  78. package/deps/rocksdb/rocksdb/db/version_set.h +1 -0
  79. package/deps/rocksdb/rocksdb/db/write_stall_stats.cc +179 -0
  80. package/deps/rocksdb/rocksdb/db/write_stall_stats.h +47 -0
  81. package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +109 -7
  82. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +147 -12
  83. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +31 -0
  84. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +22 -0
  85. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +4 -1
  86. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +42 -59
  87. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +7 -4
  88. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +7 -0
  89. package/deps/rocksdb/rocksdb/db_stress_tool/expected_state.cc +6 -10
  90. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +6 -0
  91. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.h +4 -0
  92. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +127 -36
  93. package/deps/rocksdb/rocksdb/env/fs_posix.cc +8 -0
  94. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +35 -0
  95. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +29 -8
  96. package/deps/rocksdb/rocksdb/file/file_util.cc +14 -10
  97. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +183 -63
  98. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_cache.h +159 -66
  99. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +3 -1
  100. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +52 -5
  101. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +3 -3
  102. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_filter.h +134 -73
  103. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +46 -3
  104. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +6 -0
  105. package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +0 -6
  106. package/deps/rocksdb/rocksdb/include/rocksdb/metadata.h +7 -0
  107. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +2 -2
  108. package/deps/rocksdb/rocksdb/include/rocksdb/perf_context.h +6 -1
  109. package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +3 -3
  110. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +18 -0
  111. package/deps/rocksdb/rocksdb/include/rocksdb/types.h +28 -0
  112. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
  113. package/deps/rocksdb/rocksdb/include/rocksdb/wide_columns.h +39 -0
  114. package/deps/rocksdb/rocksdb/monitoring/perf_context.cc +5 -0
  115. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +9 -1
  116. package/deps/rocksdb/rocksdb/options/customizable_test.cc +2 -2
  117. package/deps/rocksdb/rocksdb/port/stack_trace.cc +17 -7
  118. package/deps/rocksdb/rocksdb/port/win/env_win.h +1 -0
  119. package/deps/rocksdb/rocksdb/src.mk +4 -0
  120. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +38 -34
  121. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +11 -12
  122. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +5 -5
  123. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +126 -132
  124. package/deps/rocksdb/rocksdb/table/block_based/block_cache.cc +16 -16
  125. package/deps/rocksdb/rocksdb/table/block_based/cachable_entry.h +0 -16
  126. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +1 -1
  127. package/deps/rocksdb/rocksdb/table/block_based/index_reader_common.cc +1 -1
  128. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +3 -4
  129. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_reader.cc +1 -1
  130. package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.cc +1 -1
  131. package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.cc +370 -0
  132. package/deps/rocksdb/rocksdb/table/compaction_merging_iterator.h +44 -0
  133. package/deps/rocksdb/rocksdb/table/get_context.cc +4 -2
  134. package/deps/rocksdb/rocksdb/table/merging_iterator.cc +555 -267
  135. package/deps/rocksdb/rocksdb/table/merging_iterator.h +10 -5
  136. package/deps/rocksdb/rocksdb/table/table_test.cc +113 -70
  137. package/deps/rocksdb/rocksdb/test_util/secondary_cache_test_util.cc +96 -0
  138. package/deps/rocksdb/rocksdb/test_util/secondary_cache_test_util.h +117 -0
  139. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.cc +5 -3
  140. package/deps/rocksdb/rocksdb/utilities/fault_injection_secondary_cache.cc +3 -3
  141. package/deps/rocksdb/rocksdb/utilities/fault_injection_secondary_cache.h +1 -1
  142. package/deps/rocksdb/rocksdb/utilities/simulator_cache/sim_cache.cc +9 -2
  143. package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.cc +5 -1
  144. package/deps/rocksdb/rocksdb/utilities/ttl/ttl_test.cc +11 -0
  145. package/deps/rocksdb/rocksdb.gyp +7 -1
  146. package/package.json +1 -1
  147. package/prebuilds/linux-x64/node.napi.node +0 -0
package/binding.cc CHANGED
@@ -18,6 +18,9 @@
18
18
  #include <rocksdb/table.h>
19
19
  #include <rocksdb/write_batch.h>
20
20
 
21
+ #include <liburing.h>
22
+ #include <sys/uio.h>
23
+
21
24
  #include <iostream>
22
25
  #include <memory>
23
26
  #include <optional>
@@ -383,7 +386,7 @@ struct BaseIterator : public Closable {
383
386
  }
384
387
  readOptions.fill_cache = fillCache_;
385
388
  readOptions.snapshot = snapshot_.get();
386
- // readOptions.async_io = true;
389
+ readOptions.async_io = true;
387
390
  readOptions.adaptive_readahead = true;
388
391
  readOptions.tailing = tailing_;
389
392
 
@@ -468,7 +471,33 @@ static void FinalizeDatabase(napi_env env, void* data, void* hint) {
468
471
  }
469
472
  }
470
473
 
474
+ inline void DeleteIOUring(void* p) {
475
+ struct io_uring* iu = static_cast<struct io_uring*>(p);
476
+ delete iu;
477
+ }
478
+
479
+ const unsigned int kIoUringDepth = 256;
480
+ inline struct io_uring* CreateIOUring() {
481
+ struct io_uring* new_io_uring = new struct io_uring;
482
+ int ret = io_uring_queue_init(kIoUringDepth, new_io_uring, 0);
483
+ if (ret) {
484
+ delete new_io_uring;
485
+ new_io_uring = nullptr;
486
+ }
487
+ return new_io_uring;
488
+ }
489
+
471
490
  NAPI_METHOD(db_init) {
491
+ // Ensure io_uring works.
492
+ {
493
+ io_uring new_io_uring = {};
494
+ auto ret = io_uring_queue_init(256, &new_io_uring, 0);
495
+ if (ret) {
496
+ ROCKS_STATUS_THROWS_NAPI(rocksdb::Status::NotSupported("ioring not supported"));
497
+ }
498
+ io_uring_queue_exit(&new_io_uring);
499
+ }
500
+
472
501
  auto database = new Database();
473
502
  napi_add_env_cleanup_hook(env, env_cleanup_hook, database);
474
503
 
@@ -915,8 +944,9 @@ NAPI_METHOD(db_get_many) {
915
944
  rocksdb::ReadOptions readOptions;
916
945
  readOptions.fill_cache = fillCache;
917
946
  readOptions.snapshot = snapshot.get();
918
- // readOptions.async_io = true;
947
+ readOptions.async_io = true;
919
948
  readOptions.ignore_range_deletions = ignoreRangeDeletions;
949
+ readOptions.optimize_multiget_for_io = true;
920
950
 
921
951
  const auto size = keys.size();
922
952
 
package/binding.gyp CHANGED
@@ -15,6 +15,14 @@
15
15
  "-mbmi",
16
16
  "-mlzcnt"
17
17
  ],
18
+ "dependencies": [
19
+ "./deps/liburing/liburing.gyp:liburing"
20
+ ],
21
+ "include_dirs": [
22
+ "/usr/lib/x86_64-linux-gnu/include",
23
+ "/usr/lib/include",
24
+ # "/usr/local/Cellar/jemalloc/5.3.0/include"
25
+ ],
18
26
  "ccflags": ["-flto"],
19
27
  "cflags!": ["-fno-exceptions"],
20
28
  "cflags_cc!": ["-fno-exceptions"],
@@ -0,0 +1,20 @@
1
+ {
2
+ "variables": { "openssl_fips": "0" },
3
+ "targets":
4
+ [
5
+ {
6
+ "target_name": "liburing",
7
+ "type": "static_library",
8
+ "include_dirs": ["linux", "liburing/src/include"],
9
+ "direct_dependent_settings":
10
+ { "include_dirs": ["linux", "liburing/src/include"] },
11
+ "sources":
12
+ [
13
+ "liburing/src/queue.c",
14
+ "liburing/src/register.c",
15
+ "liburing/src/setup.c",
16
+ "liburing/src/syscall.c",
17
+ ],
18
+ },
19
+ ],
20
+ }
@@ -661,6 +661,7 @@ set(SOURCES
661
661
  cache/compressed_secondary_cache.cc
662
662
  cache/lru_cache.cc
663
663
  cache/secondary_cache.cc
664
+ cache/secondary_cache_adapter.cc
664
665
  cache/sharded_cache.cc
665
666
  db/arena_wrapped_db_iter.cc
666
667
  db/blob/blob_contents.cc
@@ -747,6 +748,7 @@ set(SOURCES
747
748
  db/write_batch.cc
748
749
  db/write_batch_base.cc
749
750
  db/write_controller.cc
751
+ db/write_stall_stats.cc
750
752
  db/write_thread.cc
751
753
  env/composite_env.cc
752
754
  env/env.cc
@@ -838,6 +840,7 @@ set(SOURCES
838
840
  table/get_context.cc
839
841
  table/iterator.cc
840
842
  table/merging_iterator.cc
843
+ table/compaction_merging_iterator.cc
841
844
  table/meta_blocks.cc
842
845
  table/persistent_cache_helper.cc
843
846
  table/plain/plain_table_bloom.cc
@@ -1278,6 +1281,7 @@ if(WITH_TESTS OR WITH_BENCHMARK_TOOLS)
1278
1281
  add_subdirectory(third-party/gtest-1.8.1/fused-src/gtest)
1279
1282
  add_library(testharness STATIC
1280
1283
  test_util/mock_time_env.cc
1284
+ test_util/secondary_cache_test_util.cc
1281
1285
  test_util/testharness.cc)
1282
1286
  target_link_libraries(testharness gtest)
1283
1287
  endif()
@@ -19,6 +19,7 @@ cpp_library_wrapper(name="rocksdb_lib", srcs=[
19
19
  "cache/compressed_secondary_cache.cc",
20
20
  "cache/lru_cache.cc",
21
21
  "cache/secondary_cache.cc",
22
+ "cache/secondary_cache_adapter.cc",
22
23
  "cache/sharded_cache.cc",
23
24
  "db/arena_wrapped_db_iter.cc",
24
25
  "db/blob/blob_contents.cc",
@@ -105,6 +106,7 @@ cpp_library_wrapper(name="rocksdb_lib", srcs=[
105
106
  "db/write_batch.cc",
106
107
  "db/write_batch_base.cc",
107
108
  "db/write_controller.cc",
109
+ "db/write_stall_stats.cc",
108
110
  "db/write_thread.cc",
109
111
  "env/composite_env.cc",
110
112
  "env/env.cc",
@@ -200,6 +202,7 @@ cpp_library_wrapper(name="rocksdb_lib", srcs=[
200
202
  "table/block_based/reader_common.cc",
201
203
  "table/block_based/uncompression_dict_reader.cc",
202
204
  "table/block_fetcher.cc",
205
+ "table/compaction_merging_iterator.cc",
203
206
  "table/cuckoo/cuckoo_table_builder.cc",
204
207
  "table/cuckoo/cuckoo_table_factory.cc",
205
208
  "table/cuckoo/cuckoo_table_reader.cc",
@@ -362,6 +365,7 @@ cpp_library_wrapper(name="rocksdb_whole_archive_lib", srcs=[
362
365
  "cache/compressed_secondary_cache.cc",
363
366
  "cache/lru_cache.cc",
364
367
  "cache/secondary_cache.cc",
368
+ "cache/secondary_cache_adapter.cc",
365
369
  "cache/sharded_cache.cc",
366
370
  "db/arena_wrapped_db_iter.cc",
367
371
  "db/blob/blob_contents.cc",
@@ -448,6 +452,7 @@ cpp_library_wrapper(name="rocksdb_whole_archive_lib", srcs=[
448
452
  "db/write_batch.cc",
449
453
  "db/write_batch_base.cc",
450
454
  "db/write_controller.cc",
455
+ "db/write_stall_stats.cc",
451
456
  "db/write_thread.cc",
452
457
  "env/composite_env.cc",
453
458
  "env/env.cc",
@@ -543,6 +548,7 @@ cpp_library_wrapper(name="rocksdb_whole_archive_lib", srcs=[
543
548
  "table/block_based/reader_common.cc",
544
549
  "table/block_based/uncompression_dict_reader.cc",
545
550
  "table/block_fetcher.cc",
551
+ "table/compaction_merging_iterator.cc",
546
552
  "table/cuckoo/cuckoo_table_builder.cc",
547
553
  "table/cuckoo/cuckoo_table_factory.cc",
548
554
  "table/cuckoo/cuckoo_table_reader.cc",
@@ -699,6 +705,7 @@ cpp_library_wrapper(name="rocksdb_test_lib", srcs=[
699
705
  "db/db_with_timestamp_test_util.cc",
700
706
  "table/mock_table.cc",
701
707
  "test_util/mock_time_env.cc",
708
+ "test_util/secondary_cache_test_util.cc",
702
709
  "test_util/testharness.cc",
703
710
  "test_util/testutil.cc",
704
711
  "tools/block_cache_analyzer/block_cache_trace_analyzer.cc",
@@ -16,6 +16,8 @@
16
16
  #include "util/string_util.h"
17
17
 
18
18
  namespace ROCKSDB_NAMESPACE {
19
+ const Cache::CacheItemHelper kNoopCacheItemHelper{};
20
+
19
21
  static std::unordered_map<std::string, OptionTypeInfo>
20
22
  lru_cache_options_type_info = {
21
23
  {"capacity",
@@ -112,4 +114,45 @@ Status Cache::CreateFromString(const ConfigOptions& config_options,
112
114
  }
113
115
  return status;
114
116
  }
117
+
118
+ bool Cache::AsyncLookupHandle::IsReady() {
119
+ return pending_handle == nullptr || pending_handle->IsReady();
120
+ }
121
+
122
+ bool Cache::AsyncLookupHandle::IsPending() { return pending_handle != nullptr; }
123
+
124
+ Cache::Handle* Cache::AsyncLookupHandle::Result() {
125
+ assert(!IsPending());
126
+ return result_handle;
127
+ }
128
+
129
+ void Cache::StartAsyncLookup(AsyncLookupHandle& async_handle) {
130
+ async_handle.found_dummy_entry = false; // in case re-used
131
+ assert(!async_handle.IsPending());
132
+ async_handle.result_handle =
133
+ Lookup(async_handle.key, async_handle.helper, async_handle.create_context,
134
+ async_handle.priority, async_handle.stats);
135
+ }
136
+
137
+ Cache::Handle* Cache::Wait(AsyncLookupHandle& async_handle) {
138
+ WaitAll(&async_handle, 1);
139
+ return async_handle.Result();
140
+ }
141
+
142
+ void Cache::WaitAll(AsyncLookupHandle* async_handles, size_t count) {
143
+ for (size_t i = 0; i < count; ++i) {
144
+ if (async_handles[i].IsPending()) {
145
+ // If a pending handle gets here, it should be marked at "to be handled
146
+ // by a caller" by that caller erasing the pending_cache on it.
147
+ assert(async_handles[i].pending_cache == nullptr);
148
+ }
149
+ }
150
+ }
151
+
152
+ void Cache::SetEvictionCallback(EvictionCallback&& fn) {
153
+ // Overwriting non-empty with non-empty could indicate a bug
154
+ assert(!eviction_callback_ || !fn);
155
+ eviction_callback_ = std::move(fn);
156
+ }
157
+
115
158
  } // namespace ROCKSDB_NAMESPACE
@@ -255,12 +255,15 @@ void DeleteFn(Cache::ObjectPtr value, MemoryAllocator* /*alloc*/) {
255
255
  delete[] static_cast<char*>(value);
256
256
  }
257
257
 
258
+ Cache::CacheItemHelper helper1_wos(CacheEntryRole::kDataBlock, DeleteFn);
258
259
  Cache::CacheItemHelper helper1(CacheEntryRole::kDataBlock, DeleteFn, SizeFn,
259
- SaveToFn, CreateFn);
260
+ SaveToFn, CreateFn, &helper1_wos);
261
+ Cache::CacheItemHelper helper2_wos(CacheEntryRole::kIndexBlock, DeleteFn);
260
262
  Cache::CacheItemHelper helper2(CacheEntryRole::kIndexBlock, DeleteFn, SizeFn,
261
- SaveToFn, CreateFn);
263
+ SaveToFn, CreateFn, &helper2_wos);
264
+ Cache::CacheItemHelper helper3_wos(CacheEntryRole::kFilterBlock, DeleteFn);
262
265
  Cache::CacheItemHelper helper3(CacheEntryRole::kFilterBlock, DeleteFn, SizeFn,
263
- SaveToFn, CreateFn);
266
+ SaveToFn, CreateFn, &helper3_wos);
264
267
  } // namespace
265
268
 
266
269
  class CacheBench {
@@ -544,7 +547,7 @@ class CacheBench {
544
547
  }
545
548
  // do lookup
546
549
  handle = cache_->Lookup(key, &helper2, /*context*/ nullptr,
547
- Cache::Priority::LOW, true);
550
+ Cache::Priority::LOW);
548
551
  if (handle) {
549
552
  if (!FLAGS_lean) {
550
553
  // do something with the data
@@ -573,7 +576,7 @@ class CacheBench {
573
576
  }
574
577
  // do lookup
575
578
  handle = cache_->Lookup(key, &helper2, /*context*/ nullptr,
576
- Cache::Priority::LOW, true);
579
+ Cache::Priority::LOW);
577
580
  if (handle) {
578
581
  if (!FLAGS_lean) {
579
582
  // do something with the data
@@ -143,7 +143,7 @@ class CacheEntryStatsCollector {
143
143
  }
144
144
  }
145
145
  // If we reach here, shared entry is in cache with handle `h`.
146
- assert(cache.get()->GetCacheItemHelper(h) == &cache.kBasicHelper);
146
+ assert(cache.get()->GetCacheItemHelper(h) == cache.GetBasicHelper());
147
147
 
148
148
  // Build an aliasing shared_ptr that keeps `ptr` in cache while there
149
149
  // are references.
@@ -169,7 +169,7 @@ Slice CacheReservationManagerImpl<R>::GetNextCacheKey() {
169
169
  template <CacheEntryRole R>
170
170
  const Cache::CacheItemHelper*
171
171
  CacheReservationManagerImpl<R>::TEST_GetCacheItemHelperForRole() {
172
- return &CacheInterface::kHelper;
172
+ return CacheInterface::GetHelper();
173
173
  }
174
174
 
175
175
  template class CacheReservationManagerImpl<
@@ -18,6 +18,7 @@
18
18
  #include "cache/lru_cache.h"
19
19
  #include "cache/typed_cache.h"
20
20
  #include "port/stack_trace.h"
21
+ #include "test_util/secondary_cache_test_util.h"
21
22
  #include "test_util/testharness.h"
22
23
  #include "util/coding.h"
23
24
  #include "util/string_util.h"
@@ -81,13 +82,10 @@ const Cache::CacheItemHelper kEraseOnDeleteHelper2{
81
82
  Cache* cache = static_cast<Cache*>(value);
82
83
  cache->Erase(EncodeKey16Bytes(1234));
83
84
  }};
84
-
85
- const std::string kLRU = "lru";
86
- const std::string kHyperClock = "hyper_clock";
87
-
88
85
  } // anonymous namespace
89
86
 
90
- class CacheTest : public testing::TestWithParam<std::string> {
87
+ class CacheTest : public testing::Test,
88
+ public secondary_cache_test_util::WithCacheTypeParam {
91
89
  public:
92
90
  static CacheTest* current_;
93
91
  static std::string type_;
@@ -95,8 +93,7 @@ class CacheTest : public testing::TestWithParam<std::string> {
95
93
  static void Deleter(Cache::ObjectPtr v, MemoryAllocator*) {
96
94
  current_->deleted_values_.push_back(DecodeValue(v));
97
95
  }
98
- static constexpr Cache::CacheItemHelper kHelper{CacheEntryRole::kMisc,
99
- &Deleter};
96
+ static const Cache::CacheItemHelper kHelper;
100
97
 
101
98
  static const int kCacheSize = 1000;
102
99
  static const int kNumShardBits = 4;
@@ -108,8 +105,6 @@ class CacheTest : public testing::TestWithParam<std::string> {
108
105
  std::shared_ptr<Cache> cache_;
109
106
  std::shared_ptr<Cache> cache2_;
110
107
 
111
- size_t estimated_value_size_ = 1;
112
-
113
108
  CacheTest()
114
109
  : cache_(NewCache(kCacheSize, kNumShardBits, false)),
115
110
  cache2_(NewCache(kCacheSize2, kNumShardBits2, false)) {
@@ -119,41 +114,6 @@ class CacheTest : public testing::TestWithParam<std::string> {
119
114
 
120
115
  ~CacheTest() override {}
121
116
 
122
- std::shared_ptr<Cache> NewCache(size_t capacity) {
123
- auto type = GetParam();
124
- if (type == kLRU) {
125
- return NewLRUCache(capacity);
126
- }
127
- if (type == kHyperClock) {
128
- return HyperClockCacheOptions(
129
- capacity, estimated_value_size_ /*estimated_value_size*/)
130
- .MakeSharedCache();
131
- }
132
- return nullptr;
133
- }
134
-
135
- std::shared_ptr<Cache> NewCache(
136
- size_t capacity, int num_shard_bits, bool strict_capacity_limit,
137
- CacheMetadataChargePolicy charge_policy = kDontChargeCacheMetadata) {
138
- auto type = GetParam();
139
- if (type == kLRU) {
140
- LRUCacheOptions co;
141
- co.capacity = capacity;
142
- co.num_shard_bits = num_shard_bits;
143
- co.strict_capacity_limit = strict_capacity_limit;
144
- co.high_pri_pool_ratio = 0;
145
- co.metadata_charge_policy = charge_policy;
146
- return NewLRUCache(co);
147
- }
148
- if (type == kHyperClock) {
149
- return HyperClockCacheOptions(capacity, 1 /*estimated_value_size*/,
150
- num_shard_bits, strict_capacity_limit,
151
- nullptr /*allocator*/, charge_policy)
152
- .MakeSharedCache();
153
- }
154
- return nullptr;
155
- }
156
-
157
117
  // These functions encode/decode keys in tests cases that use
158
118
  // int keys.
159
119
  // Currently, HyperClockCache requires keys to be 16B long, whereas
@@ -187,8 +147,8 @@ class CacheTest : public testing::TestWithParam<std::string> {
187
147
 
188
148
  void Insert(std::shared_ptr<Cache> cache, int key, int value,
189
149
  int charge = 1) {
190
- EXPECT_OK(
191
- cache->Insert(EncodeKey(key), EncodeValue(value), &kHelper, charge));
150
+ EXPECT_OK(cache->Insert(EncodeKey(key), EncodeValue(value), &kHelper,
151
+ charge, /*handle*/ nullptr, Cache::Priority::HIGH));
192
152
  }
193
153
 
194
154
  void Erase(std::shared_ptr<Cache> cache, int key) {
@@ -212,6 +172,9 @@ class CacheTest : public testing::TestWithParam<std::string> {
212
172
  void Erase2(int key) { Erase(cache2_, key); }
213
173
  };
214
174
 
175
+ const Cache::CacheItemHelper CacheTest::kHelper{CacheEntryRole::kMisc,
176
+ &CacheTest::Deleter};
177
+
215
178
  CacheTest* CacheTest::current_;
216
179
  std::string CacheTest::type_;
217
180
 
@@ -993,8 +956,9 @@ TEST_P(CacheTest, GetChargeAndDeleter) {
993
956
  }
994
957
 
995
958
  INSTANTIATE_TEST_CASE_P(CacheTestInstance, CacheTest,
996
- testing::Values(kLRU, kHyperClock));
997
- INSTANTIATE_TEST_CASE_P(CacheTestInstance, LRUCacheTest, testing::Values(kLRU));
959
+ secondary_cache_test_util::GetTestingCacheTypes());
960
+ INSTANTIATE_TEST_CASE_P(CacheTestInstance, LRUCacheTest,
961
+ testing::Values(secondary_cache_test_util::kLRU));
998
962
 
999
963
  } // namespace ROCKSDB_NAMESPACE
1000
964
 
@@ -11,7 +11,7 @@ namespace ROCKSDB_NAMESPACE {
11
11
 
12
12
  ChargedCache::ChargedCache(std::shared_ptr<Cache> cache,
13
13
  std::shared_ptr<Cache> block_cache)
14
- : cache_(cache),
14
+ : CacheWrapper(cache),
15
15
  cache_res_mgr_(std::make_shared<ConcurrentCacheReservationManager>(
16
16
  std::make_shared<
17
17
  CacheReservationManagerImpl<CacheEntryRole::kBlobCache>>(
@@ -20,13 +20,13 @@ ChargedCache::ChargedCache(std::shared_ptr<Cache> cache,
20
20
  Status ChargedCache::Insert(const Slice& key, ObjectPtr obj,
21
21
  const CacheItemHelper* helper, size_t charge,
22
22
  Handle** handle, Priority priority) {
23
- Status s = cache_->Insert(key, obj, helper, charge, handle, priority);
23
+ Status s = target_->Insert(key, obj, helper, charge, handle, priority);
24
24
  if (s.ok()) {
25
25
  // Insert may cause the cache entry eviction if the cache is full. So we
26
26
  // directly call the reservation manager to update the total memory used
27
27
  // in the cache.
28
28
  assert(cache_res_mgr_);
29
- cache_res_mgr_->UpdateCacheReservation(cache_->GetUsage())
29
+ cache_res_mgr_->UpdateCacheReservation(target_->GetUsage())
30
30
  .PermitUncheckedError();
31
31
  }
32
32
  return s;
@@ -35,25 +35,33 @@ Status ChargedCache::Insert(const Slice& key, ObjectPtr obj,
35
35
  Cache::Handle* ChargedCache::Lookup(const Slice& key,
36
36
  const CacheItemHelper* helper,
37
37
  CreateContext* create_context,
38
- Priority priority, bool wait,
39
- Statistics* stats) {
40
- auto handle =
41
- cache_->Lookup(key, helper, create_context, priority, wait, stats);
38
+ Priority priority, Statistics* stats) {
39
+ auto handle = target_->Lookup(key, helper, create_context, priority, stats);
42
40
  // Lookup may promote the KV pair from the secondary cache to the primary
43
41
  // cache. So we directly call the reservation manager to update the total
44
42
  // memory used in the cache.
45
43
  if (helper && helper->create_cb) {
46
44
  assert(cache_res_mgr_);
47
- cache_res_mgr_->UpdateCacheReservation(cache_->GetUsage())
45
+ cache_res_mgr_->UpdateCacheReservation(target_->GetUsage())
48
46
  .PermitUncheckedError();
49
47
  }
50
48
  return handle;
51
49
  }
52
50
 
51
+ void ChargedCache::WaitAll(AsyncLookupHandle* async_handles, size_t count) {
52
+ target_->WaitAll(async_handles, count);
53
+ // In case of any promotions. Although some could finish by return of
54
+ // StartAsyncLookup, Wait/WaitAll will generally be used, so simpler to
55
+ // update here.
56
+ assert(cache_res_mgr_);
57
+ cache_res_mgr_->UpdateCacheReservation(target_->GetUsage())
58
+ .PermitUncheckedError();
59
+ }
60
+
53
61
  bool ChargedCache::Release(Cache::Handle* handle, bool useful,
54
62
  bool erase_if_last_ref) {
55
- size_t memory_used_delta = cache_->GetUsage(handle);
56
- bool erased = cache_->Release(handle, useful, erase_if_last_ref);
63
+ size_t memory_used_delta = target_->GetUsage(handle);
64
+ bool erased = target_->Release(handle, useful, erase_if_last_ref);
57
65
  if (erased) {
58
66
  assert(cache_res_mgr_);
59
67
  cache_res_mgr_
@@ -64,8 +72,8 @@ bool ChargedCache::Release(Cache::Handle* handle, bool useful,
64
72
  }
65
73
 
66
74
  bool ChargedCache::Release(Cache::Handle* handle, bool erase_if_last_ref) {
67
- size_t memory_used_delta = cache_->GetUsage(handle);
68
- bool erased = cache_->Release(handle, erase_if_last_ref);
75
+ size_t memory_used_delta = target_->GetUsage(handle);
76
+ bool erased = target_->Release(handle, erase_if_last_ref);
69
77
  if (erased) {
70
78
  assert(cache_res_mgr_);
71
79
  cache_res_mgr_
@@ -76,25 +84,25 @@ bool ChargedCache::Release(Cache::Handle* handle, bool erase_if_last_ref) {
76
84
  }
77
85
 
78
86
  void ChargedCache::Erase(const Slice& key) {
79
- cache_->Erase(key);
87
+ target_->Erase(key);
80
88
  assert(cache_res_mgr_);
81
- cache_res_mgr_->UpdateCacheReservation(cache_->GetUsage())
89
+ cache_res_mgr_->UpdateCacheReservation(target_->GetUsage())
82
90
  .PermitUncheckedError();
83
91
  }
84
92
 
85
93
  void ChargedCache::EraseUnRefEntries() {
86
- cache_->EraseUnRefEntries();
94
+ target_->EraseUnRefEntries();
87
95
  assert(cache_res_mgr_);
88
- cache_res_mgr_->UpdateCacheReservation(cache_->GetUsage())
96
+ cache_res_mgr_->UpdateCacheReservation(target_->GetUsage())
89
97
  .PermitUncheckedError();
90
98
  }
91
99
 
92
100
  void ChargedCache::SetCapacity(size_t capacity) {
93
- cache_->SetCapacity(capacity);
101
+ target_->SetCapacity(capacity);
94
102
  // SetCapacity can result in evictions when the cache capacity is decreased,
95
103
  // so we would want to update the cache reservation here as well.
96
104
  assert(cache_res_mgr_);
97
- cache_res_mgr_->UpdateCacheReservation(cache_->GetUsage())
105
+ cache_res_mgr_->UpdateCacheReservation(target_->GetUsage())
98
106
  .PermitUncheckedError();
99
107
  }
100
108
 
@@ -17,11 +17,10 @@ class ConcurrentCacheReservationManager;
17
17
  // A cache interface which wraps around another cache and takes care of
18
18
  // reserving space in block cache towards a single global memory limit, and
19
19
  // forwards all the calls to the underlying cache.
20
- class ChargedCache : public Cache {
20
+ class ChargedCache : public CacheWrapper {
21
21
  public:
22
22
  ChargedCache(std::shared_ptr<Cache> cache,
23
23
  std::shared_ptr<Cache> block_cache);
24
- ~ChargedCache() override = default;
25
24
 
26
25
  Status Insert(const Slice& key, ObjectPtr obj, const CacheItemHelper* helper,
27
26
  size_t charge, Handle** handle = nullptr,
@@ -29,9 +28,11 @@ class ChargedCache : public Cache {
29
28
 
30
29
  Cache::Handle* Lookup(const Slice& key, const CacheItemHelper* helper,
31
30
  CreateContext* create_context,
32
- Priority priority = Priority::LOW, bool wait = true,
31
+ Priority priority = Priority::LOW,
33
32
  Statistics* stats = nullptr) override;
34
33
 
34
+ void WaitAll(AsyncLookupHandle* async_handles, size_t count) override;
35
+
35
36
  bool Release(Cache::Handle* handle, bool useful,
36
37
  bool erase_if_last_ref = false) override;
37
38
  bool Release(Cache::Handle* handle, bool erase_if_last_ref = false) override;
@@ -42,66 +43,9 @@ class ChargedCache : public Cache {
42
43
  static const char* kClassName() { return "ChargedCache"; }
43
44
  const char* Name() const override { return kClassName(); }
44
45
 
45
- uint64_t NewId() override { return cache_->NewId(); }
46
-
47
46
  void SetCapacity(size_t capacity) override;
48
47
 
49
- void SetStrictCapacityLimit(bool strict_capacity_limit) override {
50
- cache_->SetStrictCapacityLimit(strict_capacity_limit);
51
- }
52
-
53
- bool HasStrictCapacityLimit() const override {
54
- return cache_->HasStrictCapacityLimit();
55
- }
56
-
57
- ObjectPtr Value(Cache::Handle* handle) override {
58
- return cache_->Value(handle);
59
- }
60
-
61
- bool IsReady(Cache::Handle* handle) override {
62
- return cache_->IsReady(handle);
63
- }
64
-
65
- void Wait(Cache::Handle* handle) override { cache_->Wait(handle); }
66
-
67
- void WaitAll(std::vector<Handle*>& handles) override {
68
- cache_->WaitAll(handles);
69
- }
70
-
71
- bool Ref(Cache::Handle* handle) override { return cache_->Ref(handle); }
72
-
73
- size_t GetCapacity() const override { return cache_->GetCapacity(); }
74
-
75
- size_t GetUsage() const override { return cache_->GetUsage(); }
76
-
77
- size_t GetUsage(Cache::Handle* handle) const override {
78
- return cache_->GetUsage(handle);
79
- }
80
-
81
- size_t GetPinnedUsage() const override { return cache_->GetPinnedUsage(); }
82
-
83
- size_t GetCharge(Cache::Handle* handle) const override {
84
- return cache_->GetCharge(handle);
85
- }
86
-
87
- const CacheItemHelper* GetCacheItemHelper(Handle* handle) const override {
88
- return cache_->GetCacheItemHelper(handle);
89
- }
90
-
91
- void ApplyToAllEntries(
92
- const std::function<void(const Slice& key, ObjectPtr value, size_t charge,
93
- const CacheItemHelper* helper)>& callback,
94
- const Cache::ApplyToAllEntriesOptions& opts) override {
95
- cache_->ApplyToAllEntries(callback, opts);
96
- }
97
-
98
- std::string GetPrintableOptions() const override {
99
- return cache_->GetPrintableOptions();
100
- }
101
-
102
- void DisownData() override { return cache_->DisownData(); }
103
-
104
- inline Cache* GetCache() const { return cache_.get(); }
48
+ inline Cache* GetCache() const { return target_.get(); }
105
49
 
106
50
  inline ConcurrentCacheReservationManager* TEST_GetCacheReservationManager()
107
51
  const {
@@ -109,7 +53,6 @@ class ChargedCache : public Cache {
109
53
  }
110
54
 
111
55
  private:
112
- std::shared_ptr<Cache> cache_;
113
56
  std::shared_ptr<ConcurrentCacheReservationManager> cache_res_mgr_;
114
57
  };
115
58