@nxtedition/rocksdb 13.1.4 → 13.2.0

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 (237) hide show
  1. package/binding.cc +43 -16
  2. package/deps/rocksdb/rocksdb/{TARGETS → BUCK} +27 -0
  3. package/deps/rocksdb/rocksdb/CMakeLists.txt +3 -1
  4. package/deps/rocksdb/rocksdb/Makefile +2 -2
  5. package/deps/rocksdb/rocksdb/cache/cache.cc +3 -1
  6. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.h +2 -0
  7. package/deps/rocksdb/rocksdb/db/attribute_group_iterator_impl.h +34 -9
  8. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +7 -6
  9. package/deps/rocksdb/rocksdb/db/blob/blob_source.h +5 -1
  10. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +22 -14
  11. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +149 -0
  12. package/deps/rocksdb/rocksdb/db/builder.cc +13 -24
  13. package/deps/rocksdb/rocksdb/db/coalescing_iterator.h +35 -10
  14. package/deps/rocksdb/rocksdb/db/column_family.cc +21 -10
  15. package/deps/rocksdb/rocksdb/db/column_family.h +15 -8
  16. package/deps/rocksdb/rocksdb/db/column_family_test.cc +98 -7
  17. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +126 -16
  18. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +51 -5
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +2 -2
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +2 -8
  21. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +24 -0
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +52 -22
  23. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +9 -7
  24. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +36 -9
  25. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +6 -0
  26. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +30 -17
  27. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +26 -23
  28. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +43 -33
  29. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +6 -5
  30. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +19 -9
  31. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +6 -5
  32. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +632 -411
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +171 -51
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +7 -5
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +37 -10
  36. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +51 -11
  37. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +10 -3
  38. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +350 -154
  39. package/deps/rocksdb/rocksdb/db/convenience.cc +1 -1
  40. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +62 -27
  41. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +68 -1
  42. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +91 -0
  43. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +134 -70
  44. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +71 -23
  45. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +43 -16
  46. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +47 -33
  47. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +27 -19
  48. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +38 -25
  49. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +3 -3
  50. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +7 -4
  51. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +258 -42
  52. package/deps/rocksdb/rocksdb/db/db_io_failure_test.cc +161 -9
  53. package/deps/rocksdb/rocksdb/db/db_iter.cc +118 -86
  54. package/deps/rocksdb/rocksdb/db/db_iter.h +44 -17
  55. package/deps/rocksdb/rocksdb/db/db_options_test.cc +27 -6
  56. package/deps/rocksdb/rocksdb/db/db_test.cc +48 -16
  57. package/deps/rocksdb/rocksdb/db/db_test2.cc +60 -15
  58. package/deps/rocksdb/rocksdb/db/db_test_util.cc +97 -44
  59. package/deps/rocksdb/rocksdb/db/db_test_util.h +7 -1
  60. package/deps/rocksdb/rocksdb/db/dbformat.cc +15 -5
  61. package/deps/rocksdb/rocksdb/db/dbformat.h +137 -55
  62. package/deps/rocksdb/rocksdb/db/event_helpers.cc +1 -0
  63. package/deps/rocksdb/rocksdb/db/experimental.cc +54 -0
  64. package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +663 -8
  65. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +152 -91
  66. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +134 -11
  67. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +55 -9
  68. package/deps/rocksdb/rocksdb/db/flush_job.cc +52 -29
  69. package/deps/rocksdb/rocksdb/db/flush_job.h +5 -3
  70. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +18 -12
  71. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +23 -29
  72. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +3 -2
  73. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +2 -0
  74. package/deps/rocksdb/rocksdb/db/internal_stats.cc +9 -6
  75. package/deps/rocksdb/rocksdb/db/internal_stats.h +54 -0
  76. package/deps/rocksdb/rocksdb/db/job_context.h +1 -1
  77. package/deps/rocksdb/rocksdb/db/log_reader.cc +6 -7
  78. package/deps/rocksdb/rocksdb/db/manifest_ops.cc +47 -0
  79. package/deps/rocksdb/rocksdb/db/manifest_ops.h +20 -0
  80. package/deps/rocksdb/rocksdb/db/memtable.cc +165 -64
  81. package/deps/rocksdb/rocksdb/db/memtable.h +422 -243
  82. package/deps/rocksdb/rocksdb/db/memtable_list.cc +99 -68
  83. package/deps/rocksdb/rocksdb/db/memtable_list.h +63 -38
  84. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +28 -25
  85. package/deps/rocksdb/rocksdb/db/multi_cf_iterator_impl.h +118 -60
  86. package/deps/rocksdb/rocksdb/db/multi_cf_iterator_test.cc +344 -89
  87. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.h +2 -3
  88. package/deps/rocksdb/rocksdb/db/repair.cc +15 -14
  89. package/deps/rocksdb/rocksdb/db/repair_test.cc +0 -13
  90. package/deps/rocksdb/rocksdb/db/snapshot_checker.h +7 -0
  91. package/deps/rocksdb/rocksdb/db/table_cache.cc +62 -65
  92. package/deps/rocksdb/rocksdb/db/table_cache.h +70 -76
  93. package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +5 -6
  94. package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +1 -1
  95. package/deps/rocksdb/rocksdb/db/transaction_log_impl.cc +8 -7
  96. package/deps/rocksdb/rocksdb/db/version_builder.cc +17 -19
  97. package/deps/rocksdb/rocksdb/db/version_builder.h +13 -12
  98. package/deps/rocksdb/rocksdb/db/version_edit.h +30 -0
  99. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +3 -5
  100. package/deps/rocksdb/rocksdb/db/version_set.cc +89 -129
  101. package/deps/rocksdb/rocksdb/db/version_set.h +12 -4
  102. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +1 -2
  103. package/deps/rocksdb/rocksdb/db/version_set_test.cc +12 -8
  104. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +0 -15
  105. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +0 -2
  106. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization_test.cc +9 -7
  107. package/deps/rocksdb/rocksdb/db/wide/wide_columns_helper.cc +0 -8
  108. package/deps/rocksdb/rocksdb/db/wide/wide_columns_helper.h +28 -2
  109. package/deps/rocksdb/rocksdb/db/write_batch.cc +32 -10
  110. package/deps/rocksdb/rocksdb/db/write_batch_internal.h +9 -0
  111. package/deps/rocksdb/rocksdb/db/write_batch_test.cc +2 -1
  112. package/deps/rocksdb/rocksdb/db/write_thread.cc +3 -1
  113. package/deps/rocksdb/rocksdb/db/write_thread.h +6 -2
  114. package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +15 -0
  115. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +7 -0
  116. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +4 -0
  117. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +18 -2
  118. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +100 -22
  119. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +15 -4
  120. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +34 -8
  121. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +223 -78
  122. package/deps/rocksdb/rocksdb/env/file_system.cc +6 -1
  123. package/deps/rocksdb/rocksdb/env/fs_posix.cc +53 -0
  124. package/deps/rocksdb/rocksdb/env/io_posix.cc +63 -17
  125. package/deps/rocksdb/rocksdb/env/io_posix.h +30 -1
  126. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +132 -48
  127. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +92 -24
  128. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +727 -109
  129. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +3 -4
  130. package/deps/rocksdb/rocksdb/file/random_access_file_reader.h +1 -1
  131. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +8 -0
  132. package/deps/rocksdb/rocksdb/include/rocksdb/attribute_groups.h +20 -1
  133. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_job_stats.h +9 -0
  134. package/deps/rocksdb/rocksdb/include/rocksdb/configurable.h +9 -5
  135. package/deps/rocksdb/rocksdb/include/rocksdb/convenience.h +2 -0
  136. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +10 -2
  137. package/deps/rocksdb/rocksdb/include/rocksdb/env.h +1 -0
  138. package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +7 -0
  139. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +34 -37
  140. package/deps/rocksdb/rocksdb/include/rocksdb/iterator_base.h +21 -0
  141. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +56 -28
  142. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +3 -0
  143. package/deps/rocksdb/rocksdb/include/rocksdb/table.h +36 -28
  144. package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +11 -0
  145. package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +1 -0
  146. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_type.h +84 -60
  147. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/secondary_index.h +102 -0
  148. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/table_properties_collectors.h +89 -2
  149. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction.h +32 -0
  150. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db.h +30 -1
  151. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/write_batch_with_index.h +23 -2
  152. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
  153. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +2 -0
  154. package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +79 -21
  155. package/deps/rocksdb/rocksdb/memtable/skiplist.h +41 -18
  156. package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +1 -5
  157. package/deps/rocksdb/rocksdb/memtable/wbwi_memtable.cc +169 -0
  158. package/deps/rocksdb/rocksdb/memtable/wbwi_memtable.h +400 -0
  159. package/deps/rocksdb/rocksdb/monitoring/thread_status_util_debug.cc +2 -0
  160. package/deps/rocksdb/rocksdb/options/cf_options.cc +137 -82
  161. package/deps/rocksdb/rocksdb/options/cf_options.h +18 -6
  162. package/deps/rocksdb/rocksdb/options/configurable.cc +31 -17
  163. package/deps/rocksdb/rocksdb/options/configurable_helper.h +7 -6
  164. package/deps/rocksdb/rocksdb/options/options_helper.cc +10 -8
  165. package/deps/rocksdb/rocksdb/options/options_parser.cc +74 -54
  166. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +89 -0
  167. package/deps/rocksdb/rocksdb/options/options_test.cc +112 -26
  168. package/deps/rocksdb/rocksdb/port/port.h +5 -9
  169. package/deps/rocksdb/rocksdb/src.mk +8 -0
  170. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.h +4 -0
  171. package/deps/rocksdb/rocksdb/table/block_based/block.h +1 -7
  172. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +2 -0
  173. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +62 -80
  174. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +13 -3
  175. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +16 -5
  176. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +38 -7
  177. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +12 -4
  178. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +4 -1
  179. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +4 -1
  180. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +204 -1
  181. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +3 -3
  182. package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +2 -1
  183. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_factory.h +4 -0
  184. package/deps/rocksdb/rocksdb/table/format.cc +3 -3
  185. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +4 -1
  186. package/deps/rocksdb/rocksdb/table/mock_table.cc +0 -50
  187. package/deps/rocksdb/rocksdb/table/mock_table.h +53 -0
  188. package/deps/rocksdb/rocksdb/table/plain/plain_table_factory.h +4 -0
  189. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +1 -1
  190. package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +10 -5
  191. package/deps/rocksdb/rocksdb/table/table_builder.h +3 -1
  192. package/deps/rocksdb/rocksdb/table/table_properties.cc +181 -0
  193. package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +5 -5
  194. package/deps/rocksdb/rocksdb/table/table_test.cc +71 -64
  195. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim.py +45 -45
  196. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim_test.py +35 -35
  197. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py +43 -43
  198. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +41 -4
  199. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +1 -0
  200. package/deps/rocksdb/rocksdb/tools/sst_dump_test.cc +1 -1
  201. package/deps/rocksdb/rocksdb/unreleased_history/add.sh +13 -0
  202. package/deps/rocksdb/rocksdb/util/aligned_buffer.h +24 -5
  203. package/deps/rocksdb/rocksdb/util/compaction_job_stats_impl.cc +7 -0
  204. package/deps/rocksdb/rocksdb/util/file_checksum_helper.cc +0 -52
  205. package/deps/rocksdb/rocksdb/util/file_checksum_helper.h +1 -10
  206. package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +92 -0
  207. package/deps/rocksdb/rocksdb/util/thread_operation.h +1 -0
  208. package/deps/rocksdb/rocksdb/util/udt_util.cc +50 -4
  209. package/deps/rocksdb/rocksdb/util/udt_util.h +24 -11
  210. package/deps/rocksdb/rocksdb/util/udt_util_test.cc +26 -13
  211. package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +1 -16
  212. package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +2 -0
  213. package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index.cc +214 -0
  214. package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index.h +60 -0
  215. package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index_test.cc +124 -0
  216. package/deps/rocksdb/rocksdb/utilities/secondary_index/secondary_index_mixin.h +441 -0
  217. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_for_tiering_collector.cc +34 -3
  218. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_for_tiering_collector.h +7 -2
  219. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_test.cc +437 -0
  220. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.cc +34 -11
  221. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.h +14 -7
  222. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.cc +7 -1
  223. package/deps/rocksdb/rocksdb/utilities/transactions/snapshot_checker.cc +17 -0
  224. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +69 -0
  225. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.h +20 -0
  226. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +1290 -0
  227. package/deps/rocksdb/rocksdb/utilities/transactions/write_committed_transaction_ts_test.cc +324 -0
  228. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +18 -1
  229. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.h +8 -1
  230. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +57 -12
  231. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.cc +32 -3
  232. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +33 -2
  233. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +721 -9
  234. package/deps/rocksdb/rocksdb.gyp +2 -0
  235. package/package.json +1 -1
  236. package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
  237. package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
@@ -9,15 +9,26 @@
9
9
  // found in the LICENSE file. See the AUTHORS file for names of contributors.
10
10
 
11
11
  #include "db/db_test_util.h"
12
+ #include "options/cf_options.h"
12
13
  #include "port/stack_trace.h"
13
14
  #include "rocksdb/iostats_context.h"
14
15
  #include "rocksdb/listener.h"
15
16
  #include "rocksdb/utilities/debug.h"
16
17
  #include "rocksdb/utilities/table_properties_collectors.h"
17
18
  #include "test_util/mock_time_env.h"
19
+ #include "util/defer.h"
18
20
  #include "utilities/merge_operators.h"
19
21
 
20
22
  namespace ROCKSDB_NAMESPACE {
23
+ namespace {
24
+ ConfigOptions GetStrictConfigOptions() {
25
+ ConfigOptions config_options;
26
+ config_options.ignore_unknown_options = false;
27
+ config_options.ignore_unsupported_options = false;
28
+ config_options.input_strings_escaped = false;
29
+ return config_options;
30
+ }
31
+ } // namespace
21
32
 
22
33
  class TieredCompactionTest : public DBTestBase {
23
34
  public:
@@ -1234,82 +1245,9 @@ TEST_F(TieredCompactionTest, RangeBasedTieredStorageLevel) {
1234
1245
  db_->ReleaseSnapshot(temp_snap);
1235
1246
  }
1236
1247
 
1237
- TEST_F(TieredCompactionTest, CheckInternalKeyRange) {
1238
- // When compacting keys from the last level to penultimate level,
1239
- // output to penultimate level should be within internal key range
1240
- // of input files from penultimate level.
1241
- // Set up:
1242
- // L5:
1243
- // File 1: DeleteRange[1, 3)@4, File 2: [3@5, 100@6]
1244
- // L6:
1245
- // File 3: [2@1, 3@2], File 4: [50@3]
1246
- //
1247
- // When File 1 and File 3 are being compacted,
1248
- // Key(3) cannot be compacted up, otherwise it causes
1249
- // inconsistency where File 3's Key(3) has a lower sequence number
1250
- // than File 2's Key(3).
1251
- const int kNumLevels = 7;
1252
- auto options = CurrentOptions();
1253
- SetColdTemperature(options);
1254
- options.level_compaction_dynamic_level_bytes = true;
1255
- options.num_levels = kNumLevels;
1256
- options.statistics = CreateDBStatistics();
1257
- options.max_subcompactions = 10;
1258
- options.preclude_last_level_data_seconds = 10000;
1259
- DestroyAndReopen(options);
1260
- auto cmp = options.comparator;
1261
-
1262
- std::string hot_start = Key(0);
1263
- std::string hot_end = Key(0);
1264
- SyncPoint::GetInstance()->SetCallBack(
1265
- "CompactionIterator::PrepareOutput.context", [&](void* arg) {
1266
- auto context = static_cast<PerKeyPlacementContext*>(arg);
1267
- context->output_to_penultimate_level =
1268
- cmp->Compare(context->key, hot_start) >= 0 &&
1269
- cmp->Compare(context->key, hot_end) < 0;
1270
- });
1271
- SyncPoint::GetInstance()->EnableProcessing();
1272
- // File 1
1273
- ASSERT_OK(Put(Key(2), "val2"));
1274
- ASSERT_OK(Put(Key(3), "val3"));
1275
- ASSERT_OK(Flush());
1276
- MoveFilesToLevel(6);
1277
- // File 2
1278
- ASSERT_OK(Put(Key(50), "val50"));
1279
- ASSERT_OK(Flush());
1280
- MoveFilesToLevel(6);
1281
-
1282
- const Snapshot* snapshot = db_->GetSnapshot();
1283
- hot_end = Key(100);
1284
- std::string start = Key(1);
1285
- std::string end = Key(3);
1286
- ASSERT_OK(
1287
- db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(), start, end));
1288
- ASSERT_OK(Flush());
1289
- MoveFilesToLevel(5);
1290
- // File 3
1291
- ASSERT_OK(Put(Key(3), "vall"));
1292
- ASSERT_OK(Put(Key(100), "val100"));
1293
- ASSERT_OK(Flush());
1294
- MoveFilesToLevel(5);
1295
- // Try to compact keys up
1296
- CompactRangeOptions cro;
1297
- cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
1298
- start = Key(1);
1299
- end = Key(2);
1300
- Slice begin_slice(start);
1301
- Slice end_slice(end);
1302
- ASSERT_OK(db_->CompactRange(cro, &begin_slice, &end_slice));
1303
- // Without internal key range checking, we get the following error:
1304
- // Corruption: force_consistency_checks(DEBUG): VersionBuilder: L5 has
1305
- // overlapping ranges: file #18 largest key: '6B6579303030303033' seq:102,
1306
- // type:1 vs. file #15 smallest key: '6B6579303030303033' seq:104, type:1
1307
- db_->ReleaseSnapshot(snapshot);
1308
- }
1309
-
1310
- class PrecludeLastLevelTest : public DBTestBase {
1248
+ class PrecludeLastLevelTestBase : public DBTestBase {
1311
1249
  public:
1312
- PrecludeLastLevelTest(std::string test_name = "preclude_last_level_test")
1250
+ PrecludeLastLevelTestBase(std::string test_name = "preclude_last_level_test")
1313
1251
  : DBTestBase(test_name, /*env_do_fsync=*/false) {
1314
1252
  mock_clock_ = std::make_shared<MockSystemClock>(env_->GetSystemClock());
1315
1253
  mock_clock_->SetCurrentTime(kMockStartTime);
@@ -1334,9 +1272,52 @@ class PrecludeLastLevelTest : public DBTestBase {
1334
1272
  });
1335
1273
  mock_clock_->SetCurrentTime(kMockStartTime);
1336
1274
  }
1275
+
1276
+ void ApplyConfigChangeImpl(
1277
+ bool dynamic, Options* options,
1278
+ const std::unordered_map<std::string, std::string>& config_change,
1279
+ const std::unordered_map<std::string, std::string>& db_config_change) {
1280
+ if (dynamic) {
1281
+ if (config_change.size() > 0) {
1282
+ // FIXME: temporary while preserve/preclude options are not user mutable
1283
+ SaveAndRestore<bool> m(&TEST_allowSetOptionsImmutableInMutable, true);
1284
+ ASSERT_OK(db_->SetOptions(config_change));
1285
+ }
1286
+ if (db_config_change.size() > 0) {
1287
+ ASSERT_OK(db_->SetDBOptions(db_config_change));
1288
+ }
1289
+ } else {
1290
+ if (config_change.size() > 0) {
1291
+ ASSERT_OK(GetColumnFamilyOptionsFromMap(
1292
+ GetStrictConfigOptions(), *options, config_change, options));
1293
+ }
1294
+ if (db_config_change.size() > 0) {
1295
+ ASSERT_OK(GetDBOptionsFromMap(GetStrictConfigOptions(), *options,
1296
+ db_config_change, options));
1297
+ }
1298
+ Reopen(*options);
1299
+ }
1300
+ }
1301
+ };
1302
+
1303
+ class PrecludeLastLevelTest : public PrecludeLastLevelTestBase,
1304
+ public testing::WithParamInterface<bool> {
1305
+ public:
1306
+ using PrecludeLastLevelTestBase::PrecludeLastLevelTestBase;
1307
+
1308
+ bool UseDynamicConfig() const { return GetParam(); }
1309
+
1310
+ void ApplyConfigChange(
1311
+ Options* options,
1312
+ const std::unordered_map<std::string, std::string>& config_change,
1313
+ const std::unordered_map<std::string, std::string>& db_config_change =
1314
+ {}) {
1315
+ ApplyConfigChangeImpl(UseDynamicConfig(), options, config_change,
1316
+ db_config_change);
1317
+ }
1337
1318
  };
1338
1319
 
1339
- TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimeManualCompaction) {
1320
+ TEST_P(PrecludeLastLevelTest, MigrationFromPreserveTimeManualCompaction) {
1340
1321
  const int kNumTrigger = 4;
1341
1322
  const int kNumLevels = 7;
1342
1323
  const int kNumKeys = 100;
@@ -1367,9 +1348,8 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimeManualCompaction) {
1367
1348
  ASSERT_EQ("0,0,0,0,0,0,1", FilesPerLevel());
1368
1349
 
1369
1350
  // enable preclude feature
1370
- options.preclude_last_level_data_seconds = 10000;
1371
- options.last_level_temperature = Temperature::kCold;
1372
- Reopen(options);
1351
+ ApplyConfigChange(&options, {{"preclude_last_level_data_seconds", "10000"},
1352
+ {"last_level_temperature", "kCold"}});
1373
1353
 
1374
1354
  // all data is hot, even they're in the last level
1375
1355
  ASSERT_EQ(GetSstSizeHelper(Temperature::kCold), 0);
@@ -1393,7 +1373,7 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimeManualCompaction) {
1393
1373
  Close();
1394
1374
  }
1395
1375
 
1396
- TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimeAutoCompaction) {
1376
+ TEST_P(PrecludeLastLevelTest, MigrationFromPreserveTimeAutoCompaction) {
1397
1377
  const int kNumTrigger = 4;
1398
1378
  const int kNumLevels = 7;
1399
1379
  const int kNumKeys = 100;
@@ -1423,16 +1403,17 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimeAutoCompaction) {
1423
1403
  // all data is pushed to the last level
1424
1404
  ASSERT_EQ("0,0,0,0,0,0,1", FilesPerLevel());
1425
1405
 
1426
- // enable preclude feature
1427
- options.preclude_last_level_data_seconds = 10000;
1428
- options.last_level_temperature = Temperature::kCold;
1406
+ // enable preclude feature, and...
1429
1407
  // make sure it won't trigger Size Amp compaction, unlike normal Size Amp
1430
1408
  // compaction which is typically a last level compaction, when tiered Storage
1431
1409
  // ("preclude_last_level") is enabled, size amp won't include the last level.
1432
1410
  // As the last level would be in cold tier and the size would not be a
1433
1411
  // problem, which also avoid frequent hot to cold storage compaction.
1434
- options.compaction_options_universal.max_size_amplification_percent = 400;
1435
- Reopen(options);
1412
+ ApplyConfigChange(
1413
+ &options,
1414
+ {{"preclude_last_level_data_seconds", "10000"},
1415
+ {"last_level_temperature", "kCold"},
1416
+ {"compaction_options_universal.max_size_amplification_percent", "400"}});
1436
1417
 
1437
1418
  // all data is hot, even they're in the last level
1438
1419
  ASSERT_EQ(GetSstSizeHelper(Temperature::kCold), 0);
@@ -1464,7 +1445,7 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimeAutoCompaction) {
1464
1445
  Close();
1465
1446
  }
1466
1447
 
1467
- TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimePartial) {
1448
+ TEST_P(PrecludeLastLevelTest, MigrationFromPreserveTimePartial) {
1468
1449
  const int kNumTrigger = 4;
1469
1450
  const int kNumLevels = 7;
1470
1451
  const int kNumKeys = 100;
@@ -1512,9 +1493,8 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimePartial) {
1512
1493
  }
1513
1494
 
1514
1495
  // enable preclude feature
1515
- options.preclude_last_level_data_seconds = 2000;
1516
- options.last_level_temperature = Temperature::kCold;
1517
- Reopen(options);
1496
+ ApplyConfigChange(&options, {{"preclude_last_level_data_seconds", "2000"},
1497
+ {"last_level_temperature", "kCold"}});
1518
1498
 
1519
1499
  // Generate a sstable and trigger manual compaction
1520
1500
  ASSERT_OK(Put(Key(10), "value"));
@@ -1532,7 +1512,7 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimePartial) {
1532
1512
  Close();
1533
1513
  }
1534
1514
 
1535
- TEST_F(PrecludeLastLevelTest, SmallPrecludeTime) {
1515
+ TEST_P(PrecludeLastLevelTest, SmallPrecludeTime) {
1536
1516
  const int kNumTrigger = 4;
1537
1517
  const int kNumLevels = 7;
1538
1518
  const int kNumKeys = 100;
@@ -1585,13 +1565,203 @@ TEST_F(PrecludeLastLevelTest, SmallPrecludeTime) {
1585
1565
  Close();
1586
1566
  }
1587
1567
 
1588
- // Test Param: protection_bytes_per_key for WriteBatch
1568
+ TEST_P(PrecludeLastLevelTest, CheckInternalKeyRange) {
1569
+ // When compacting keys from the last level to penultimate level,
1570
+ // output to penultimate level should be within internal key range
1571
+ // of input files from penultimate level.
1572
+ // Set up:
1573
+ // L5:
1574
+ // File 1: DeleteRange[1, 3)@4, File 2: [3@5, 100@6]
1575
+ // L6:
1576
+ // File 3: [2@1, 3@2], File 4: [50@3]
1577
+ //
1578
+ // When File 1 and File 3 are being compacted,
1579
+ // Key(3) cannot be compacted up, otherwise it causes
1580
+ // inconsistency where File 3's Key(3) has a lower sequence number
1581
+ // than File 2's Key(3).
1582
+ const int kNumLevels = 7;
1583
+ auto options = CurrentOptions();
1584
+ options.env = mock_env_.get();
1585
+ options.last_level_temperature = Temperature::kCold;
1586
+ options.level_compaction_dynamic_level_bytes = true;
1587
+ options.num_levels = kNumLevels;
1588
+ options.statistics = CreateDBStatistics();
1589
+ options.max_subcompactions = 10;
1590
+ options.preserve_internal_time_seconds = 10000;
1591
+ DestroyAndReopen(options);
1592
+ // File 3
1593
+ ASSERT_OK(Put(Key(2), "val2"));
1594
+ ASSERT_OK(Put(Key(3), "val3"));
1595
+ ASSERT_OK(Flush());
1596
+ MoveFilesToLevel(6);
1597
+ // File 4
1598
+ ASSERT_OK(Put(Key(50), "val50"));
1599
+ ASSERT_OK(Flush());
1600
+ MoveFilesToLevel(6);
1601
+
1602
+ ApplyConfigChange(&options, {{"preclude_last_level_data_seconds", "10000"}});
1603
+ const Snapshot* snapshot = db_->GetSnapshot();
1604
+
1605
+ // File 1
1606
+ std::string start = Key(1);
1607
+ std::string end = Key(3);
1608
+ ASSERT_OK(db_->DeleteRange({}, db_->DefaultColumnFamily(), start, end));
1609
+ ASSERT_OK(Flush());
1610
+ MoveFilesToLevel(5);
1611
+ // File 2
1612
+ ASSERT_OK(Put(Key(3), "vall"));
1613
+ ASSERT_OK(Put(Key(100), "val100"));
1614
+ ASSERT_OK(Flush());
1615
+ MoveFilesToLevel(5);
1616
+
1617
+ ASSERT_EQ("0,0,0,0,0,2,2", FilesPerLevel());
1618
+
1619
+ auto VerifyLogicalState = [&]() {
1620
+ // First with snapshot
1621
+ ASSERT_EQ("val2", Get(Key(2), snapshot));
1622
+ ASSERT_EQ("val3", Get(Key(3), snapshot));
1623
+ ASSERT_EQ("val50", Get(Key(50), snapshot));
1624
+ ASSERT_EQ("NOT_FOUND", Get(Key(100), snapshot));
1625
+
1626
+ // Then without snapshot
1627
+ ASSERT_EQ("NOT_FOUND", Get(Key(2)));
1628
+ ASSERT_EQ("vall", Get(Key(3)));
1629
+ ASSERT_EQ("val50", Get(Key(50)));
1630
+ ASSERT_EQ("val100", Get(Key(100)));
1631
+ };
1632
+
1633
+ VerifyLogicalState();
1634
+
1635
+ // Try to compact keys up
1636
+ CompactRangeOptions cro;
1637
+ cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
1638
+ // Without internal key range checking, we get the following error:
1639
+ // Corruption: force_consistency_checks(DEBUG): VersionBuilder: L5 has
1640
+ // overlapping ranges: file #18 largest key: '6B6579303030303033' seq:102,
1641
+ // type:1 vs. file #15 smallest key: '6B6579303030303033' seq:104, type:1
1642
+ ASSERT_OK(CompactRange(cro, Key(1), Key(2)));
1643
+
1644
+ VerifyLogicalState();
1645
+
1646
+ db_->ReleaseSnapshot(snapshot);
1647
+ Close();
1648
+ }
1649
+
1650
+ TEST_P(PrecludeLastLevelTest, RangeTombstoneSnapshotMigrateFromLast) {
1651
+ // Reproducer for issue originally described in
1652
+ // https://github.com/facebook/rocksdb/pull/9964/files#r1024449523
1653
+ if (!UseDynamicConfig()) {
1654
+ // Depends on config change while holding a snapshot
1655
+ return;
1656
+ }
1657
+ const int kNumLevels = 7;
1658
+ auto options = CurrentOptions();
1659
+ options.env = mock_env_.get();
1660
+ options.last_level_temperature = Temperature::kCold;
1661
+ options.level_compaction_dynamic_level_bytes = true;
1662
+ options.num_levels = kNumLevels;
1663
+ options.statistics = CreateDBStatistics();
1664
+ options.max_subcompactions = 10;
1665
+ options.preserve_internal_time_seconds = 30000;
1666
+ DestroyAndReopen(options);
1667
+
1668
+ // Entries with much older write time
1669
+ ASSERT_OK(Put(Key(2), "val2"));
1670
+ ASSERT_OK(Put(Key(6), "val6"));
1671
+
1672
+ for (int i = 0; i < 10; i++) {
1673
+ dbfull()->TEST_WaitForPeriodicTaskRun(
1674
+ [&] { mock_clock_->MockSleepForSeconds(static_cast<int>(1000)); });
1675
+ }
1676
+ const Snapshot* snapshot = db_->GetSnapshot();
1677
+
1678
+ ASSERT_OK(db_->DeleteRange({}, db_->DefaultColumnFamily(), Key(1), Key(5)));
1679
+ ASSERT_OK(Put(Key(1), "val1"));
1680
+ ASSERT_OK(Flush());
1681
+ MoveFilesToLevel(6);
1682
+ ASSERT_EQ("0,0,0,0,0,0,1", FilesPerLevel());
1683
+
1684
+ ApplyConfigChange(&options, {{"preclude_last_level_data_seconds", "10000"}});
1685
+
1686
+ // To exercise the WithinPenultimateLevelOutputRange feature, we want files
1687
+ // around the middle file to be compacted on the penultimate level
1688
+ ASSERT_OK(Put(Key(0), "val0"));
1689
+ ASSERT_OK(Flush());
1690
+ ASSERT_OK(Put(Key(3), "val3"));
1691
+ ASSERT_OK(Flush());
1692
+ ASSERT_OK(Put(Key(7), "val7"));
1693
+
1694
+ // FIXME: ideally this wouldn't be necessary to get a seqno to time entry
1695
+ // into a later compaction to get data into the last level
1696
+ dbfull()->TEST_WaitForPeriodicTaskRun(
1697
+ [&] { mock_clock_->MockSleepForSeconds(static_cast<int>(1000)); });
1698
+
1699
+ ASSERT_OK(Flush());
1700
+ MoveFilesToLevel(5);
1701
+ ASSERT_EQ("0,0,0,0,0,3,1", FilesPerLevel());
1702
+
1703
+ auto VerifyLogicalState = [&]() {
1704
+ // First with snapshot
1705
+ if (snapshot) {
1706
+ ASSERT_EQ("NOT_FOUND", Get(Key(0), snapshot));
1707
+ ASSERT_EQ("NOT_FOUND", Get(Key(1), snapshot));
1708
+ ASSERT_EQ("val2", Get(Key(2), snapshot));
1709
+ ASSERT_EQ("NOT_FOUND", Get(Key(3), snapshot));
1710
+ ASSERT_EQ("val6", Get(Key(6), snapshot));
1711
+ ASSERT_EQ("NOT_FOUND", Get(Key(7), snapshot));
1712
+ }
1713
+
1714
+ // Then without snapshot
1715
+ ASSERT_EQ("val0", Get(Key(0)));
1716
+ ASSERT_EQ("val1", Get(Key(1)));
1717
+ ASSERT_EQ("NOT_FOUND", Get(Key(2)));
1718
+ ASSERT_EQ("val3", Get(Key(3)));
1719
+ ASSERT_EQ("val6", Get(Key(6)));
1720
+ ASSERT_EQ("val7", Get(Key(7)));
1721
+ };
1722
+
1723
+ VerifyLogicalState();
1724
+
1725
+ // Try a limited range compaction
1726
+ // FIXME: this currently hits the "Unsafe to store Seq later than snapshot"
1727
+ // error. Needs to work safely for preclude option to be user mutable.
1728
+ // ASSERT_OK(CompactRange({}, Key(3), Key(4)));
1729
+ EXPECT_EQ("0,0,0,0,0,3,1", FilesPerLevel());
1730
+ VerifyLogicalState();
1731
+
1732
+ // Compact everything, but some data still goes to both penultimate and last
1733
+ // levels. A full-range compaction should be safe to "migrate" data from the
1734
+ // last level to penultimate (because of preclude setting change).
1735
+ ASSERT_OK(CompactRange({}, {}, {}));
1736
+ EXPECT_EQ("0,0,0,0,0,1,1", FilesPerLevel());
1737
+ VerifyLogicalState();
1738
+ // Key1 should have been migrated out of the last level
1739
+ auto& meta = *GetLevelFileMetadatas(6)[0];
1740
+ ASSERT_LT(Key(1), meta.smallest.user_key().ToString());
1741
+
1742
+ // Make data eligible for last level
1743
+ db_->ReleaseSnapshot(snapshot);
1744
+ snapshot = nullptr;
1745
+ mock_clock_->MockSleepForSeconds(static_cast<int>(10000));
1746
+
1747
+ ASSERT_OK(CompactRange({}, {}, {}));
1748
+ EXPECT_EQ("0,0,0,0,0,0,1", FilesPerLevel());
1749
+ VerifyLogicalState();
1750
+
1751
+ Close();
1752
+ }
1753
+
1754
+ INSTANTIATE_TEST_CASE_P(PrecludeLastLevelTest, PrecludeLastLevelTest,
1755
+ ::testing::Bool());
1756
+
1589
1757
  class TimedPutPrecludeLastLevelTest
1590
- : public PrecludeLastLevelTest,
1758
+ : public PrecludeLastLevelTestBase,
1591
1759
  public testing::WithParamInterface<size_t> {
1592
1760
  public:
1593
1761
  TimedPutPrecludeLastLevelTest()
1594
- : PrecludeLastLevelTest("timed_put_preclude_last_level_test") {}
1762
+ : PrecludeLastLevelTestBase("timed_put_preclude_last_level_test") {}
1763
+
1764
+ size_t ProtectionBytesPerKey() const { return GetParam(); }
1595
1765
  };
1596
1766
 
1597
1767
  TEST_P(TimedPutPrecludeLastLevelTest, FastTrackTimedPutToLastLevel) {
@@ -1609,7 +1779,7 @@ TEST_P(TimedPutPrecludeLastLevelTest, FastTrackTimedPutToLastLevel) {
1609
1779
  options.last_level_temperature = Temperature::kCold;
1610
1780
  DestroyAndReopen(options);
1611
1781
  WriteOptions wo;
1612
- wo.protection_bytes_per_key = GetParam();
1782
+ wo.protection_bytes_per_key = ProtectionBytesPerKey();
1613
1783
 
1614
1784
  Random rnd(301);
1615
1785
 
@@ -1663,7 +1833,7 @@ TEST_P(TimedPutPrecludeLastLevelTest, InterleavedTimedPutAndPut) {
1663
1833
  options.default_write_temperature = Temperature::kHot;
1664
1834
  DestroyAndReopen(options);
1665
1835
  WriteOptions wo;
1666
- wo.protection_bytes_per_key = GetParam();
1836
+ wo.protection_bytes_per_key = ProtectionBytesPerKey();
1667
1837
 
1668
1838
  // Start time: kMockStartTime = 10000000;
1669
1839
  ASSERT_OK(TimedPut(0, Key(0), "v0", kMockStartTime - 1 * 24 * 60 * 60, wo));
@@ -1689,7 +1859,7 @@ TEST_P(TimedPutPrecludeLastLevelTest, PreserveTimedPutOnPenultimateLevel) {
1689
1859
  options.default_write_temperature = Temperature::kHot;
1690
1860
  DestroyAndReopen(options);
1691
1861
  WriteOptions wo;
1692
- wo.protection_bytes_per_key = GetParam();
1862
+ wo.protection_bytes_per_key = ProtectionBytesPerKey();
1693
1863
 
1694
1864
  // Creating a snapshot to manually control when preferred sequence number is
1695
1865
  // swapped in. An entry's preferred seqno won't get swapped in until it's
@@ -1759,7 +1929,7 @@ TEST_P(TimedPutPrecludeLastLevelTest, AutoTriggerCompaction) {
1759
1929
  options.table_properties_collector_factories.push_back(factory);
1760
1930
  DestroyAndReopen(options);
1761
1931
  WriteOptions wo;
1762
- wo.protection_bytes_per_key = GetParam();
1932
+ wo.protection_bytes_per_key = ProtectionBytesPerKey();
1763
1933
 
1764
1934
  Random rnd(301);
1765
1935
 
@@ -1814,7 +1984,7 @@ TEST_P(TimedPutPrecludeLastLevelTest, AutoTriggerCompaction) {
1814
1984
  INSTANTIATE_TEST_CASE_P(TimedPutPrecludeLastLevelTest,
1815
1985
  TimedPutPrecludeLastLevelTest, ::testing::Values(0, 8));
1816
1986
 
1817
- TEST_F(PrecludeLastLevelTest, LastLevelOnlyCompactionPartial) {
1987
+ TEST_P(PrecludeLastLevelTest, LastLevelOnlyCompactionPartial) {
1818
1988
  const int kNumTrigger = 4;
1819
1989
  const int kNumLevels = 7;
1820
1990
  const int kNumKeys = 100;
@@ -1845,9 +2015,8 @@ TEST_F(PrecludeLastLevelTest, LastLevelOnlyCompactionPartial) {
1845
2015
  ASSERT_EQ("0,0,0,0,0,0,1", FilesPerLevel());
1846
2016
 
1847
2017
  // enable preclude feature
1848
- options.preclude_last_level_data_seconds = 2000;
1849
- options.last_level_temperature = Temperature::kCold;
1850
- Reopen(options);
2018
+ ApplyConfigChange(&options, {{"preclude_last_level_data_seconds", "2000"},
2019
+ {"last_level_temperature", "kCold"}});
1851
2020
 
1852
2021
  CompactRangeOptions cro;
1853
2022
  cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
@@ -1878,21 +2047,30 @@ TEST_F(PrecludeLastLevelTest, LastLevelOnlyCompactionPartial) {
1878
2047
  Close();
1879
2048
  }
1880
2049
 
1881
- class PrecludeLastLevelTestWithParms
1882
- : public PrecludeLastLevelTest,
1883
- public testing::WithParamInterface<bool> {
2050
+ class PrecludeLastLevelOptionalTest
2051
+ : public PrecludeLastLevelTestBase,
2052
+ public testing::WithParamInterface<std::tuple<bool, bool>> {
1884
2053
  public:
1885
- PrecludeLastLevelTestWithParms() : PrecludeLastLevelTest() {}
2054
+ bool UseDynamicConfig() const { return std::get<0>(GetParam()); }
2055
+
2056
+ void ApplyConfigChange(
2057
+ Options* options,
2058
+ const std::unordered_map<std::string, std::string>& config_change,
2059
+ const std::unordered_map<std::string, std::string>& db_config_change =
2060
+ {}) {
2061
+ ApplyConfigChangeImpl(UseDynamicConfig(), options, config_change,
2062
+ db_config_change);
2063
+ }
2064
+
2065
+ bool EnablePrecludeLastLevel() const { return std::get<1>(GetParam()); }
1886
2066
  };
1887
2067
 
1888
- TEST_P(PrecludeLastLevelTestWithParms, LastLevelOnlyCompactionNoPreclude) {
2068
+ TEST_P(PrecludeLastLevelOptionalTest, LastLevelOnlyCompactionNoPreclude) {
1889
2069
  const int kNumTrigger = 4;
1890
2070
  const int kNumLevels = 7;
1891
2071
  const int kNumKeys = 100;
1892
2072
  const int kKeyPerSec = 10;
1893
2073
 
1894
- bool enable_preclude_last_level = GetParam();
1895
-
1896
2074
  Options options = CurrentOptions();
1897
2075
  options.compaction_style = kCompactionStyleUniversal;
1898
2076
  options.preserve_internal_time_seconds = 2000;
@@ -1950,7 +2128,7 @@ TEST_P(PrecludeLastLevelTestWithParms, LastLevelOnlyCompactionNoPreclude) {
1950
2128
  SyncPoint::GetInstance()->SetCallBack(
1951
2129
  "UniversalCompactionBuilder::PickCompaction:Return", [&](void* arg) {
1952
2130
  auto compaction = static_cast<Compaction*>(arg);
1953
- if (enable_preclude_last_level && is_manual_compaction_running) {
2131
+ if (EnablePrecludeLastLevel() && is_manual_compaction_running) {
1954
2132
  ASSERT_TRUE(compaction == nullptr);
1955
2133
  verified_compaction_order = true;
1956
2134
  } else {
@@ -1977,12 +2155,11 @@ TEST_P(PrecludeLastLevelTestWithParms, LastLevelOnlyCompactionNoPreclude) {
1977
2155
  SyncPoint::GetInstance()->EnableProcessing();
1978
2156
 
1979
2157
  // only enable if the Parameter is true
1980
- if (enable_preclude_last_level) {
1981
- options.preclude_last_level_data_seconds = 2000;
1982
- }
1983
- options.max_background_jobs = 8;
1984
- options.last_level_temperature = Temperature::kCold;
1985
- Reopen(options);
2158
+ ApplyConfigChange(&options,
2159
+ {{"preclude_last_level_data_seconds",
2160
+ EnablePrecludeLastLevel() ? "2000" : "0"},
2161
+ {"last_level_temperature", "kCold"}},
2162
+ {{"max_background_jobs", "8"}});
1986
2163
 
1987
2164
  auto manual_compaction_thread = port::Thread([this]() {
1988
2165
  CompactRangeOptions cro;
@@ -2011,7 +2188,7 @@ TEST_P(PrecludeLastLevelTestWithParms, LastLevelOnlyCompactionNoPreclude) {
2011
2188
 
2012
2189
  ASSERT_OK(dbfull()->TEST_WaitForCompact());
2013
2190
 
2014
- if (enable_preclude_last_level) {
2191
+ if (EnablePrecludeLastLevel()) {
2015
2192
  ASSERT_NE("0,0,0,0,0,1,1", FilesPerLevel());
2016
2193
  } else {
2017
2194
  ASSERT_EQ("0,0,0,0,0,1,1", FilesPerLevel());
@@ -2025,7 +2202,7 @@ TEST_P(PrecludeLastLevelTestWithParms, LastLevelOnlyCompactionNoPreclude) {
2025
2202
  Close();
2026
2203
  }
2027
2204
 
2028
- TEST_P(PrecludeLastLevelTestWithParms, PeriodicCompactionToPenultimateLevel) {
2205
+ TEST_P(PrecludeLastLevelOptionalTest, PeriodicCompactionToPenultimateLevel) {
2029
2206
  // Test the last level only periodic compaction should also be blocked by an
2030
2207
  // ongoing compaction in penultimate level if tiered compaction is enabled
2031
2208
  // otherwise, the periodic compaction should just run for the last level.
@@ -2035,8 +2212,6 @@ TEST_P(PrecludeLastLevelTestWithParms, PeriodicCompactionToPenultimateLevel) {
2035
2212
  const int kKeyPerSec = 1;
2036
2213
  const int kNumKeys = 100;
2037
2214
 
2038
- bool enable_preclude_last_level = GetParam();
2039
-
2040
2215
  Options options = CurrentOptions();
2041
2216
  options.compaction_style = kCompactionStyleUniversal;
2042
2217
  options.preserve_internal_time_seconds = 20000;
@@ -2063,12 +2238,11 @@ TEST_P(PrecludeLastLevelTestWithParms, PeriodicCompactionToPenultimateLevel) {
2063
2238
  ASSERT_EQ("0,0,0,0,0,0,1", FilesPerLevel());
2064
2239
 
2065
2240
  // enable preclude feature
2066
- if (enable_preclude_last_level) {
2067
- options.preclude_last_level_data_seconds = 20000;
2068
- }
2069
- options.max_background_jobs = 8;
2070
- options.last_level_temperature = Temperature::kCold;
2071
- Reopen(options);
2241
+ ApplyConfigChange(&options,
2242
+ {{"preclude_last_level_data_seconds",
2243
+ EnablePrecludeLastLevel() ? "2000" : "0"},
2244
+ {"last_level_temperature", "kCold"}},
2245
+ {{"max_background_jobs", "8"}});
2072
2246
 
2073
2247
  std::atomic_bool is_size_ratio_compaction_running = false;
2074
2248
  std::atomic_bool verified_last_level_compaction = false;
@@ -2093,7 +2267,7 @@ TEST_P(PrecludeLastLevelTestWithParms, PeriodicCompactionToPenultimateLevel) {
2093
2267
  auto compaction = static_cast<Compaction*>(arg);
2094
2268
 
2095
2269
  if (is_size_ratio_compaction_running) {
2096
- if (enable_preclude_last_level) {
2270
+ if (EnablePrecludeLastLevel()) {
2097
2271
  ASSERT_TRUE(compaction == nullptr);
2098
2272
  } else {
2099
2273
  ASSERT_TRUE(compaction != nullptr);
@@ -2151,8 +2325,10 @@ TEST_P(PrecludeLastLevelTestWithParms, PeriodicCompactionToPenultimateLevel) {
2151
2325
  Close();
2152
2326
  }
2153
2327
 
2154
- INSTANTIATE_TEST_CASE_P(PrecludeLastLevelTestWithParms,
2155
- PrecludeLastLevelTestWithParms, testing::Bool());
2328
+ INSTANTIATE_TEST_CASE_P(PrecludeLastLevelOptionalTest,
2329
+ PrecludeLastLevelOptionalTest,
2330
+ ::testing::Combine(::testing::Bool(),
2331
+ ::testing::Bool()));
2156
2332
 
2157
2333
  // partition the SST into 3 ranges [0, 19] [20, 39] [40, ...]
2158
2334
  class ThreeRangesPartitioner : public SstPartitioner {
@@ -2196,7 +2372,7 @@ class ThreeRangesPartitionerFactory : public SstPartitionerFactory {
2196
2372
  }
2197
2373
  };
2198
2374
 
2199
- TEST_F(PrecludeLastLevelTest, PartialPenultimateLevelCompaction) {
2375
+ TEST_P(PrecludeLastLevelTest, PartialPenultimateLevelCompaction) {
2200
2376
  const int kNumTrigger = 4;
2201
2377
  const int kNumLevels = 7;
2202
2378
  const int kKeyPerSec = 10;
@@ -2207,6 +2383,7 @@ TEST_F(PrecludeLastLevelTest, PartialPenultimateLevelCompaction) {
2207
2383
  options.level0_file_num_compaction_trigger = kNumTrigger;
2208
2384
  options.preserve_internal_time_seconds = 10000;
2209
2385
  options.num_levels = kNumLevels;
2386
+ options.statistics = CreateDBStatistics();
2210
2387
  DestroyAndReopen(options);
2211
2388
 
2212
2389
  Random rnd(301);
@@ -2244,11 +2421,10 @@ TEST_F(PrecludeLastLevelTest, PartialPenultimateLevelCompaction) {
2244
2421
  // L6: [0, 299]
2245
2422
  ASSERT_EQ("0,0,0,0,0,3,1", FilesPerLevel());
2246
2423
 
2424
+ ASSERT_OK(options.statistics->Reset());
2247
2425
  // enable tiered storage feature
2248
- options.preclude_last_level_data_seconds = 10000;
2249
- options.last_level_temperature = Temperature::kCold;
2250
- options.statistics = CreateDBStatistics();
2251
- Reopen(options);
2426
+ ApplyConfigChange(&options, {{"preclude_last_level_data_seconds", "10000"},
2427
+ {"last_level_temperature", "kCold"}});
2252
2428
 
2253
2429
  ColumnFamilyMetaData meta;
2254
2430
  db_->GetColumnFamilyMetaData(&meta);
@@ -2294,7 +2470,7 @@ TEST_F(PrecludeLastLevelTest, PartialPenultimateLevelCompaction) {
2294
2470
  Close();
2295
2471
  }
2296
2472
 
2297
- TEST_F(PrecludeLastLevelTest, RangeDelsCauseFileEndpointsToOverlap) {
2473
+ TEST_P(PrecludeLastLevelTest, RangeDelsCauseFileEndpointsToOverlap) {
2298
2474
  const int kNumLevels = 7;
2299
2475
  const int kSecondsPerKey = 10;
2300
2476
  const int kNumFiles = 3;
@@ -2433,12 +2609,25 @@ TEST_F(PrecludeLastLevelTest, RangeDelsCauseFileEndpointsToOverlap) {
2433
2609
 
2434
2610
  // Tests DBIter::GetProperty("rocksdb.iterator.write-time") return a data's
2435
2611
  // approximate write unix time.
2436
- // Test Param:
2437
- // 1) use tailing iterator or regular iterator (when it applies)
2438
- class IteratorWriteTimeTest : public PrecludeLastLevelTest,
2439
- public testing::WithParamInterface<bool> {
2612
+ class IteratorWriteTimeTest
2613
+ : public PrecludeLastLevelTestBase,
2614
+ public testing::WithParamInterface<std::tuple<bool, bool>> {
2440
2615
  public:
2441
- IteratorWriteTimeTest() : PrecludeLastLevelTest("iterator_write_time_test") {}
2616
+ IteratorWriteTimeTest()
2617
+ : PrecludeLastLevelTestBase("iterator_write_time_test") {}
2618
+
2619
+ bool UseTailingIterator() const { return std::get<0>(GetParam()); }
2620
+
2621
+ bool UseDynamicConfig() const { return std::get<1>(GetParam()); }
2622
+
2623
+ void ApplyConfigChange(
2624
+ Options* options,
2625
+ const std::unordered_map<std::string, std::string>& config_change,
2626
+ const std::unordered_map<std::string, std::string>& db_config_change =
2627
+ {}) {
2628
+ ApplyConfigChangeImpl(UseDynamicConfig(), options, config_change,
2629
+ db_config_change);
2630
+ }
2442
2631
 
2443
2632
  uint64_t VerifyKeyAndGetWriteTime(Iterator* iter,
2444
2633
  const std::string& expected_key) {
@@ -2478,10 +2667,14 @@ TEST_P(IteratorWriteTimeTest, ReadFromMemtables) {
2478
2667
  options.compaction_style = kCompactionStyleUniversal;
2479
2668
  options.env = mock_env_.get();
2480
2669
  options.level0_file_num_compaction_trigger = kNumTrigger;
2481
- options.preserve_internal_time_seconds = 10000;
2482
2670
  options.num_levels = kNumLevels;
2483
2671
  DestroyAndReopen(options);
2484
2672
 
2673
+ // While there are issues with tracking seqno 0
2674
+ ASSERT_OK(Delete("something_to_bump_seqno"));
2675
+
2676
+ ApplyConfigChange(&options, {{"preserve_internal_time_seconds", "10000"}});
2677
+
2485
2678
  Random rnd(301);
2486
2679
  for (int i = 0; i < kNumKeys; i++) {
2487
2680
  dbfull()->TEST_WaitForPeriodicTaskRun(
@@ -2495,7 +2688,7 @@ TEST_P(IteratorWriteTimeTest, ReadFromMemtables) {
2495
2688
  }
2496
2689
 
2497
2690
  ReadOptions ropts;
2498
- ropts.tailing = GetParam();
2691
+ ropts.tailing = UseTailingIterator();
2499
2692
  int i;
2500
2693
 
2501
2694
  // Forward iteration
@@ -2535,10 +2728,9 @@ TEST_P(IteratorWriteTimeTest, ReadFromMemtables) {
2535
2728
  ASSERT_EQ(-1, i);
2536
2729
  }
2537
2730
 
2538
- // Reopen the DB and disable the seqno to time recording, data with user
2539
- // specified write time can still get a write time before it's flushed.
2540
- options.preserve_internal_time_seconds = 0;
2541
- Reopen(options);
2731
+ // Disable the seqno to time recording. Data with user specified write time
2732
+ // can still get a write time before it's flushed.
2733
+ ApplyConfigChange(&options, {{"preserve_internal_time_seconds", "0"}});
2542
2734
  ASSERT_OK(TimedPut(Key(kKeyWithWriteTime), rnd.RandomString(100),
2543
2735
  kUserSpecifiedWriteTime));
2544
2736
  {
@@ -2574,10 +2766,14 @@ TEST_P(IteratorWriteTimeTest, ReadFromSstFile) {
2574
2766
  options.compaction_style = kCompactionStyleUniversal;
2575
2767
  options.env = mock_env_.get();
2576
2768
  options.level0_file_num_compaction_trigger = kNumTrigger;
2577
- options.preserve_internal_time_seconds = 10000;
2578
2769
  options.num_levels = kNumLevels;
2579
2770
  DestroyAndReopen(options);
2580
2771
 
2772
+ // While there are issues with tracking seqno 0
2773
+ ASSERT_OK(Delete("something_to_bump_seqno"));
2774
+
2775
+ ApplyConfigChange(&options, {{"preserve_internal_time_seconds", "10000"}});
2776
+
2581
2777
  Random rnd(301);
2582
2778
  for (int i = 0; i < kNumKeys; i++) {
2583
2779
  dbfull()->TEST_WaitForPeriodicTaskRun(
@@ -2592,7 +2788,7 @@ TEST_P(IteratorWriteTimeTest, ReadFromSstFile) {
2592
2788
 
2593
2789
  ASSERT_OK(Flush());
2594
2790
  ReadOptions ropts;
2595
- ropts.tailing = GetParam();
2791
+ ropts.tailing = UseTailingIterator();
2596
2792
  std::string prop;
2597
2793
  int i;
2598
2794
 
@@ -2638,10 +2834,9 @@ TEST_P(IteratorWriteTimeTest, ReadFromSstFile) {
2638
2834
  ASSERT_EQ(-1, i);
2639
2835
  }
2640
2836
 
2641
- // Reopen the DB and disable the seqno to time recording. Data retrieved from
2642
- // SST files still have write time available.
2643
- options.preserve_internal_time_seconds = 0;
2644
- Reopen(options);
2837
+ // Disable the seqno to time recording. Data retrieved from SST files still
2838
+ // have write time available.
2839
+ ApplyConfigChange(&options, {{"preserve_internal_time_seconds", "0"}});
2645
2840
 
2646
2841
  dbfull()->TEST_WaitForPeriodicTaskRun(
2647
2842
  [&] { mock_clock_->MockSleepForSeconds(kSecondsPerRecording); });
@@ -2705,11 +2900,12 @@ TEST_P(IteratorWriteTimeTest, MergeReturnsBaseValueWriteTime) {
2705
2900
  options.compaction_style = kCompactionStyleUniversal;
2706
2901
  options.env = mock_env_.get();
2707
2902
  options.level0_file_num_compaction_trigger = kNumTrigger;
2708
- options.preserve_internal_time_seconds = 10000;
2709
2903
  options.num_levels = kNumLevels;
2710
2904
  options.merge_operator = MergeOperators::CreateStringAppendOperator();
2711
2905
  DestroyAndReopen(options);
2712
2906
 
2907
+ ApplyConfigChange(&options, {{"preserve_internal_time_seconds", "10000"}});
2908
+
2713
2909
  dbfull()->TEST_WaitForPeriodicTaskRun(
2714
2910
  [&] { mock_clock_->MockSleepForSeconds(kSecondsPerRecording); });
2715
2911
  ASSERT_OK(Put("foo", "fv1"));
@@ -2720,7 +2916,7 @@ TEST_P(IteratorWriteTimeTest, MergeReturnsBaseValueWriteTime) {
2720
2916
  ASSERT_OK(Merge("foo", "bv1"));
2721
2917
 
2722
2918
  ReadOptions ropts;
2723
- ropts.tailing = GetParam();
2919
+ ropts.tailing = UseTailingIterator();
2724
2920
  {
2725
2921
  std::unique_ptr<Iterator> iter(dbfull()->NewIterator(ropts));
2726
2922
  iter->SeekToFirst();
@@ -2738,7 +2934,7 @@ TEST_P(IteratorWriteTimeTest, MergeReturnsBaseValueWriteTime) {
2738
2934
  }
2739
2935
 
2740
2936
  INSTANTIATE_TEST_CASE_P(IteratorWriteTimeTest, IteratorWriteTimeTest,
2741
- testing::Bool());
2937
+ testing::Combine(testing::Bool(), testing::Bool()));
2742
2938
 
2743
2939
  } // namespace ROCKSDB_NAMESPACE
2744
2940