@nxtedition/rocksdb 7.1.4 → 7.1.7

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 (185) hide show
  1. package/binding.cc +32 -14
  2. package/deps/rocksdb/iostats.patch +19 -0
  3. package/deps/rocksdb/rocksdb/CMakeLists.txt +15 -1
  4. package/deps/rocksdb/rocksdb/cache/cache.cc +4 -0
  5. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +6 -8
  6. package/deps/rocksdb/rocksdb/cache/cache_key.cc +184 -164
  7. package/deps/rocksdb/rocksdb/cache/cache_key.h +38 -29
  8. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager_test.cc +4 -4
  9. package/deps/rocksdb/rocksdb/cache/cache_test.cc +93 -58
  10. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +92 -42
  11. package/deps/rocksdb/rocksdb/cache/clock_cache.h +57 -32
  12. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +114 -37
  13. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +34 -2
  14. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +187 -38
  15. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +3 -1
  16. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +88 -19
  17. package/deps/rocksdb/rocksdb/cache/lru_cache.h +48 -8
  18. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +481 -224
  19. package/deps/rocksdb/rocksdb/crash_test.mk +15 -1
  20. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.cc +2 -2
  21. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.cc +3 -7
  22. package/deps/rocksdb/rocksdb/db/blob/blob_index.h +1 -1
  23. package/deps/rocksdb/rocksdb/db/blob/blob_log_format.cc +3 -5
  24. package/deps/rocksdb/rocksdb/db/blob/blob_log_writer.cc +25 -19
  25. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +4 -5
  26. package/deps/rocksdb/rocksdb/db/blob/blob_source.h +2 -3
  27. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +12 -4
  28. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +149 -0
  29. package/deps/rocksdb/rocksdb/db/blob/db_blob_compaction_test.cc +105 -0
  30. package/deps/rocksdb/rocksdb/db/column_family.cc +2 -15
  31. package/deps/rocksdb/rocksdb/db/column_family_test.cc +17 -4
  32. package/deps/rocksdb/rocksdb/db/compact_files_test.cc +8 -8
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +0 -7
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +5 -0
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +56 -53
  36. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +33 -11
  37. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +45 -11
  38. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +1 -2
  39. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +143 -2
  40. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +43 -18
  41. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +48 -65
  42. package/deps/rocksdb/rocksdb/db/corruption_test.cc +1 -0
  43. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +73 -4
  44. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +239 -190
  45. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +71 -2
  46. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +144 -33
  47. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +18 -35
  48. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +11 -5
  49. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +7 -7
  50. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +15 -8
  51. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +2 -1
  52. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +3 -1
  53. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +11 -0
  54. package/deps/rocksdb/rocksdb/db/db_iter.cc +69 -11
  55. package/deps/rocksdb/rocksdb/db/db_iter.h +16 -0
  56. package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +239 -23
  57. package/deps/rocksdb/rocksdb/db/db_memtable_test.cc +2 -1
  58. package/deps/rocksdb/rocksdb/db/db_merge_operand_test.cc +42 -0
  59. package/deps/rocksdb/rocksdb/db/db_test.cc +61 -28
  60. package/deps/rocksdb/rocksdb/db/db_test2.cc +24 -9
  61. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +17 -0
  62. package/deps/rocksdb/rocksdb/db/db_with_timestamp_compaction_test.cc +61 -0
  63. package/deps/rocksdb/rocksdb/db/db_write_test.cc +130 -0
  64. package/deps/rocksdb/rocksdb/db/event_helpers.cc +2 -1
  65. package/deps/rocksdb/rocksdb/db/experimental.cc +7 -8
  66. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +1 -2
  67. package/deps/rocksdb/rocksdb/db/flush_job.cc +11 -7
  68. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +7 -1
  69. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +4 -2
  70. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +7 -1
  71. package/deps/rocksdb/rocksdb/db/import_column_family_job.h +6 -0
  72. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +6 -0
  73. package/deps/rocksdb/rocksdb/db/kv_checksum.h +8 -4
  74. package/deps/rocksdb/rocksdb/db/log_reader.cc +48 -11
  75. package/deps/rocksdb/rocksdb/db/log_reader.h +8 -2
  76. package/deps/rocksdb/rocksdb/db/log_test.cc +10 -1
  77. package/deps/rocksdb/rocksdb/db/log_writer.cc +7 -1
  78. package/deps/rocksdb/rocksdb/db/manual_compaction_test.cc +4 -4
  79. package/deps/rocksdb/rocksdb/db/memtable.cc +222 -47
  80. package/deps/rocksdb/rocksdb/db/memtable.h +70 -14
  81. package/deps/rocksdb/rocksdb/db/memtable_list.cc +14 -8
  82. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +30 -10
  83. package/deps/rocksdb/rocksdb/db/perf_context_test.cc +5 -5
  84. package/deps/rocksdb/rocksdb/db/pinned_iterators_manager.h +5 -0
  85. package/deps/rocksdb/rocksdb/db/repair.cc +2 -3
  86. package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +3 -7
  87. package/deps/rocksdb/rocksdb/db/table_cache.cc +72 -0
  88. package/deps/rocksdb/rocksdb/db/table_cache.h +19 -1
  89. package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +10 -15
  90. package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +2 -2
  91. package/deps/rocksdb/rocksdb/db/version_builder_test.cc +35 -64
  92. package/deps/rocksdb/rocksdb/db/version_edit.cc +3 -32
  93. package/deps/rocksdb/rocksdb/db/version_edit.h +2 -12
  94. package/deps/rocksdb/rocksdb/db/version_edit_test.cc +10 -23
  95. package/deps/rocksdb/rocksdb/db/version_set.cc +71 -28
  96. package/deps/rocksdb/rocksdb/db/version_set.h +3 -3
  97. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +7 -7
  98. package/deps/rocksdb/rocksdb/db/version_set_test.cc +17 -15
  99. package/deps/rocksdb/rocksdb/db/wal_manager.cc +0 -4
  100. package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +2 -1
  101. package/deps/rocksdb/rocksdb/db/wide/db_wide_basic_test.cc +137 -42
  102. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +21 -0
  103. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +1 -0
  104. package/deps/rocksdb/rocksdb/db/write_batch_test.cc +2 -1
  105. package/deps/rocksdb/rocksdb/db/write_callback_test.cc +4 -4
  106. package/deps/rocksdb/rocksdb/db/write_thread.cc +51 -46
  107. package/deps/rocksdb/rocksdb/db/write_thread.h +0 -4
  108. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +5 -0
  109. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +12 -0
  110. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +8 -0
  111. package/deps/rocksdb/rocksdb/env/env_posix.cc +1 -1
  112. package/deps/rocksdb/rocksdb/env/env_test.cc +38 -8
  113. package/deps/rocksdb/rocksdb/env/file_system.cc +20 -0
  114. package/deps/rocksdb/rocksdb/env/fs_posix.cc +2 -46
  115. package/deps/rocksdb/rocksdb/env/io_posix.cc +1 -0
  116. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +110 -5
  117. package/deps/rocksdb/rocksdb/file/writable_file_writer.h +7 -0
  118. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +29 -1
  119. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +31 -6
  120. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +4 -0
  121. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +1 -1
  122. package/deps/rocksdb/rocksdb/include/rocksdb/iostats_context.h +7 -0
  123. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +10 -3
  124. package/deps/rocksdb/rocksdb/include/rocksdb/slice.h +3 -1
  125. package/deps/rocksdb/rocksdb/include/rocksdb/status.h +1 -1
  126. package/deps/rocksdb/rocksdb/include/rocksdb/wide_columns.h +2 -0
  127. package/deps/rocksdb/rocksdb/logging/auto_roll_logger.cc +12 -0
  128. package/deps/rocksdb/rocksdb/logging/auto_roll_logger_test.cc +9 -13
  129. package/deps/rocksdb/rocksdb/logging/env_logger.h +39 -13
  130. package/deps/rocksdb/rocksdb/memory/memory_allocator_test.cc +1 -1
  131. package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +1 -1
  132. package/deps/rocksdb/rocksdb/memtable/write_buffer_manager_test.cc +1 -1
  133. package/deps/rocksdb/rocksdb/microbench/db_basic_bench.cc +6 -0
  134. package/deps/rocksdb/rocksdb/monitoring/iostats_context_imp.h +4 -1
  135. package/deps/rocksdb/rocksdb/options/cf_options.cc +10 -3
  136. package/deps/rocksdb/rocksdb/options/cf_options.h +10 -5
  137. package/deps/rocksdb/rocksdb/options/options_helper.cc +4 -1
  138. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +3 -1
  139. package/deps/rocksdb/rocksdb/options/options_test.cc +4 -2
  140. package/deps/rocksdb/rocksdb/port/util_logger.h +1 -3
  141. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +2 -6
  142. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +1 -0
  143. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +52 -12
  144. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +5 -7
  145. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +9 -1
  146. package/deps/rocksdb/rocksdb/table/block_based/block_like_traits.h +28 -10
  147. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +1 -1
  148. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +5 -2
  149. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +1 -0
  150. package/deps/rocksdb/rocksdb/table/get_context.cc +16 -6
  151. package/deps/rocksdb/rocksdb/table/table_reader.h +9 -0
  152. package/deps/rocksdb/rocksdb/table/table_test.cc +2 -1
  153. package/deps/rocksdb/rocksdb/table/unique_id.cc +22 -24
  154. package/deps/rocksdb/rocksdb/table/unique_id_impl.h +2 -1
  155. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py +7 -0
  156. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +41 -4
  157. package/deps/rocksdb/rocksdb/tools/db_sanity_test.cc +5 -2
  158. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +7 -8
  159. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +6 -6
  160. package/deps/rocksdb/rocksdb/tools/reduce_levels_test.cc +1 -1
  161. package/deps/rocksdb/rocksdb/util/async_file_reader.cc +2 -1
  162. package/deps/rocksdb/rocksdb/util/async_file_reader.h +3 -3
  163. package/deps/rocksdb/rocksdb/util/coro_utils.h +2 -1
  164. package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +2 -0
  165. package/deps/rocksdb/rocksdb/util/hash_test.cc +67 -0
  166. package/deps/rocksdb/rocksdb/util/math.h +41 -0
  167. package/deps/rocksdb/rocksdb/util/math128.h +6 -0
  168. package/deps/rocksdb/rocksdb/util/single_thread_executor.h +2 -1
  169. package/deps/rocksdb/rocksdb/util/stderr_logger.h +13 -0
  170. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +55 -46
  171. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +3 -6
  172. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_functional_test.cc +2 -1
  173. package/deps/rocksdb/rocksdb/utilities/counted_fs.cc +10 -0
  174. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager_test.h +5 -0
  175. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_lock_manager.h +6 -0
  176. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_locking_test.cc +2 -2
  177. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_test.cc +2 -2
  178. package/deps/rocksdb/rocksdb/utilities/ttl/ttl_test.cc +2 -2
  179. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +2 -2
  180. package/index.js +17 -8
  181. package/package.json +1 -1
  182. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  183. package/prebuilds/darwin-x64/node.napi.node +0 -0
  184. package/prebuilds/linux-x64/node.napi.node +0 -0
  185. package/deps/rocksdb/rocksdb/logging/posix_logger.h +0 -179
@@ -116,8 +116,7 @@ class CompactionPickerTest : public testing::Test {
116
116
  InternalKey(largest, largest_seq, kTypeValue), smallest_seq,
117
117
  largest_seq, marked_for_compact, temperature, kInvalidBlobFileNumber,
118
118
  kUnknownOldestAncesterTime, kUnknownFileCreationTime,
119
- kUnknownFileChecksum, kUnknownFileChecksumFuncName,
120
- kDisableUserTimestamp, kDisableUserTimestamp, kNullUniqueId64x2);
119
+ kUnknownFileChecksum, kUnknownFileChecksumFuncName, kNullUniqueId64x2);
121
120
  f->compensated_file_size =
122
121
  (compensated_file_size != 0) ? compensated_file_size : file_size;
123
122
  f->oldest_ancester_time = oldest_ancestor_time;
@@ -3176,6 +3175,148 @@ TEST_F(CompactionPickerTest, UniversalMarkedManualCompaction) {
3176
3175
  ASSERT_EQ(0U, vstorage_->FilesMarkedForCompaction().size());
3177
3176
  }
3178
3177
 
3178
+ TEST_F(CompactionPickerTest, UniversalSizeAmpTierCompactionNonLastLevel) {
3179
+ // This test make sure size amplification compaction could still be triggered
3180
+ // if the last sorted run is not the last level.
3181
+ const uint64_t kFileSize = 100000;
3182
+ const int kNumLevels = 7;
3183
+ const int kLastLevel = kNumLevels - 1;
3184
+
3185
+ ioptions_.compaction_style = kCompactionStyleUniversal;
3186
+ ioptions_.preclude_last_level_data_seconds = 1000;
3187
+ mutable_cf_options_.compaction_options_universal
3188
+ .max_size_amplification_percent = 200;
3189
+ UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
3190
+
3191
+ NewVersionStorage(kNumLevels, kCompactionStyleUniversal);
3192
+ Add(0, 100U, "100", "300", 1 * kFileSize);
3193
+ Add(0, 101U, "200", "400", 1 * kFileSize);
3194
+ Add(4, 90U, "100", "600", 4 * kFileSize);
3195
+ Add(5, 80U, "200", "300", 2 * kFileSize);
3196
+ UpdateVersionStorageInfo();
3197
+
3198
+ std::unique_ptr<Compaction> compaction(
3199
+ universal_compaction_picker.PickCompaction(
3200
+ cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
3201
+ &log_buffer_));
3202
+
3203
+ // Make sure it's a size amp compaction and includes all files
3204
+ ASSERT_EQ(compaction->compaction_reason(),
3205
+ CompactionReason::kUniversalSizeAmplification);
3206
+ ASSERT_EQ(compaction->output_level(), kLastLevel);
3207
+ ASSERT_EQ(compaction->input_levels(0)->num_files, 2);
3208
+ ASSERT_EQ(compaction->input_levels(4)->num_files, 1);
3209
+ ASSERT_EQ(compaction->input_levels(5)->num_files, 1);
3210
+ }
3211
+
3212
+ TEST_F(CompactionPickerTest, UniversalSizeRatioTierCompactionLastLevel) {
3213
+ // This test makes sure the size amp calculation skips the last level (L6), so
3214
+ // size amp compaction is not triggered, instead a size ratio compaction is
3215
+ // triggered.
3216
+ const uint64_t kFileSize = 100000;
3217
+ const int kNumLevels = 7;
3218
+ const int kLastLevel = kNumLevels - 1;
3219
+ const int kPenultimateLevel = kLastLevel - 1;
3220
+
3221
+ ioptions_.compaction_style = kCompactionStyleUniversal;
3222
+ ioptions_.preclude_last_level_data_seconds = 1000;
3223
+ mutable_cf_options_.compaction_options_universal
3224
+ .max_size_amplification_percent = 200;
3225
+ UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
3226
+
3227
+ NewVersionStorage(kNumLevels, kCompactionStyleUniversal);
3228
+ Add(0, 100U, "100", "300", 1 * kFileSize);
3229
+ Add(0, 101U, "200", "400", 1 * kFileSize);
3230
+ Add(5, 90U, "100", "600", 4 * kFileSize);
3231
+ Add(6, 80U, "200", "300", 2 * kFileSize);
3232
+ UpdateVersionStorageInfo();
3233
+
3234
+ std::unique_ptr<Compaction> compaction(
3235
+ universal_compaction_picker.PickCompaction(
3236
+ cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
3237
+ &log_buffer_));
3238
+
3239
+ // Internally, size amp compaction is evaluated before size ratio compaction.
3240
+ // Here to make sure it's size ratio compaction instead of size amp
3241
+ ASSERT_EQ(compaction->compaction_reason(),
3242
+ CompactionReason::kUniversalSizeRatio);
3243
+ ASSERT_EQ(compaction->output_level(), kPenultimateLevel - 1);
3244
+ ASSERT_EQ(compaction->input_levels(0)->num_files, 2);
3245
+ ASSERT_EQ(compaction->input_levels(5)->num_files, 0);
3246
+ ASSERT_EQ(compaction->input_levels(6)->num_files, 0);
3247
+ }
3248
+
3249
+ TEST_F(CompactionPickerTest, UniversalSizeAmpTierCompactionNotSuport) {
3250
+ // Tiered compaction only support level_num > 2 (otherwise the penultimate
3251
+ // level is going to be level 0, which may make thing more complicated), so
3252
+ // when there's only 2 level, still treating level 1 as the last level for
3253
+ // size amp compaction
3254
+ const uint64_t kFileSize = 100000;
3255
+ const int kNumLevels = 2;
3256
+ const int kLastLevel = kNumLevels - 1;
3257
+
3258
+ ioptions_.compaction_style = kCompactionStyleUniversal;
3259
+ ioptions_.preclude_last_level_data_seconds = 1000;
3260
+ mutable_cf_options_.compaction_options_universal
3261
+ .max_size_amplification_percent = 200;
3262
+ UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
3263
+
3264
+ NewVersionStorage(kNumLevels, kCompactionStyleUniversal);
3265
+ Add(0, 100U, "100", "300", 1 * kFileSize);
3266
+ Add(0, 101U, "200", "400", 1 * kFileSize);
3267
+ Add(0, 90U, "100", "600", 4 * kFileSize);
3268
+ Add(1, 80U, "200", "300", 2 * kFileSize);
3269
+ UpdateVersionStorageInfo();
3270
+
3271
+ std::unique_ptr<Compaction> compaction(
3272
+ universal_compaction_picker.PickCompaction(
3273
+ cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
3274
+ &log_buffer_));
3275
+
3276
+ // size amp compaction is still triggered even preclude_last_level is set
3277
+ ASSERT_EQ(compaction->compaction_reason(),
3278
+ CompactionReason::kUniversalSizeAmplification);
3279
+ ASSERT_EQ(compaction->output_level(), kLastLevel);
3280
+ ASSERT_EQ(compaction->input_levels(0)->num_files, 3);
3281
+ ASSERT_EQ(compaction->input_levels(1)->num_files, 1);
3282
+ }
3283
+
3284
+ TEST_F(CompactionPickerTest, UniversalSizeAmpTierCompactionLastLevel) {
3285
+ // This test makes sure the size amp compaction for tiered storage could still
3286
+ // be triggered, but only for non-last-level files
3287
+ const uint64_t kFileSize = 100000;
3288
+ const int kNumLevels = 7;
3289
+ const int kLastLevel = kNumLevels - 1;
3290
+ const int kPenultimateLevel = kLastLevel - 1;
3291
+
3292
+ ioptions_.compaction_style = kCompactionStyleUniversal;
3293
+ ioptions_.preclude_last_level_data_seconds = 1000;
3294
+ mutable_cf_options_.compaction_options_universal
3295
+ .max_size_amplification_percent = 200;
3296
+ UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
3297
+
3298
+ NewVersionStorage(kNumLevels, kCompactionStyleUniversal);
3299
+ Add(0, 100U, "100", "300", 3 * kFileSize);
3300
+ Add(0, 101U, "200", "400", 2 * kFileSize);
3301
+ Add(5, 90U, "100", "600", 2 * kFileSize);
3302
+ Add(6, 80U, "200", "300", 2 * kFileSize);
3303
+ UpdateVersionStorageInfo();
3304
+
3305
+ std::unique_ptr<Compaction> compaction(
3306
+ universal_compaction_picker.PickCompaction(
3307
+ cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
3308
+ &log_buffer_));
3309
+
3310
+ // It's a Size Amp compaction, but doesn't include the last level file and
3311
+ // output to the penultimate level.
3312
+ ASSERT_EQ(compaction->compaction_reason(),
3313
+ CompactionReason::kUniversalSizeAmplification);
3314
+ ASSERT_EQ(compaction->output_level(), kPenultimateLevel);
3315
+ ASSERT_EQ(compaction->input_levels(0)->num_files, 2);
3316
+ ASSERT_EQ(compaction->input_levels(5)->num_files, 1);
3317
+ ASSERT_EQ(compaction->input_levels(6)->num_files, 0);
3318
+ }
3319
+
3179
3320
  class PerKeyPlacementCompactionPickerTest
3180
3321
  : public CompactionPickerTest,
3181
3322
  public testing::WithParamInterface<bool> {
@@ -106,6 +106,9 @@ class UniversalCompactionBuilder {
106
106
  Compaction* PickCompactionToOldest(size_t start_index,
107
107
  CompactionReason compaction_reason);
108
108
 
109
+ Compaction* PickCompactionWithSortedRunRange(
110
+ size_t start_index, size_t end_index, CompactionReason compaction_reason);
111
+
109
112
  // Try to pick periodic compaction. The caller should only call it
110
113
  // if there is at least one file marked for periodic compaction.
111
114
  // null will be returned if no such a compaction can be formed
@@ -811,8 +814,20 @@ Compaction* UniversalCompactionBuilder::PickCompactionToReduceSizeAmp() {
811
814
  cf_name_.c_str(), file_num_buf, start_index, " to reduce size amp.\n");
812
815
  }
813
816
 
817
+ // size of the base sorted run for size amp calculation
818
+ uint64_t base_sr_size = sorted_runs_.back().size;
819
+ size_t sr_end_idx = sorted_runs_.size() - 1;
820
+ // If tiered compaction is enabled and the last sorted run is the last level
821
+ if (ioptions_.preclude_last_level_data_seconds > 0 &&
822
+ ioptions_.num_levels > 2 &&
823
+ sorted_runs_.back().level == ioptions_.num_levels - 1 &&
824
+ sorted_runs_.size() > 1) {
825
+ sr_end_idx = sorted_runs_.size() - 2;
826
+ base_sr_size = sorted_runs_[sr_end_idx].size;
827
+ }
828
+
814
829
  // keep adding up all the remaining files
815
- for (size_t loop = start_index; loop + 1 < sorted_runs_.size(); loop++) {
830
+ for (size_t loop = start_index; loop < sr_end_idx; loop++) {
816
831
  sr = &sorted_runs_[loop];
817
832
  if (sr->being_compacted) {
818
833
  // TODO with incremental compaction is supported, we might want to
@@ -832,23 +847,20 @@ Compaction* UniversalCompactionBuilder::PickCompactionToReduceSizeAmp() {
832
847
  return nullptr;
833
848
  }
834
849
 
835
- // size of earliest file
836
- uint64_t earliest_file_size = sorted_runs_.back().size;
837
-
838
850
  // size amplification = percentage of additional size
839
- if (candidate_size * 100 < ratio * earliest_file_size) {
851
+ if (candidate_size * 100 < ratio * base_sr_size) {
840
852
  ROCKS_LOG_BUFFER(
841
853
  log_buffer_,
842
854
  "[%s] Universal: size amp not needed. newer-files-total-size %" PRIu64
843
855
  " earliest-file-size %" PRIu64,
844
- cf_name_.c_str(), candidate_size, earliest_file_size);
856
+ cf_name_.c_str(), candidate_size, base_sr_size);
845
857
  return nullptr;
846
858
  } else {
847
859
  ROCKS_LOG_BUFFER(
848
860
  log_buffer_,
849
861
  "[%s] Universal: size amp needed. newer-files-total-size %" PRIu64
850
862
  " earliest-file-size %" PRIu64,
851
- cf_name_.c_str(), candidate_size, earliest_file_size);
863
+ cf_name_.c_str(), candidate_size, base_sr_size);
852
864
  }
853
865
  // Since incremental compaction can't include more than second last
854
866
  // level, it can introduce penalty, compared to full compaction. We
@@ -860,7 +872,7 @@ Compaction* UniversalCompactionBuilder::PickCompactionToReduceSizeAmp() {
860
872
  // This also prevent the case when compaction falls behind and we
861
873
  // need to compact more levels for compactions to catch up.
862
874
  if (mutable_cf_options_.compaction_options_universal.incremental) {
863
- double fanout_threshold = static_cast<double>(earliest_file_size) /
875
+ double fanout_threshold = static_cast<double>(base_sr_size) /
864
876
  static_cast<double>(candidate_size) * 1.8;
865
877
  Compaction* picked = PickIncrementalForReduceSizeAmp(fanout_threshold);
866
878
  if (picked != nullptr) {
@@ -869,8 +881,8 @@ Compaction* UniversalCompactionBuilder::PickCompactionToReduceSizeAmp() {
869
881
  return picked;
870
882
  }
871
883
  }
872
- return PickCompactionToOldest(start_index,
873
- CompactionReason::kUniversalSizeAmplification);
884
+ return PickCompactionWithSortedRunRange(
885
+ start_index, sr_end_idx, CompactionReason::kUniversalSizeAmplification);
874
886
  }
875
887
 
876
888
  Compaction* UniversalCompactionBuilder::PickIncrementalForReduceSizeAmp(
@@ -1233,11 +1245,17 @@ Compaction* UniversalCompactionBuilder::PickDeleteTriggeredCompaction() {
1233
1245
 
1234
1246
  Compaction* UniversalCompactionBuilder::PickCompactionToOldest(
1235
1247
  size_t start_index, CompactionReason compaction_reason) {
1248
+ return PickCompactionWithSortedRunRange(start_index, sorted_runs_.size() - 1,
1249
+ compaction_reason);
1250
+ }
1251
+
1252
+ Compaction* UniversalCompactionBuilder::PickCompactionWithSortedRunRange(
1253
+ size_t start_index, size_t end_index, CompactionReason compaction_reason) {
1236
1254
  assert(start_index < sorted_runs_.size());
1237
1255
 
1238
1256
  // Estimate total file size
1239
1257
  uint64_t estimated_total_size = 0;
1240
- for (size_t loop = start_index; loop < sorted_runs_.size(); loop++) {
1258
+ for (size_t loop = start_index; loop <= end_index; loop++) {
1241
1259
  estimated_total_size += sorted_runs_[loop].size;
1242
1260
  }
1243
1261
  uint32_t path_id =
@@ -1248,7 +1266,7 @@ Compaction* UniversalCompactionBuilder::PickCompactionToOldest(
1248
1266
  for (size_t i = 0; i < inputs.size(); ++i) {
1249
1267
  inputs[i].level = start_level + static_cast<int>(i);
1250
1268
  }
1251
- for (size_t loop = start_index; loop < sorted_runs_.size(); loop++) {
1269
+ for (size_t loop = start_index; loop <= end_index; loop++) {
1252
1270
  auto& picking_sr = sorted_runs_[loop];
1253
1271
  if (picking_sr.level == 0) {
1254
1272
  FileMetaData* f = picking_sr.file;
@@ -1279,12 +1297,19 @@ Compaction* UniversalCompactionBuilder::PickCompactionToOldest(
1279
1297
  file_num_buf);
1280
1298
  }
1281
1299
 
1282
- // output files at the bottom most level, unless it's reserved
1283
- int output_level = vstorage_->num_levels() - 1;
1284
- // last level is reserved for the files ingested behind
1285
- if (ioptions_.allow_ingest_behind) {
1286
- assert(output_level > 1);
1287
- output_level--;
1300
+ int output_level;
1301
+ if (end_index == sorted_runs_.size() - 1) {
1302
+ // output files at the last level, unless it's reserved
1303
+ output_level = vstorage_->num_levels() - 1;
1304
+ // last level is reserved for the files ingested behind
1305
+ if (ioptions_.allow_ingest_behind) {
1306
+ assert(output_level > 1);
1307
+ output_level--;
1308
+ }
1309
+ } else {
1310
+ // if it's not including all sorted_runs, it can only output to the level
1311
+ // above the `end_index + 1` sorted_run.
1312
+ output_level = sorted_runs_[end_index + 1].level - 1;
1288
1313
  }
1289
1314
 
1290
1315
  // We never check size for
@@ -16,7 +16,8 @@ namespace ROCKSDB_NAMESPACE {
16
16
 
17
17
  #if !defined(ROCKSDB_LITE)
18
18
 
19
- class TieredCompactionTest : public DBTestBase {
19
+ class TieredCompactionTest : public DBTestBase,
20
+ public testing::WithParamInterface<bool> {
20
21
  public:
21
22
  TieredCompactionTest()
22
23
  : DBTestBase("tiered_compaction_test", /*env_do_fsync=*/true),
@@ -120,6 +121,16 @@ class TieredCompactionTest : public DBTestBase {
120
121
  pl_stats.Clear();
121
122
  }
122
123
 
124
+ // bottommost_temperature is renaming to last_level_temperature, set either
125
+ // of them should have the same effect.
126
+ void SetColdTemperature(Options& options) {
127
+ if (GetParam()) {
128
+ options.bottommost_temperature = Temperature::kCold;
129
+ } else {
130
+ options.last_level_temperature = Temperature::kCold;
131
+ }
132
+ }
133
+
123
134
  private:
124
135
  void CompareStats(uint64_t val, uint64_t expect) {
125
136
  if (expect > 0) {
@@ -159,7 +170,7 @@ class TieredCompactionTest : public DBTestBase {
159
170
  }
160
171
  };
161
172
 
162
- TEST_F(TieredCompactionTest, SequenceBasedTieredStorageUniversal) {
173
+ TEST_P(TieredCompactionTest, SequenceBasedTieredStorageUniversal) {
163
174
  const int kNumTrigger = 4;
164
175
  const int kNumLevels = 7;
165
176
  const int kNumKeys = 100;
@@ -167,7 +178,7 @@ TEST_F(TieredCompactionTest, SequenceBasedTieredStorageUniversal) {
167
178
 
168
179
  auto options = CurrentOptions();
169
180
  options.compaction_style = kCompactionStyleUniversal;
170
- options.bottommost_temperature = Temperature::kCold;
181
+ SetColdTemperature(options);
171
182
  options.level0_file_num_compaction_trigger = kNumTrigger;
172
183
  options.statistics = CreateDBStatistics();
173
184
  options.max_subcompactions = 10;
@@ -321,7 +332,7 @@ TEST_F(TieredCompactionTest, SequenceBasedTieredStorageUniversal) {
321
332
  ASSERT_GT(GetSstSizeHelper(Temperature::kCold), 0);
322
333
  }
323
334
 
324
- TEST_F(TieredCompactionTest, RangeBasedTieredStorageUniversal) {
335
+ TEST_P(TieredCompactionTest, RangeBasedTieredStorageUniversal) {
325
336
  const int kNumTrigger = 4;
326
337
  const int kNumLevels = 7;
327
338
  const int kNumKeys = 100;
@@ -329,7 +340,7 @@ TEST_F(TieredCompactionTest, RangeBasedTieredStorageUniversal) {
329
340
 
330
341
  auto options = CurrentOptions();
331
342
  options.compaction_style = kCompactionStyleUniversal;
332
- options.bottommost_temperature = Temperature::kCold;
343
+ SetColdTemperature(options);
333
344
  options.level0_file_num_compaction_trigger = kNumTrigger;
334
345
  options.statistics = CreateDBStatistics();
335
346
  options.max_subcompactions = 10;
@@ -513,13 +524,14 @@ TEST_F(TieredCompactionTest, RangeBasedTieredStorageUniversal) {
513
524
  1);
514
525
  }
515
526
 
516
- TEST_F(TieredCompactionTest, LevelColdRangeDelete) {
527
+ TEST_P(TieredCompactionTest, LevelColdRangeDelete) {
517
528
  const int kNumTrigger = 4;
518
529
  const int kNumLevels = 7;
519
530
  const int kNumKeys = 100;
531
+ const int kLastLevel = kNumLevels - 1;
520
532
 
521
533
  auto options = CurrentOptions();
522
- options.bottommost_temperature = Temperature::kCold;
534
+ SetColdTemperature(options);
523
535
  options.level0_file_num_compaction_trigger = kNumTrigger;
524
536
  options.num_levels = kNumLevels;
525
537
  options.statistics = CreateDBStatistics();
@@ -544,11 +556,13 @@ TEST_F(TieredCompactionTest, LevelColdRangeDelete) {
544
556
  CompactRangeOptions cro;
545
557
  cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
546
558
  ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
547
- ASSERT_EQ("0,1", FilesPerLevel());
548
- ASSERT_EQ(GetSstSizeHelper(Temperature::kUnknown), 0);
549
- ASSERT_GT(GetSstSizeHelper(Temperature::kCold), 0);
559
+ ASSERT_EQ("0,1",
560
+ FilesPerLevel()); // bottommost but not last level file is hot
561
+ ASSERT_GT(GetSstSizeHelper(Temperature::kUnknown), 0);
562
+ ASSERT_EQ(GetSstSizeHelper(Temperature::kCold), 0);
550
563
 
551
- MoveFilesToLevel(kNumLevels - 1);
564
+ // explicitly move the data to the last level
565
+ MoveFilesToLevel(kLastLevel);
552
566
 
553
567
  ASSERT_EQ("0,0,0,0,0,0,1", FilesPerLevel());
554
568
 
@@ -616,14 +630,14 @@ class SingleKeySstPartitionerFactory : public SstPartitionerFactory {
616
630
  }
617
631
  };
618
632
 
619
- TEST_F(TieredCompactionTest, LevelOutofBoundaryRangeDelete) {
633
+ TEST_P(TieredCompactionTest, LevelOutofBoundaryRangeDelete) {
620
634
  const int kNumTrigger = 4;
621
635
  const int kNumLevels = 3;
622
636
  const int kNumKeys = 10;
623
637
 
624
638
  auto factory = std::make_shared<SingleKeySstPartitionerFactory>();
625
639
  auto options = CurrentOptions();
626
- options.bottommost_temperature = Temperature::kCold;
640
+ SetColdTemperature(options);
627
641
  options.level0_file_num_compaction_trigger = kNumTrigger;
628
642
  options.num_levels = kNumLevels;
629
643
  options.statistics = CreateDBStatistics();
@@ -734,7 +748,7 @@ TEST_F(TieredCompactionTest, LevelOutofBoundaryRangeDelete) {
734
748
  ASSERT_GT(GetSstSizeHelper(Temperature::kCold), 0);
735
749
  }
736
750
 
737
- TEST_F(TieredCompactionTest, UniversalRangeDelete) {
751
+ TEST_P(TieredCompactionTest, UniversalRangeDelete) {
738
752
  const int kNumTrigger = 4;
739
753
  const int kNumLevels = 7;
740
754
  const int kNumKeys = 10;
@@ -743,7 +757,7 @@ TEST_F(TieredCompactionTest, UniversalRangeDelete) {
743
757
 
744
758
  auto options = CurrentOptions();
745
759
  options.compaction_style = kCompactionStyleUniversal;
746
- options.bottommost_temperature = Temperature::kCold;
760
+ SetColdTemperature(options);
747
761
  options.level0_file_num_compaction_trigger = kNumTrigger;
748
762
  options.statistics = CreateDBStatistics();
749
763
  options.sst_partitioner_factory = factory;
@@ -866,14 +880,14 @@ TEST_F(TieredCompactionTest, UniversalRangeDelete) {
866
880
  ASSERT_GT(GetSstSizeHelper(Temperature::kCold), 0);
867
881
  }
868
882
 
869
- TEST_F(TieredCompactionTest, SequenceBasedTieredStorageLevel) {
883
+ TEST_P(TieredCompactionTest, SequenceBasedTieredStorageLevel) {
870
884
  const int kNumTrigger = 4;
871
885
  const int kNumLevels = 7;
872
886
  const int kNumKeys = 100;
873
887
  const int kLastLevel = kNumLevels - 1;
874
888
 
875
889
  auto options = CurrentOptions();
876
- options.bottommost_temperature = Temperature::kCold;
890
+ SetColdTemperature(options);
877
891
  options.level0_file_num_compaction_trigger = kNumTrigger;
878
892
  options.num_levels = kNumLevels;
879
893
  options.statistics = CreateDBStatistics();
@@ -904,23 +918,22 @@ TEST_F(TieredCompactionTest, SequenceBasedTieredStorageLevel) {
904
918
  }
905
919
  ASSERT_OK(dbfull()->WaitForCompact(true));
906
920
 
907
- // non-last-level compaction doesn't support per_key_placement
921
+ // non last level is hot
908
922
  ASSERT_EQ("0,1", FilesPerLevel());
909
- ASSERT_EQ(GetSstSizeHelper(Temperature::kUnknown), 0);
910
- ASSERT_GT(GetSstSizeHelper(Temperature::kCold), 0);
923
+ ASSERT_GT(GetSstSizeHelper(Temperature::kUnknown), 0);
924
+ ASSERT_EQ(GetSstSizeHelper(Temperature::kCold), 0);
911
925
 
912
926
  expect_stats[1].Add(kBasicCompStats);
913
927
  expect_stats[1].Add(kBasicPerLevelStats);
914
928
  expect_stats[1].ResetCompactionReason(CompactionReason::kLevelL0FilesNum);
915
929
  VerifyCompactionStats(expect_stats, expect_pl_stats);
916
930
 
931
+ // move all data to the last level
917
932
  MoveFilesToLevel(kLastLevel);
918
933
 
919
934
  ResetAllStats(expect_stats, expect_pl_stats);
920
935
 
921
- // the data should be all hot, and it's a last level compaction, but all
922
- // sequence numbers have been zeroed out, so they're still treated as old
923
- // data.
936
+ // The compaction won't move the data up
924
937
  CompactRangeOptions cro;
925
938
  cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
926
939
  ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
@@ -973,49 +986,19 @@ TEST_F(TieredCompactionTest, SequenceBasedTieredStorageLevel) {
973
986
 
974
987
  // move forward the cold_seq, try to split the data into cold and hot, but in
975
988
  // this case it's unsafe to split the data
989
+ // because it's non-last-level but bottommost file, the sequence number will
990
+ // be zeroed out and lost the time information (with
991
+ // `level_compaction_dynamic_level_bytes` or Universal Compaction, it should
992
+ // be rare.)
993
+ // TODO(zjay): ideally we should avoid zero out non-last-level bottommost file
976
994
  latest_cold_seq = seq_history[1];
977
995
  ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
978
996
  ASSERT_EQ("0,0,0,0,0,1", FilesPerLevel());
979
- ASSERT_EQ(GetSstSizeHelper(Temperature::kUnknown), 0);
980
- ASSERT_GT(GetSstSizeHelper(Temperature::kCold), 0);
997
+ ASSERT_GT(GetSstSizeHelper(Temperature::kUnknown), 0);
998
+ ASSERT_EQ(GetSstSizeHelper(Temperature::kCold), 0);
981
999
 
982
1000
  seq_history.clear();
983
1001
 
984
- // Add new data again
985
- for (int i = 0; i < kNumTrigger; i++) {
986
- for (int j = 0; j < kNumKeys; j++) {
987
- ASSERT_OK(Put(Key(i * 10 + j), "value" + std::to_string(i)));
988
- }
989
- ASSERT_OK(Flush());
990
- seq_history.emplace_back(dbfull()->GetLatestSequenceNumber());
991
- }
992
- ASSERT_OK(dbfull()->WaitForCompact(true));
993
-
994
- ResetAllStats(expect_stats, expect_pl_stats);
995
-
996
- // Try to split the last level cold data into hot and cold, which
997
- // is not supported
998
- latest_cold_seq = seq_history[0];
999
- ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
1000
- ASSERT_EQ("0,0,0,0,0,1", FilesPerLevel());
1001
- ASSERT_EQ(GetSstSizeHelper(Temperature::kUnknown), 0);
1002
- ASSERT_GT(GetSstSizeHelper(Temperature::kCold), 0);
1003
-
1004
- auto comp_stats = kBasicCompStats;
1005
- comp_stats.ResetCompactionReason(CompactionReason::kManualCompaction);
1006
- const int bottommost_level = 5;
1007
- expect_stats[bottommost_level].Add(comp_stats);
1008
- expect_stats[bottommost_level].Add(
1009
- comp_stats); // bottommost level has 2 compactions
1010
- expect_stats[bottommost_level].Add(kBasicPerLevelStats);
1011
- expect_stats[bottommost_level].bytes_read_output_level = kHasValue;
1012
- expect_stats[bottommost_level].num_input_files_in_output_level = kHasValue;
1013
-
1014
- for (int level = 2; level < bottommost_level; level++) {
1015
- expect_stats[level].bytes_moved = kHasValue;
1016
- }
1017
- VerifyCompactionStats(expect_stats, expect_pl_stats);
1018
-
1019
1002
  // manually move all data (cold) to last level
1020
1003
  MoveFilesToLevel(kLastLevel);
1021
1004
  seq_history.clear();
@@ -1097,9 +1080,6 @@ TEST_F(TieredCompactionTest, SequenceBasedTieredStorageLevel) {
1097
1080
 
1098
1081
  db_->ReleaseSnapshot(snap);
1099
1082
 
1100
- // TODO: it should push the data to last level, but penultimate level file is
1101
- // already bottommost, it's a conflict between bottommost_temperature and
1102
- // tiered compaction which only applies to last level compaction.
1103
1083
  ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
1104
1084
  ASSERT_EQ("0,0,0,0,0,1,1", FilesPerLevel());
1105
1085
  ASSERT_GT(GetSstSizeHelper(Temperature::kUnknown), 0);
@@ -1124,13 +1104,13 @@ TEST_F(TieredCompactionTest, SequenceBasedTieredStorageLevel) {
1124
1104
  ASSERT_GT(GetSstSizeHelper(Temperature::kCold), 0);
1125
1105
  }
1126
1106
 
1127
- TEST_F(TieredCompactionTest, RangeBasedTieredStorageLevel) {
1107
+ TEST_P(TieredCompactionTest, RangeBasedTieredStorageLevel) {
1128
1108
  const int kNumTrigger = 4;
1129
1109
  const int kNumLevels = 7;
1130
1110
  const int kNumKeys = 100;
1131
1111
 
1132
1112
  auto options = CurrentOptions();
1133
- options.bottommost_temperature = Temperature::kCold;
1113
+ SetColdTemperature(options);
1134
1114
  options.level0_file_num_compaction_trigger = kNumTrigger;
1135
1115
  options.level_compaction_dynamic_level_bytes = true;
1136
1116
  options.num_levels = kNumLevels;
@@ -1232,6 +1212,9 @@ TEST_F(TieredCompactionTest, RangeBasedTieredStorageLevel) {
1232
1212
  1);
1233
1213
  }
1234
1214
 
1215
+ INSTANTIATE_TEST_CASE_P(TieredCompactionTest, TieredCompactionTest,
1216
+ testing::Bool());
1217
+
1235
1218
  #endif // !defined(ROCKSDB_LITE)
1236
1219
 
1237
1220
  } // namespace ROCKSDB_NAMESPACE
@@ -764,6 +764,7 @@ TEST_F(CorruptionTest, ParanoidFileChecksOnCompact) {
764
764
  delete db_;
765
765
  db_ = nullptr;
766
766
  s = DestroyDB(dbname_, options);
767
+ ASSERT_OK(s);
767
768
  std::shared_ptr<mock::MockTableFactory> mock =
768
769
  std::make_shared<mock::MockTableFactory>();
769
770
  options.table_factory = mock;
@@ -1209,9 +1209,9 @@ TEST_F(DBBasicTest, DBCloseAllDirectoryFDs) {
1209
1209
  s = db->Close();
1210
1210
  auto* counted_fs =
1211
1211
  options.env->GetFileSystem()->CheckedCast<CountedFileSystem>();
1212
- assert(counted_fs);
1213
- ASSERT_TRUE(counted_fs->counters()->dir_opens ==
1214
- counted_fs->counters()->dir_closes);
1212
+ ASSERT_TRUE(counted_fs != nullptr);
1213
+ ASSERT_EQ(counted_fs->counters()->dir_opens,
1214
+ counted_fs->counters()->dir_closes);
1215
1215
  ASSERT_OK(s);
1216
1216
  delete db;
1217
1217
  }
@@ -2146,7 +2146,7 @@ class DBMultiGetAsyncIOTest : public DBBasicTest {
2146
2146
 
2147
2147
  // Put all keys in the bottommost level, and overwrite some keys
2148
2148
  // in L0 and L1
2149
- for (int i = 0; i < 128; ++i) {
2149
+ for (int i = 0; i < 256; ++i) {
2150
2150
  EXPECT_OK(Put(Key(i), "val_l2_" + std::to_string(i)));
2151
2151
  num_keys++;
2152
2152
  if (num_keys == 8) {
@@ -2172,6 +2172,21 @@ class DBMultiGetAsyncIOTest : public DBBasicTest {
2172
2172
  EXPECT_OK(Flush());
2173
2173
  num_keys = 0;
2174
2174
  }
2175
+ // Put some range deletes in L1
2176
+ for (int i = 128; i < 256; i += 32) {
2177
+ std::string range_begin = Key(i);
2178
+ std::string range_end = Key(i + 16);
2179
+ EXPECT_OK(dbfull()->DeleteRange(WriteOptions(),
2180
+ dbfull()->DefaultColumnFamily(),
2181
+ range_begin, range_end));
2182
+ // Also do some Puts to force creation of bloom filter
2183
+ for (int j = i + 16; j < i + 32; ++j) {
2184
+ if (j % 3 == 0) {
2185
+ EXPECT_OK(Put(Key(j), "val_l1_" + std::to_string(j)));
2186
+ }
2187
+ }
2188
+ EXPECT_OK(Flush());
2189
+ }
2175
2190
  MoveFilesToLevel(1);
2176
2191
 
2177
2192
  for (int i = 0; i < 128; i += 5) {
@@ -2338,6 +2353,60 @@ TEST_F(DBMultiGetAsyncIOTest, GetFromL1AndL2) {
2338
2353
  ASSERT_EQ(multiget_io_batch_size.count, 1);
2339
2354
  ASSERT_EQ(multiget_io_batch_size.max, 2);
2340
2355
  }
2356
+
2357
+ TEST_F(DBMultiGetAsyncIOTest, GetFromL2WithRangeOverlapL0L1) {
2358
+ std::vector<std::string> key_strs;
2359
+ std::vector<Slice> keys;
2360
+ std::vector<PinnableSlice> values;
2361
+ std::vector<Status> statuses;
2362
+
2363
+ // 19 and 26 are in L2, but overlap with L0 and L1 file ranges
2364
+ key_strs.push_back(Key(19));
2365
+ key_strs.push_back(Key(26));
2366
+ keys.push_back(key_strs[0]);
2367
+ keys.push_back(key_strs[1]);
2368
+ values.resize(keys.size());
2369
+ statuses.resize(keys.size());
2370
+
2371
+ ReadOptions ro;
2372
+ ro.async_io = true;
2373
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
2374
+ keys.data(), values.data(), statuses.data());
2375
+ ASSERT_EQ(values.size(), 2);
2376
+ ASSERT_EQ(statuses[0], Status::OK());
2377
+ ASSERT_EQ(statuses[1], Status::OK());
2378
+ ASSERT_EQ(values[0], "val_l2_" + std::to_string(19));
2379
+ ASSERT_EQ(values[1], "val_l2_" + std::to_string(26));
2380
+
2381
+ // Bloom filters in L0/L1 will avoid the coroutine calls in those levels
2382
+ ASSERT_EQ(statistics()->getTickerCount(MULTIGET_COROUTINE_COUNT), 2);
2383
+ }
2384
+
2385
+ TEST_F(DBMultiGetAsyncIOTest, GetFromL2WithRangeDelInL1) {
2386
+ std::vector<std::string> key_strs;
2387
+ std::vector<Slice> keys;
2388
+ std::vector<PinnableSlice> values;
2389
+ std::vector<Status> statuses;
2390
+
2391
+ // 139 and 163 are in L2, but overlap with a range deletes in L1
2392
+ key_strs.push_back(Key(139));
2393
+ key_strs.push_back(Key(163));
2394
+ keys.push_back(key_strs[0]);
2395
+ keys.push_back(key_strs[1]);
2396
+ values.resize(keys.size());
2397
+ statuses.resize(keys.size());
2398
+
2399
+ ReadOptions ro;
2400
+ ro.async_io = true;
2401
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
2402
+ keys.data(), values.data(), statuses.data());
2403
+ ASSERT_EQ(values.size(), 2);
2404
+ ASSERT_EQ(statuses[0], Status::NotFound());
2405
+ ASSERT_EQ(statuses[1], Status::NotFound());
2406
+
2407
+ // Bloom filters in L0/L1 will avoid the coroutine calls in those levels
2408
+ ASSERT_EQ(statistics()->getTickerCount(MULTIGET_COROUTINE_COUNT), 2);
2409
+ }
2341
2410
  #endif // USE_COROUTINES
2342
2411
 
2343
2412
  TEST_F(DBBasicTest, MultiGetStats) {