@nxtedition/rocksdb 7.0.24 → 7.0.25

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 (146) hide show
  1. package/binding.cc +3 -1
  2. package/deps/rocksdb/rocksdb/CMakeLists.txt +5 -0
  3. package/deps/rocksdb/rocksdb/Makefile +6 -2
  4. package/deps/rocksdb/rocksdb/TARGETS +14 -0
  5. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +4 -1
  6. package/deps/rocksdb/rocksdb/cache/cache_helpers.h +20 -0
  7. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager_test.cc +2 -2
  8. package/deps/rocksdb/rocksdb/cache/cache_test.cc +44 -31
  9. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +491 -722
  10. package/deps/rocksdb/rocksdb/cache/clock_cache.h +468 -2
  11. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +1 -1
  12. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +51 -52
  13. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.h +28 -16
  14. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +12 -1
  15. package/deps/rocksdb/rocksdb/cache/lru_cache.h +1 -0
  16. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +170 -36
  17. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache_test.cc +1 -1
  18. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +63 -36
  19. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.h +4 -6
  20. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader_test.cc +57 -38
  21. package/deps/rocksdb/rocksdb/db/blob/blob_read_request.h +58 -0
  22. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +164 -74
  23. package/deps/rocksdb/rocksdb/db/blob/blob_source.h +42 -29
  24. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +419 -62
  25. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +208 -8
  26. package/deps/rocksdb/rocksdb/db/c.cc +68 -0
  27. package/deps/rocksdb/rocksdb/db/c_test.c +95 -2
  28. package/deps/rocksdb/rocksdb/db/column_family.cc +12 -3
  29. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +92 -15
  30. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +76 -4
  31. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +52 -1
  32. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +30 -1
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +126 -0
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +203 -1584
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +93 -26
  36. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +87 -1
  37. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +314 -0
  38. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +328 -0
  39. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +32 -6
  40. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +4 -1
  41. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +7 -3
  42. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +174 -33
  43. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +474 -7
  44. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +5 -2
  45. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +825 -0
  46. package/deps/rocksdb/rocksdb/db/compaction/compaction_state.cc +46 -0
  47. package/deps/rocksdb/rocksdb/db/compaction/compaction_state.h +42 -0
  48. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +223 -0
  49. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +255 -0
  50. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +1253 -0
  51. package/deps/rocksdb/rocksdb/db/corruption_test.cc +32 -8
  52. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +3 -1
  53. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +13 -8
  54. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +376 -0
  55. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +103 -78
  56. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +4 -6
  57. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +0 -8
  58. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +10 -3
  59. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +21 -6
  60. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.h +19 -1
  61. package/deps/rocksdb/rocksdb/db/db_iter.cc +91 -14
  62. package/deps/rocksdb/rocksdb/db/db_iter.h +5 -0
  63. package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +33 -0
  64. package/deps/rocksdb/rocksdb/db/db_properties_test.cc +79 -0
  65. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +2 -0
  66. package/deps/rocksdb/rocksdb/db/db_test2.cc +1 -1
  67. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +5 -2
  68. package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +185 -0
  69. package/deps/rocksdb/rocksdb/db/dbformat.cc +1 -4
  70. package/deps/rocksdb/rocksdb/db/dbformat.h +2 -8
  71. package/deps/rocksdb/rocksdb/db/internal_stats.cc +71 -29
  72. package/deps/rocksdb/rocksdb/db/internal_stats.h +160 -5
  73. package/deps/rocksdb/rocksdb/db/log_reader.cc +29 -3
  74. package/deps/rocksdb/rocksdb/db/log_reader.h +12 -3
  75. package/deps/rocksdb/rocksdb/db/repair_test.cc +1 -3
  76. package/deps/rocksdb/rocksdb/db/version_edit.cc +6 -0
  77. package/deps/rocksdb/rocksdb/db/version_set.cc +93 -129
  78. package/deps/rocksdb/rocksdb/db/version_set.h +4 -4
  79. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +2 -2
  80. package/deps/rocksdb/rocksdb/db/version_set_test.cc +42 -35
  81. package/deps/rocksdb/rocksdb/db/write_batch.cc +10 -2
  82. package/deps/rocksdb/rocksdb/db/write_batch_internal.h +4 -1
  83. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +10 -4
  84. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +3 -3
  85. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +3 -2
  86. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +4 -0
  87. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.h +5 -1
  88. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +140 -8
  89. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +12 -0
  90. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +46 -7
  91. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.h +7 -0
  92. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +27 -7
  93. package/deps/rocksdb/rocksdb/env/composite_env_wrapper.h +8 -0
  94. package/deps/rocksdb/rocksdb/env/env_posix.cc +14 -0
  95. package/deps/rocksdb/rocksdb/env/env_test.cc +130 -1
  96. package/deps/rocksdb/rocksdb/env/fs_posix.cc +7 -1
  97. package/deps/rocksdb/rocksdb/env/io_posix.cc +18 -50
  98. package/deps/rocksdb/rocksdb/env/io_posix.h +53 -6
  99. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +8 -10
  100. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +3 -7
  101. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +239 -259
  102. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +84 -19
  103. package/deps/rocksdb/rocksdb/file/random_access_file_reader.h +24 -4
  104. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +1 -1
  105. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +31 -1
  106. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +11 -7
  107. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_job_stats.h +2 -0
  108. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +14 -0
  109. package/deps/rocksdb/rocksdb/include/rocksdb/env.h +20 -0
  110. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +37 -13
  111. package/deps/rocksdb/rocksdb/include/rocksdb/perf_context.h +7 -0
  112. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +14 -0
  113. package/deps/rocksdb/rocksdb/include/rocksdb/threadpool.h +9 -0
  114. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +13 -13
  115. package/deps/rocksdb/rocksdb/logging/auto_roll_logger.cc +12 -2
  116. package/deps/rocksdb/rocksdb/monitoring/perf_context.cc +38 -0
  117. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +7 -1
  118. package/deps/rocksdb/rocksdb/port/win/env_win.cc +17 -0
  119. package/deps/rocksdb/rocksdb/port/win/env_win.h +8 -0
  120. package/deps/rocksdb/rocksdb/port/win/io_win.cc +6 -3
  121. package/{prebuilds → deps/rocksdb/rocksdb/prebuilds}/linux-x64/node.napi.node +0 -0
  122. package/deps/rocksdb/rocksdb/src.mk +5 -0
  123. package/deps/rocksdb/rocksdb/table/block_based/block.h +1 -2
  124. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +1 -1
  125. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +5 -2
  126. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +1 -1
  127. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +15 -12
  128. package/deps/rocksdb/rocksdb/table/block_based/block_prefetcher.cc +5 -4
  129. package/deps/rocksdb/rocksdb/table/block_based/block_prefetcher.h +2 -1
  130. package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +1 -1
  131. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_iterator.cc +4 -4
  132. package/deps/rocksdb/rocksdb/table/block_fetcher.cc +1 -2
  133. package/deps/rocksdb/rocksdb/table/get_context.cc +1 -0
  134. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +1 -2
  135. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +24 -4
  136. package/deps/rocksdb/rocksdb/util/async_file_reader.cc +1 -1
  137. package/deps/rocksdb/rocksdb/util/compression.h +2 -0
  138. package/deps/rocksdb/rocksdb/util/thread_list_test.cc +18 -1
  139. package/deps/rocksdb/rocksdb/util/threadpool_imp.cc +67 -4
  140. package/deps/rocksdb/rocksdb/util/threadpool_imp.h +8 -0
  141. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +15 -12
  142. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +4 -2
  143. package/deps/rocksdb/rocksdb/utilities/simulator_cache/sim_cache_test.cc +1 -1
  144. package/deps/rocksdb/rocksdb.gyp +5 -1
  145. package/package.json +1 -1
  146. package/prebuilds/darwin-arm64/node.napi.node +0 -0
@@ -7,11 +7,13 @@
7
7
  // Use of this source code is governed by a BSD-style license that can be
8
8
  // found in the LICENSE file. See the AUTHORS file for names of contributors.
9
9
 
10
+ #include "db/compaction/compaction_picker_level.h"
11
+
10
12
  #include <string>
11
13
  #include <utility>
12
14
  #include <vector>
13
15
 
14
- #include "db/compaction/compaction_picker_level.h"
16
+ #include "db/version_edit.h"
15
17
  #include "logging/log_buffer.h"
16
18
  #include "test_util/sync_point.h"
17
19
 
@@ -87,6 +89,9 @@ class LevelCompactionBuilder {
87
89
  // function will return false.
88
90
  bool PickFileToCompact();
89
91
 
92
+ // Return true if a L0 trivial move is picked up.
93
+ bool TryPickL0TrivialMove();
94
+
90
95
  // For L0->L0, picks the longest span of files that aren't currently
91
96
  // undergoing compaction for which work-per-deleted-file decreases. The span
92
97
  // always starts from the newest L0 file.
@@ -98,6 +103,10 @@ class LevelCompactionBuilder {
98
103
  // otherwise, returns false.
99
104
  bool PickIntraL0Compaction();
100
105
 
106
+ // Return true if TrivialMove is extended. `start_index` is the index of
107
+ // the intiial file picked, which should already be in `start_level_inputs_`.
108
+ bool TryExtendNonL0TrivialMove(int start_index);
109
+
101
110
  // Picks a file from level_files to compact.
102
111
  // level_files is a vector of (level, file metadata) in ascending order of
103
112
  // level. If compact_to_next_level is true, compact the file to the next
@@ -117,6 +126,7 @@ class LevelCompactionBuilder {
117
126
  int base_index_ = -1;
118
127
  double start_level_score_ = 0;
119
128
  bool is_manual_ = false;
129
+ bool is_l0_trivial_move_ = false;
120
130
  CompactionInputFiles start_level_inputs_;
121
131
  std::vector<CompactionInputFiles> compaction_inputs_;
122
132
  CompactionInputFiles output_level_inputs_;
@@ -261,7 +271,7 @@ void LevelCompactionBuilder::SetupInitialFiles() {
261
271
  }
262
272
 
263
273
  bool LevelCompactionBuilder::SetupOtherL0FilesIfNeeded() {
264
- if (start_level_ == 0 && output_level_ != 0) {
274
+ if (start_level_ == 0 && output_level_ != 0 && !is_l0_trivial_move_) {
265
275
  return compaction_picker_->GetOverlappingL0Files(
266
276
  vstorage_, &start_level_inputs_, output_level_, &parent_index_);
267
277
  }
@@ -274,7 +284,8 @@ bool LevelCompactionBuilder::SetupOtherInputsIfNeeded() {
274
284
  // need to consider other levels.
275
285
  if (output_level_ != 0) {
276
286
  output_level_inputs_.level = output_level_;
277
- if (!compaction_picker_->SetupOtherInputs(
287
+ if (!is_l0_trivial_move_ &&
288
+ !compaction_picker_->SetupOtherInputs(
278
289
  cf_name_, mutable_cf_options_, vstorage_, &start_level_inputs_,
279
290
  &output_level_inputs_, &parent_index_, base_index_)) {
280
291
  return false;
@@ -285,20 +296,22 @@ bool LevelCompactionBuilder::SetupOtherInputsIfNeeded() {
285
296
  compaction_inputs_.push_back(output_level_inputs_);
286
297
  }
287
298
 
288
- // In some edge cases we could pick a compaction that will be compacting
289
- // a key range that overlap with another running compaction, and both
290
- // of them have the same output level. This could happen if
291
- // (1) we are running a non-exclusive manual compaction
292
- // (2) AddFile ingest a new file into the LSM tree
293
- // We need to disallow this from happening.
294
- if (compaction_picker_->FilesRangeOverlapWithCompaction(compaction_inputs_,
295
- output_level_)) {
296
- // This compaction output could potentially conflict with the output
297
- // of a currently running compaction, we cannot run it.
298
- return false;
299
+ if (!is_l0_trivial_move_) {
300
+ // In some edge cases we could pick a compaction that will be compacting
301
+ // a key range that overlap with another running compaction, and both
302
+ // of them have the same output level. This could happen if
303
+ // (1) we are running a non-exclusive manual compaction
304
+ // (2) AddFile ingest a new file into the LSM tree
305
+ // We need to disallow this from happening.
306
+ if (compaction_picker_->FilesRangeOverlapWithCompaction(
307
+ compaction_inputs_, output_level_)) {
308
+ // This compaction output could potentially conflict with the output
309
+ // of a currently running compaction, we cannot run it.
310
+ return false;
311
+ }
312
+ compaction_picker_->GetGrandparents(vstorage_, start_level_inputs_,
313
+ output_level_inputs_, &grandparents_);
299
314
  }
300
- compaction_picker_->GetGrandparents(vstorage_, start_level_inputs_,
301
- output_level_inputs_, &grandparents_);
302
315
  } else {
303
316
  compaction_inputs_.push_back(start_level_inputs_);
304
317
  }
@@ -349,6 +362,7 @@ Compaction* LevelCompactionBuilder::GetCompaction() {
349
362
  Temperature::kUnknown,
350
363
  /* max_subcompactions */ 0, std::move(grandparents_), is_manual_,
351
364
  /* trim_ts */ "", start_level_score_, false /* deletion_compaction */,
365
+ /* l0_files_might_overlap */ start_level_ == 0 && !is_l0_trivial_move_,
352
366
  compaction_reason_);
353
367
 
354
368
  // If it's level 0 compaction, make sure we don't execute any other level 0
@@ -417,6 +431,124 @@ uint32_t LevelCompactionBuilder::GetPathId(
417
431
  return p;
418
432
  }
419
433
 
434
+ bool LevelCompactionBuilder::TryPickL0TrivialMove() {
435
+ if (vstorage_->base_level() <= 0) {
436
+ return false;
437
+ }
438
+ if (start_level_ == 0 && mutable_cf_options_.compression_per_level.empty() &&
439
+ !vstorage_->LevelFiles(output_level_).empty() &&
440
+ ioptions_.db_paths.size() <= 1) {
441
+ // Try to pick trivial move from L0 to L1. We start from the oldest
442
+ // file. We keep expanding to newer files if it would form a
443
+ // trivial move.
444
+ // For now we don't support it with
445
+ // mutable_cf_options_.compression_per_level to prevent the logic
446
+ // of determining whether L0 can be trivial moved to the next level.
447
+ // We skip the case where output level is empty, since in this case, at
448
+ // least the oldest file would qualify for trivial move, and this would
449
+ // be a surprising behavior with few benefits.
450
+
451
+ // We search from the oldest file from the newest. In theory, there are
452
+ // files in the middle can form trivial move too, but it is probably
453
+ // uncommon and we ignore these cases for simplicity.
454
+ const std::vector<FileMetaData*>& level_files =
455
+ vstorage_->LevelFiles(start_level_);
456
+
457
+ InternalKey my_smallest, my_largest;
458
+ for (auto it = level_files.rbegin(); it != level_files.rend(); ++it) {
459
+ CompactionInputFiles output_level_inputs;
460
+ output_level_inputs.level = output_level_;
461
+ FileMetaData* file = *it;
462
+ if (it == level_files.rbegin()) {
463
+ my_smallest = file->smallest;
464
+ my_largest = file->largest;
465
+ } else {
466
+ if (compaction_picker_->icmp()->Compare(file->largest, my_smallest) <
467
+ 0) {
468
+ my_smallest = file->smallest;
469
+ } else if (compaction_picker_->icmp()->Compare(file->smallest,
470
+ my_largest) > 0) {
471
+ my_largest = file->largest;
472
+ } else {
473
+ break;
474
+ }
475
+ }
476
+ vstorage_->GetOverlappingInputs(output_level_, &my_smallest, &my_largest,
477
+ &output_level_inputs.files);
478
+ if (output_level_inputs.empty()) {
479
+ assert(!file->being_compacted);
480
+ start_level_inputs_.files.push_back(file);
481
+ } else {
482
+ break;
483
+ }
484
+ }
485
+ }
486
+
487
+ if (!start_level_inputs_.empty()) {
488
+ // Sort files by key range. Not sure it's 100% necessary but it's cleaner
489
+ // to always keep files sorted by key the key ranges don't overlap.
490
+ std::sort(start_level_inputs_.files.begin(),
491
+ start_level_inputs_.files.end(),
492
+ [icmp = compaction_picker_->icmp()](FileMetaData* f1,
493
+ FileMetaData* f2) -> bool {
494
+ return (icmp->Compare(f1->smallest, f2->smallest) < 0);
495
+ });
496
+
497
+ is_l0_trivial_move_ = true;
498
+ return true;
499
+ }
500
+ return false;
501
+ }
502
+
503
+ bool LevelCompactionBuilder::TryExtendNonL0TrivialMove(int start_index) {
504
+ if (start_level_inputs_.size() == 1 &&
505
+ (ioptions_.db_paths.empty() || ioptions_.db_paths.size() == 1) &&
506
+ (mutable_cf_options_.compression_per_level.empty())) {
507
+ // Only file of `index`, and it is likely a trivial move. Try to
508
+ // expand if it is still a trivial move, but not beyond
509
+ // max_compaction_bytes or 4 files, so that we don't create too
510
+ // much compaction pressure for the next level.
511
+ // Ignore if there are more than one DB path, as it would be hard
512
+ // to predict whether it is a trivial move.
513
+ const std::vector<FileMetaData*>& level_files =
514
+ vstorage_->LevelFiles(start_level_);
515
+ const size_t kMaxMultiTrivialMove = 4;
516
+ FileMetaData* initial_file = start_level_inputs_.files[0];
517
+ size_t total_size = initial_file->fd.GetFileSize();
518
+ CompactionInputFiles output_level_inputs;
519
+ output_level_inputs.level = output_level_;
520
+ for (int i = start_index + 1;
521
+ i < static_cast<int>(level_files.size()) &&
522
+ start_level_inputs_.size() < kMaxMultiTrivialMove;
523
+ i++) {
524
+ FileMetaData* next_file = level_files[i];
525
+ if (next_file->being_compacted) {
526
+ break;
527
+ }
528
+ vstorage_->GetOverlappingInputs(output_level_, &(initial_file->smallest),
529
+ &(next_file->largest),
530
+ &output_level_inputs.files);
531
+ if (!output_level_inputs.empty()) {
532
+ break;
533
+ }
534
+ if (i < static_cast<int>(level_files.size()) - 1 &&
535
+ compaction_picker_->icmp()->user_comparator()->Compare(
536
+ next_file->largest.user_key(),
537
+ level_files[i + 1]->smallest.user_key()) == 0) {
538
+ // Not a clean up after adding the next file. Skip.
539
+ break;
540
+ }
541
+ total_size += next_file->fd.GetFileSize();
542
+ if (total_size > mutable_cf_options_.max_compaction_bytes) {
543
+ break;
544
+ }
545
+ start_level_inputs_.files.push_back(next_file);
546
+ }
547
+ return start_level_inputs_.size() > 1;
548
+ }
549
+ return false;
550
+ }
551
+
420
552
  bool LevelCompactionBuilder::PickFileToCompact() {
421
553
  // level 0 files are overlapping. So we cannot pick more
422
554
  // than one concurrent compactions at this level. This
@@ -429,20 +561,26 @@ bool LevelCompactionBuilder::PickFileToCompact() {
429
561
  }
430
562
 
431
563
  start_level_inputs_.clear();
564
+ start_level_inputs_.level = start_level_;
432
565
 
433
566
  assert(start_level_ >= 0);
434
567
 
435
- // Pick the largest file in this level that is not already
436
- // being compacted
437
- const std::vector<int>& file_size =
438
- vstorage_->FilesByCompactionPri(start_level_);
568
+ if (TryPickL0TrivialMove()) {
569
+ return true;
570
+ }
571
+
439
572
  const std::vector<FileMetaData*>& level_files =
440
573
  vstorage_->LevelFiles(start_level_);
441
574
 
575
+ // Pick the file with the highest score in this level that is not already
576
+ // being compacted.
577
+ const std::vector<int>& file_scores =
578
+ vstorage_->FilesByCompactionPri(start_level_);
579
+
442
580
  unsigned int cmp_idx;
443
581
  for (cmp_idx = vstorage_->NextCompactionIndex(start_level_);
444
- cmp_idx < file_size.size(); cmp_idx++) {
445
- int index = file_size[cmp_idx];
582
+ cmp_idx < file_scores.size(); cmp_idx++) {
583
+ int index = file_scores[cmp_idx];
446
584
  auto* f = level_files[index];
447
585
 
448
586
  // do not pick a file to compact if it is being compacted
@@ -460,7 +598,6 @@ bool LevelCompactionBuilder::PickFileToCompact() {
460
598
  }
461
599
 
462
600
  start_level_inputs_.files.push_back(f);
463
- start_level_inputs_.level = start_level_;
464
601
  if (!compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
465
602
  &start_level_inputs_) ||
466
603
  compaction_picker_->FilesRangeOverlapWithCompaction(
@@ -478,8 +615,8 @@ bool LevelCompactionBuilder::PickFileToCompact() {
478
615
  continue;
479
616
  }
480
617
 
481
- // Now that input level is fully expanded, we check whether any output files
482
- // are locked due to pending compaction.
618
+ // Now that input level is fully expanded, we check whether any output
619
+ // files are locked due to pending compaction.
483
620
  //
484
621
  // Note we rely on ExpandInputsToCleanCut() to tell us whether any output-
485
622
  // level files are locked, not just the extra ones pulled in for user-key
@@ -490,15 +627,19 @@ bool LevelCompactionBuilder::PickFileToCompact() {
490
627
  output_level_inputs.level = output_level_;
491
628
  vstorage_->GetOverlappingInputs(output_level_, &smallest, &largest,
492
629
  &output_level_inputs.files);
493
- if (!output_level_inputs.empty() &&
494
- !compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
495
- &output_level_inputs)) {
496
- start_level_inputs_.clear();
497
- // The same reason as above to ensure the round-robin compaction
498
- if (ioptions_.compaction_pri == kRoundRobin) {
499
- return false;
630
+ if (output_level_inputs.empty()) {
631
+ if (TryExtendNonL0TrivialMove(index)) {
632
+ break;
633
+ }
634
+ } else {
635
+ if (!compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
636
+ &output_level_inputs)) {
637
+ start_level_inputs_.clear();
638
+ if (ioptions_.compaction_pri == kRoundRobin) {
639
+ return false;
640
+ }
641
+ continue;
500
642
  }
501
- continue;
502
643
  }
503
644
  base_index_ = index;
504
645
  break;