@nxtedition/rocksdb 8.0.4 → 8.1.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 (52) hide show
  1. package/BUILDING.md +2 -2
  2. package/binding.cc +72 -2
  3. package/deps/rocksdb/rocksdb/CMakeLists.txt +7 -0
  4. package/deps/rocksdb/rocksdb/Makefile +13 -1
  5. package/deps/rocksdb/rocksdb/db/builder.cc +13 -4
  6. package/deps/rocksdb/rocksdb/db/builder.h +2 -1
  7. package/deps/rocksdb/rocksdb/db/c.cc +6 -0
  8. package/deps/rocksdb/rocksdb/db/column_family.cc +1 -0
  9. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +18 -4
  10. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +2 -0
  11. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +2 -1
  12. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +22 -2
  13. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +5 -1
  14. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +14 -14
  15. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +1 -2
  16. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +2 -3
  17. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +225 -0
  18. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +8 -9
  19. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +0 -8
  20. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +63 -23
  21. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +2 -1
  22. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +12 -8
  23. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +115 -2
  24. package/deps/rocksdb/rocksdb/db/experimental.cc +2 -1
  25. package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +1 -0
  26. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +88 -12
  27. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +38 -1
  28. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +14 -110
  29. package/deps/rocksdb/rocksdb/db/flush_job.cc +2 -3
  30. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +1 -1
  31. package/deps/rocksdb/rocksdb/db/repair.cc +2 -1
  32. package/deps/rocksdb/rocksdb/db/version_builder_test.cc +41 -39
  33. package/deps/rocksdb/rocksdb/db/version_edit.cc +12 -0
  34. package/deps/rocksdb/rocksdb/db/version_edit.h +18 -6
  35. package/deps/rocksdb/rocksdb/db/version_edit_test.cc +9 -9
  36. package/deps/rocksdb/rocksdb/db/version_set.cc +12 -6
  37. package/deps/rocksdb/rocksdb/db/version_set_test.cc +23 -9
  38. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -0
  39. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +4 -0
  40. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +5 -0
  41. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +4 -0
  42. package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +7 -1
  43. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +2 -1
  44. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/backup_engine.h +69 -9
  45. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +245 -74
  46. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +195 -4
  47. package/index.js +17 -0
  48. package/max_rev_operator.h +100 -0
  49. package/package.json +1 -1
  50. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  51. package/prebuilds/darwin-x64/node.napi.node +0 -0
  52. package/prebuilds/linux-x64/node.napi.node +0 -0
package/BUILDING.md CHANGED
@@ -10,9 +10,9 @@
10
10
  - Copy `libfolly.a` to `/usr/lib/x86_64-linux-gnu`.
11
11
  - Copy headers to `/usr/lib/x86_64-linux-gnu/include`.
12
12
  - Copy boost headers from folly scratchpad to `/usr/lib/x86_64-linux-gnu/include`.
13
- - `JOBS=8 npx prebuildify -t 18.11.0 --napi --strip --arch x64`
13
+ - `JONS=16 npx prebuildify -t 18.11.0 --napi --strip --arch x64`
14
14
 
15
15
  # OSX
16
16
 
17
17
  - `brew install zstd`
18
- - `JOBS=8 npx prebuildify -t 18.11.0 --napi --strip --arch arm64`
18
+ - `JONS=16 npx prebuildify -t 18.11.0 --napi --strip --arch arm64`
package/binding.cc CHANGED
@@ -26,6 +26,7 @@
26
26
  #include <thread>
27
27
  #include <vector>
28
28
 
29
+ #include "max_rev_operator.h"
29
30
  #include "util.h"
30
31
 
31
32
  class NullLogger : public rocksdb::Logger {
@@ -556,8 +557,12 @@ napi_status InitOptions(napi_env env, T& columnOptions, const U& options) {
556
557
  std::optional<std::string> mergeOperatorOpt;
557
558
  NAPI_STATUS_RETURN(GetProperty(env, options, "mergeOperator", mergeOperatorOpt));
558
559
  if (mergeOperatorOpt) {
559
- ROCKS_STATUS_RETURN_NAPI(
560
- rocksdb::MergeOperator::CreateFromString(configOptions, *mergeOperatorOpt, &columnOptions.merge_operator));
560
+ if (*mergeOperatorOpt == "maxRev") {
561
+ columnOptions.merge_operator = std::make_shared<MaxRevOperator>();
562
+ } else {
563
+ ROCKS_STATUS_RETURN_NAPI(
564
+ rocksdb::MergeOperator::CreateFromString(configOptions, *mergeOperatorOpt, &columnOptions.merge_operator));
565
+ }
561
566
  }
562
567
 
563
568
  std::optional<std::string> compactionPriority;
@@ -631,6 +636,70 @@ napi_status InitOptions(napi_env env, T& columnOptions, const U& options) {
631
636
  return napi_ok;
632
637
  }
633
638
 
639
+ NAPI_METHOD(db_get_merge_operands) {
640
+ NAPI_ARGV(4);
641
+
642
+ Database* database;
643
+ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], reinterpret_cast<void**>(&database)));
644
+
645
+ std::string key;
646
+ NAPI_STATUS_THROWS(GetValue(env, argv[1], key));
647
+
648
+ const auto options = argv[2];
649
+
650
+ Encoding valueEncoding = Encoding::String;
651
+ NAPI_STATUS_THROWS(GetProperty(env, options, "valueEncoding", valueEncoding));
652
+
653
+ rocksdb::ColumnFamilyHandle* column = database->db->DefaultColumnFamily();
654
+ NAPI_STATUS_THROWS(GetProperty(env, options, "column", column));
655
+
656
+ auto callback = argv[3];
657
+
658
+ runAsync<std::vector<rocksdb::PinnableSlice>>(
659
+ "leveldown.get.mergeOperands", env, callback,
660
+ [=, key = std::move(key)](auto& values) {
661
+ rocksdb::ReadOptions readOptions;
662
+
663
+ values.resize(16); // TODO (fix): Make option
664
+
665
+ rocksdb::GetMergeOperandsOptions mergeOperandsOptions;
666
+ mergeOperandsOptions.expected_max_number_of_operands = values.size();
667
+
668
+ int size = 0;
669
+ const auto status = database->db->GetMergeOperands(
670
+ readOptions,
671
+ column,
672
+ key,
673
+ values.data(),
674
+ &mergeOperandsOptions,
675
+ &size
676
+ );
677
+
678
+ values.resize(size);
679
+
680
+ return status;
681
+ },
682
+ [=](auto& values, auto env, auto& argv) {
683
+ argv.resize(2);
684
+
685
+ NAPI_STATUS_RETURN(napi_create_array_with_length(env, values.size(), &argv[1]));
686
+
687
+ for (size_t idx = 0; idx < values.size(); idx++) {
688
+ napi_value element;
689
+ if (values[idx].GetSelf()) {
690
+ NAPI_STATUS_RETURN(Convert(env, &values[idx], valueEncoding, element));
691
+ } else {
692
+ NAPI_STATUS_RETURN(napi_get_undefined(env, &element));
693
+ }
694
+ NAPI_STATUS_RETURN(napi_set_element(env, argv[1], static_cast<uint32_t>(idx), element));
695
+ }
696
+
697
+ return napi_ok;
698
+ });
699
+
700
+ return 0;
701
+ }
702
+
634
703
  NAPI_METHOD(db_get_identity) {
635
704
  NAPI_ARGV(1);
636
705
 
@@ -1576,6 +1645,7 @@ NAPI_INIT() {
1576
1645
  NAPI_EXPORT_FUNCTION(db_get_latest_sequence);
1577
1646
  NAPI_EXPORT_FUNCTION(db_get_sorted_wal_files);
1578
1647
  NAPI_EXPORT_FUNCTION(db_flush_wal);
1648
+ NAPI_EXPORT_FUNCTION(db_get_merge_operands);
1579
1649
 
1580
1650
  NAPI_EXPORT_FUNCTION(iterator_init);
1581
1651
  NAPI_EXPORT_FUNCTION(iterator_seek);
@@ -980,6 +980,12 @@ if ( ROCKSDB_PLUGINS )
980
980
  plugin/${plugin}/${src}
981
981
  PROPERTIES COMPILE_FLAGS "${${plugin}_COMPILE_FLAGS}")
982
982
  endforeach()
983
+ foreach (test ${${plugin}_TESTS})
984
+ list(APPEND PLUGIN_TESTS plugin/${plugin}/${test})
985
+ set_source_files_properties(
986
+ plugin/${plugin}/${test}
987
+ PROPERTIES COMPILE_FLAGS "${${plugin}_COMPILE_FLAGS}")
988
+ endforeach()
983
989
  foreach (path ${${plugin}_INCLUDE_PATHS})
984
990
  include_directories(${path})
985
991
  endforeach()
@@ -1471,6 +1477,7 @@ if(WITH_TESTS)
1471
1477
  utilities/ttl/ttl_test.cc
1472
1478
  utilities/util_merge_operators_test.cc
1473
1479
  utilities/write_batch_with_index/write_batch_with_index_test.cc
1480
+ ${PLUGIN_TESTS}
1474
1481
  )
1475
1482
  endif()
1476
1483
 
@@ -266,6 +266,7 @@ ROCKSDB_PLUGIN_EXTERNS = $(foreach p, $(ROCKSDB_PLUGIN_W_FUNCS), int $($(p)_FUNC
266
266
  ROCKSDB_PLUGIN_BUILTINS = $(foreach p, $(ROCKSDB_PLUGIN_W_FUNCS), {\"$(p)\"\, $($(p)_FUNC)}\,)
267
267
  ROCKSDB_PLUGIN_LDFLAGS = $(foreach plugin, $(ROCKSDB_PLUGINS), $($(plugin)_LDFLAGS))
268
268
  ROCKSDB_PLUGIN_PKGCONFIG_REQUIRES = $(foreach plugin, $(ROCKSDB_PLUGINS), $($(plugin)_PKGCONFIG_REQUIRES))
269
+ ROCKSDB_PLUGIN_TESTS = $(foreach p, $(ROCKSDB_PLUGINS), $(foreach test, $($(p)_TESTS), plugin/$(p)/$(test)))
269
270
 
270
271
  CXXFLAGS += $(foreach plugin, $(ROCKSDB_PLUGINS), $($(plugin)_CXXFLAGS))
271
272
  PLATFORM_LDFLAGS += $(ROCKSDB_PLUGIN_LDFLAGS)
@@ -647,10 +648,12 @@ STRESS_OBJECTS = $(patsubst %.cc, $(OBJ_DIR)/%.o, $(STRESS_LIB_SOURCES))
647
648
  ALL_SOURCES = $(filter-out util/build_version.cc, $(LIB_SOURCES)) $(TEST_LIB_SOURCES) $(MOCK_LIB_SOURCES) $(GTEST_DIR)/gtest/gtest-all.cc
648
649
  ALL_SOURCES += $(TOOL_LIB_SOURCES) $(BENCH_LIB_SOURCES) $(CACHE_BENCH_LIB_SOURCES) $(ANALYZER_LIB_SOURCES) $(STRESS_LIB_SOURCES)
649
650
  ALL_SOURCES += $(TEST_MAIN_SOURCES) $(TOOL_MAIN_SOURCES) $(BENCH_MAIN_SOURCES)
650
- ALL_SOURCES += $(ROCKSDB_PLUGIN_SOURCES)
651
+ ALL_SOURCES += $(ROCKSDB_PLUGIN_SOURCES) $(ROCKSDB_PLUGIN_TESTS)
651
652
 
653
+ PLUGIN_TESTS = $(patsubst %.cc, %, $(notdir $(ROCKSDB_PLUGIN_TESTS)))
652
654
  TESTS = $(patsubst %.cc, %, $(notdir $(TEST_MAIN_SOURCES)))
653
655
  TESTS += $(patsubst %.c, %, $(notdir $(TEST_MAIN_SOURCES_C)))
656
+ TESTS += $(PLUGIN_TESTS)
654
657
 
655
658
  # `make check-headers` to very that each header file includes its own
656
659
  # dependencies
@@ -702,6 +705,7 @@ NON_PARALLEL_TEST = \
702
705
  env_test \
703
706
  deletefile_test \
704
707
  db_bloom_filter_test \
708
+ $(PLUGIN_TESTS) \
705
709
 
706
710
  PARALLEL_TEST = $(filter-out $(NON_PARALLEL_TEST), $(TESTS))
707
711
 
@@ -1355,6 +1359,14 @@ db_sanity_test: $(OBJ_DIR)/tools/db_sanity_test.o $(LIBRARY)
1355
1359
  db_repl_stress: $(OBJ_DIR)/tools/db_repl_stress.o $(LIBRARY)
1356
1360
  $(AM_LINK)
1357
1361
 
1362
+ define MakeTestRule
1363
+ $(notdir $(1:%.cc=%)): $(1:%.cc=$$(OBJ_DIR)/%.o) $$(TEST_LIBRARY) $$(LIBRARY)
1364
+ $$(AM_LINK)
1365
+ endef
1366
+
1367
+ # For each PLUGIN test, create a rule to generate the test executable
1368
+ $(foreach test, $(ROCKSDB_PLUGIN_TESTS), $(eval $(call MakeTestRule, $(test))))
1369
+
1358
1370
  arena_test: $(OBJ_DIR)/memory/arena_test.o $(TEST_LIBRARY) $(LIBRARY)
1359
1371
  $(AM_LINK)
1360
1372
 
@@ -71,8 +71,9 @@ Status BuildTable(
71
71
  int job_id, const Env::IOPriority io_priority,
72
72
  TableProperties* table_properties, Env::WriteLifeTimeHint write_hint,
73
73
  const std::string* full_history_ts_low,
74
- BlobFileCompletionCallback* blob_callback, uint64_t* num_input_entries,
75
- uint64_t* memtable_payload_bytes, uint64_t* memtable_garbage_bytes) {
74
+ BlobFileCompletionCallback* blob_callback, Version* version,
75
+ uint64_t* num_input_entries, uint64_t* memtable_payload_bytes,
76
+ uint64_t* memtable_garbage_bytes) {
76
77
  assert((tboptions.column_family_id ==
77
78
  TablePropertiesCollectorFactory::Context::kUnknownColumnFamily) ==
78
79
  tboptions.column_family_name.empty());
@@ -246,9 +247,17 @@ Status BuildTable(
246
247
  auto tombstone = range_del_it->Tombstone();
247
248
  auto kv = tombstone.Serialize();
248
249
  builder->Add(kv.first.Encode(), kv.second);
249
- meta->UpdateBoundariesForRange(kv.first, tombstone.SerializeEndKey(),
250
- tombstone.seq_,
250
+ InternalKey tombstone_end = tombstone.SerializeEndKey();
251
+ meta->UpdateBoundariesForRange(kv.first, tombstone_end, tombstone.seq_,
251
252
  tboptions.internal_comparator);
253
+ if (version) {
254
+ SizeApproximationOptions approx_opts;
255
+ approx_opts.files_size_error_margin = 0.1;
256
+ meta->compensated_range_deletion_size += versions->ApproximateSize(
257
+ approx_opts, version, kv.first.Encode(), tombstone_end.Encode(),
258
+ 0 /* start_level */, -1 /* end_level */,
259
+ TableReaderCaller::kFlush);
260
+ }
252
261
  }
253
262
  }
254
263
 
@@ -13,6 +13,7 @@
13
13
  #include "db/range_tombstone_fragmenter.h"
14
14
  #include "db/seqno_to_time_mapping.h"
15
15
  #include "db/table_properties_collector.h"
16
+ #include "db/version_set.h"
16
17
  #include "logging/event_logger.h"
17
18
  #include "options/cf_options.h"
18
19
  #include "rocksdb/comparator.h"
@@ -70,7 +71,7 @@ extern Status BuildTable(
70
71
  Env::WriteLifeTimeHint write_hint = Env::WLTH_NOT_SET,
71
72
  const std::string* full_history_ts_low = nullptr,
72
73
  BlobFileCompletionCallback* blob_callback = nullptr,
73
- uint64_t* num_input_entries = nullptr,
74
+ Version* version = nullptr, uint64_t* num_input_entries = nullptr,
74
75
  uint64_t* memtable_payload_bytes = nullptr,
75
76
  uint64_t* memtable_garbage_bytes = nullptr);
76
77
 
@@ -2588,6 +2588,12 @@ void rocksdb_block_based_options_set_partition_filters(
2588
2588
  options->rep.partition_filters = partition_filters;
2589
2589
  }
2590
2590
 
2591
+ void rocksdb_block_based_options_set_optimize_filters_for_memory(
2592
+ rocksdb_block_based_table_options_t* options,
2593
+ unsigned char optimize_filters_for_memory) {
2594
+ options->rep.optimize_filters_for_memory = optimize_filters_for_memory;
2595
+ }
2596
+
2591
2597
  void rocksdb_block_based_options_set_use_delta_encoding(
2592
2598
  rocksdb_block_based_table_options_t* options,
2593
2599
  unsigned char use_delta_encoding) {
@@ -1218,6 +1218,7 @@ Compaction* ColumnFamilyData::CompactRange(
1218
1218
  if (result != nullptr) {
1219
1219
  result->SetInputVersion(current_);
1220
1220
  }
1221
+ TEST_SYNC_POINT("ColumnFamilyData::CompactRange:Return");
1221
1222
  return result;
1222
1223
  }
1223
1224
 
@@ -235,12 +235,19 @@ Compaction::Compaction(
235
235
  inputs_(PopulateWithAtomicBoundaries(vstorage, std::move(_inputs))),
236
236
  grandparents_(std::move(_grandparents)),
237
237
  score_(_score),
238
- bottommost_level_(IsBottommostLevel(output_level_, vstorage, inputs_)),
238
+ bottommost_level_(
239
+ // For simplicity, we don't support the concept of "bottommost level"
240
+ // with
241
+ // `CompactionReason::kExternalSstIngestion` and
242
+ // `CompactionReason::kRefitLevel`
243
+ (_compaction_reason == CompactionReason::kExternalSstIngestion ||
244
+ _compaction_reason == CompactionReason::kRefitLevel)
245
+ ? false
246
+ : IsBottommostLevel(output_level_, vstorage, inputs_)),
239
247
  is_full_compaction_(IsFullCompaction(vstorage, inputs_)),
240
248
  is_manual_compaction_(_manual_compaction),
241
249
  trim_ts_(_trim_ts),
242
250
  is_trivial_move_(false),
243
-
244
251
  compaction_reason_(_compaction_reason),
245
252
  notify_on_compaction_completion_(false),
246
253
  enable_blob_garbage_collection_(
@@ -255,8 +262,15 @@ Compaction::Compaction(
255
262
  _blob_garbage_collection_age_cutoff > 1
256
263
  ? mutable_cf_options()->blob_garbage_collection_age_cutoff
257
264
  : _blob_garbage_collection_age_cutoff),
258
- penultimate_level_(EvaluatePenultimateLevel(
259
- vstorage, immutable_options_, start_level_, output_level_)) {
265
+ penultimate_level_(
266
+ // For simplicity, we don't support the concept of "penultimate level"
267
+ // with `CompactionReason::kExternalSstIngestion` and
268
+ // `CompactionReason::kRefitLevel`
269
+ _compaction_reason == CompactionReason::kExternalSstIngestion ||
270
+ _compaction_reason == CompactionReason::kRefitLevel
271
+ ? Compaction::kInvalidLevel
272
+ : EvaluatePenultimateLevel(vstorage, immutable_options_,
273
+ start_level_, output_level_)) {
260
274
  MarkFilesBeingCompacted(true);
261
275
  if (is_manual_compaction_) {
262
276
  compaction_reason_ = CompactionReason::kManualCompaction;
@@ -99,6 +99,8 @@ const char* GetCompactionReasonString(CompactionReason compaction_reason) {
99
99
  return "ForcedBlobGC";
100
100
  case CompactionReason::kRoundRobinTtl:
101
101
  return "RoundRobinTtl";
102
+ case CompactionReason::kRefitLevel:
103
+ return "RefitLevel";
102
104
  case CompactionReason::kNumOfReasons:
103
105
  // fall through
104
106
  default:
@@ -386,7 +386,8 @@ class CompactionJobTestBase : public testing::Test {
386
386
  oldest_blob_file_number, kUnknownOldestAncesterTime,
387
387
  kUnknownFileCreationTime,
388
388
  versions_->GetColumnFamilySet()->GetDefault()->NewEpochNumber(),
389
- kUnknownFileChecksum, kUnknownFileChecksumFuncName, kNullUniqueId64x2);
389
+ kUnknownFileChecksum, kUnknownFileChecksumFuncName, kNullUniqueId64x2,
390
+ 0);
390
391
 
391
392
  mutex_.Lock();
392
393
  EXPECT_OK(
@@ -525,7 +525,8 @@ Status CompactionOutputs::AddRangeDels(
525
525
  ucmp->CompareWithoutTimestamp(*lower_bound, kv.second) < 0);
526
526
  // Range tombstone is not supported by output validator yet.
527
527
  builder_->Add(kv.first.Encode(), kv.second);
528
- InternalKey smallest_candidate = std::move(kv.first);
528
+ InternalKey tombstone_start = std::move(kv.first);
529
+ InternalKey smallest_candidate{tombstone_start};
529
530
  if (lower_bound != nullptr &&
530
531
  ucmp->CompareWithoutTimestamp(smallest_candidate.user_key(),
531
532
  *lower_bound) <= 0) {
@@ -594,7 +595,8 @@ Status CompactionOutputs::AddRangeDels(
594
595
  smallest_candidate = InternalKey(*lower_bound, 0, kTypeRangeDeletion);
595
596
  }
596
597
  }
597
- InternalKey largest_candidate = tombstone.SerializeEndKey();
598
+ InternalKey tombstone_end = tombstone.SerializeEndKey();
599
+ InternalKey largest_candidate{tombstone_end};
598
600
  if (upper_bound != nullptr &&
599
601
  ucmp->CompareWithoutTimestamp(*upper_bound,
600
602
  largest_candidate.user_key()) <= 0) {
@@ -636,6 +638,24 @@ Status CompactionOutputs::AddRangeDels(
636
638
  #endif
637
639
  meta.UpdateBoundariesForRange(smallest_candidate, largest_candidate,
638
640
  tombstone.seq_, icmp);
641
+ if (!bottommost_level) {
642
+ // Range tombstones are truncated at file boundaries
643
+ if (icmp.Compare(tombstone_start, meta.smallest) < 0) {
644
+ tombstone_start = meta.smallest;
645
+ }
646
+ if (icmp.Compare(tombstone_end, meta.largest) > 0) {
647
+ tombstone_end = meta.largest;
648
+ }
649
+ SizeApproximationOptions approx_opts;
650
+ approx_opts.files_size_error_margin = 0.1;
651
+ auto approximate_covered_size =
652
+ compaction_->input_version()->version_set()->ApproximateSize(
653
+ approx_opts, compaction_->input_version(),
654
+ tombstone_start.Encode(), tombstone_end.Encode(),
655
+ compaction_->output_level() + 1 /* start_level */,
656
+ -1 /* end_level */, kCompaction);
657
+ meta.compensated_range_deletion_size += approximate_covered_size;
658
+ }
639
659
  // The smallest key in a file is used for range tombstone truncation, so
640
660
  // it cannot have a seqnum of 0 (unless the smallest data key in a file
641
661
  // has a seqnum of 0). Otherwise, the truncated tombstone may expose
@@ -1126,7 +1126,11 @@ void CompactionPicker::RegisterCompaction(Compaction* c) {
1126
1126
  c->output_level() == 0 ||
1127
1127
  !FilesRangeOverlapWithCompaction(*c->inputs(), c->output_level(),
1128
1128
  c->GetPenultimateLevel()));
1129
- if (c->start_level() == 0 ||
1129
+ // CompactionReason::kExternalSstIngestion's start level is just a placeholder
1130
+ // number without actual meaning as file ingestion technically does not have
1131
+ // an input level like other compactions
1132
+ if ((c->start_level() == 0 &&
1133
+ c->compaction_reason() != CompactionReason::kExternalSstIngestion) ||
1130
1134
  ioptions_.compaction_style == kCompactionStyleUniversal) {
1131
1135
  level0_compactions_in_progress_.insert(c);
1132
1136
  }
@@ -447,21 +447,21 @@ bool LevelCompactionBuilder::SetupOtherInputsIfNeeded() {
447
447
  compaction_inputs_.push_back(output_level_inputs_);
448
448
  }
449
449
 
450
+ // In some edge cases we could pick a compaction that will be compacting
451
+ // a key range that overlap with another running compaction, and both
452
+ // of them have the same output level. This could happen if
453
+ // (1) we are running a non-exclusive manual compaction
454
+ // (2) AddFile ingest a new file into the LSM tree
455
+ // We need to disallow this from happening.
456
+ if (compaction_picker_->FilesRangeOverlapWithCompaction(
457
+ compaction_inputs_, output_level_,
458
+ Compaction::EvaluatePenultimateLevel(
459
+ vstorage_, ioptions_, start_level_, output_level_))) {
460
+ // This compaction output could potentially conflict with the output
461
+ // of a currently running compaction, we cannot run it.
462
+ return false;
463
+ }
450
464
  if (!is_l0_trivial_move_) {
451
- // In some edge cases we could pick a compaction that will be compacting
452
- // a key range that overlap with another running compaction, and both
453
- // of them have the same output level. This could happen if
454
- // (1) we are running a non-exclusive manual compaction
455
- // (2) AddFile ingest a new file into the LSM tree
456
- // We need to disallow this from happening.
457
- if (compaction_picker_->FilesRangeOverlapWithCompaction(
458
- compaction_inputs_, output_level_,
459
- Compaction::EvaluatePenultimateLevel(
460
- vstorage_, ioptions_, start_level_, output_level_))) {
461
- // This compaction output could potentially conflict with the output
462
- // of a currently running compaction, we cannot run it.
463
- return false;
464
- }
465
465
  compaction_picker_->GetGrandparents(vstorage_, start_level_inputs_,
466
466
  output_level_inputs_, &grandparents_);
467
467
  }
@@ -148,7 +148,7 @@ class CompactionPickerTestBase : public testing::Test {
148
148
  smallest_seq, largest_seq, marked_for_compact, temperature,
149
149
  kInvalidBlobFileNumber, kUnknownOldestAncesterTime,
150
150
  kUnknownFileCreationTime, epoch_number, kUnknownFileChecksum,
151
- kUnknownFileChecksumFuncName, kNullUniqueId64x2);
151
+ kUnknownFileChecksumFuncName, kNullUniqueId64x2, 0);
152
152
  f->compensated_file_size =
153
153
  (compensated_file_size != 0) ? compensated_file_size : file_size;
154
154
  f->oldest_ancester_time = oldest_ancestor_time;
@@ -2873,7 +2873,6 @@ TEST_F(CompactionPickerTest, IntraL0MaxCompactionBytesHit) {
2873
2873
  ASSERT_EQ(0, compaction->output_level());
2874
2874
  }
2875
2875
 
2876
-
2877
2876
  #ifndef ROCKSDB_LITE
2878
2877
  TEST_F(CompactionPickerTest, UniversalMarkedCompactionFullOverlap) {
2879
2878
  const uint64_t kFileSize = 100000;
@@ -1229,7 +1229,7 @@ TEST_P(ChargeFilterConstructionTestWithParam, Basic) {
1229
1229
  *
1230
1230
  * The test is designed in a way such that the reservation for (p1 - b')
1231
1231
  * will trigger at least another dummy entry insertion
1232
- * (or equivelantly to saying, creating another peak).
1232
+ * (or equivalently to saying, creating another peak).
1233
1233
  *
1234
1234
  * kStandard128Ribbon + FullFilter +
1235
1235
  * detect_filter_construct_corruption
@@ -2618,8 +2618,7 @@ TEST_F(DBBloomFilterTest, OptimizeFiltersForHits) {
2618
2618
  BottommostLevelCompaction::kSkip;
2619
2619
  compact_options.change_level = true;
2620
2620
  compact_options.target_level = 7;
2621
- ASSERT_TRUE(db_->CompactRange(compact_options, handles_[1], nullptr, nullptr)
2622
- .IsNotSupported());
2621
+ ASSERT_OK(db_->CompactRange(compact_options, handles_[1], nullptr, nullptr));
2623
2622
 
2624
2623
  ASSERT_EQ(trivial_move, 1);
2625
2624
  ASSERT_EQ(non_trivial_move, 0);