@nxtedition/rocksdb 15.1.2 → 15.1.4

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 (154) hide show
  1. package/.claude/settings.local.json +15 -0
  2. package/binding.cc +79 -38
  3. package/build.sh +1 -2
  4. package/deps/rocksdb/rocksdb/BUCK +10 -8
  5. package/deps/rocksdb/rocksdb/CMakeLists.txt +27 -2
  6. package/deps/rocksdb/rocksdb/Makefile +27 -116
  7. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +1 -1
  8. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +101 -124
  9. package/deps/rocksdb/rocksdb/cache/clock_cache.h +47 -30
  10. package/deps/rocksdb/rocksdb/db/c.cc +793 -131
  11. package/deps/rocksdb/rocksdb/db/c_test.c +571 -0
  12. package/deps/rocksdb/rocksdb/db/compact_files_test.cc +226 -0
  13. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +4 -0
  14. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +95 -59
  15. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +2 -2
  16. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +45 -35
  17. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +8 -4
  18. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +1 -1
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +11 -6
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +8 -2
  21. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +47 -0
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +12 -2
  23. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +82 -0
  24. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +2 -2
  25. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +1 -1
  26. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +69 -24
  27. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +9 -1
  28. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +65 -0
  29. package/deps/rocksdb/rocksdb/db/db_etc3_test.cc +161 -0
  30. package/deps/rocksdb/rocksdb/db/db_filesnapshot.cc +1 -0
  31. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +20 -7
  32. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +13 -0
  33. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +114 -39
  34. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +3 -0
  35. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_follower.cc +3 -3
  36. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +1 -1
  37. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +39 -25
  38. package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +361 -0
  39. package/deps/rocksdb/rocksdb/db/db_options_test.cc +35 -0
  40. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +83 -0
  41. package/deps/rocksdb/rocksdb/db/db_test.cc +249 -4
  42. package/deps/rocksdb/rocksdb/db/db_test2.cc +3 -0
  43. package/deps/rocksdb/rocksdb/db/db_test_util.cc +2 -1
  44. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +3 -2
  45. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +7 -7
  46. package/deps/rocksdb/rocksdb/db/listener_test.cc +7 -17
  47. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +4 -2
  48. package/deps/rocksdb/rocksdb/db/obsolete_files_test.cc +41 -0
  49. package/deps/rocksdb/rocksdb/db/repair.cc +2 -2
  50. package/deps/rocksdb/rocksdb/db/version_edit.h +7 -4
  51. package/deps/rocksdb/rocksdb/db/version_set.cc +299 -90
  52. package/deps/rocksdb/rocksdb/db/version_set.h +56 -9
  53. package/deps/rocksdb/rocksdb/db/version_set_test.cc +41 -39
  54. package/deps/rocksdb/rocksdb/db/version_util.h +3 -2
  55. package/deps/rocksdb/rocksdb/db/wal_manager.cc +7 -1
  56. package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +48 -10
  57. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -0
  58. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +5 -1
  59. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +16 -5
  60. package/deps/rocksdb/rocksdb/env/env_test.cc +126 -41
  61. package/deps/rocksdb/rocksdb/env/fs_posix.cc +14 -7
  62. package/deps/rocksdb/rocksdb/env/io_posix.cc +304 -112
  63. package/deps/rocksdb/rocksdb/env/io_posix.h +16 -4
  64. package/deps/rocksdb/rocksdb/env/io_posix_test.cc +43 -0
  65. package/deps/rocksdb/rocksdb/folly.mk +148 -0
  66. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_compression.h +29 -3
  67. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +73 -0
  68. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +246 -0
  69. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_filter.h +0 -2
  70. package/deps/rocksdb/rocksdb/include/rocksdb/data_structure.h +15 -9
  71. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +19 -9
  72. package/deps/rocksdb/rocksdb/include/rocksdb/env.h +1 -1
  73. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +6 -4
  74. package/deps/rocksdb/rocksdb/include/rocksdb/metadata.h +14 -0
  75. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +67 -6
  76. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +1 -7
  77. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +3 -0
  78. package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +6 -14
  79. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/backup_engine.h +8 -1
  80. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/env_mirror.h +2 -2
  81. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd_execute_result.h +0 -4
  82. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/option_change_migration.h +33 -5
  83. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +6 -0
  84. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
  85. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +2 -0
  86. package/deps/rocksdb/rocksdb/monitoring/thread_status_impl.cc +5 -2
  87. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.cc +2 -2
  88. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.h +6 -6
  89. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater_debug.cc +2 -2
  90. package/deps/rocksdb/rocksdb/monitoring/thread_status_util.cc +10 -5
  91. package/deps/rocksdb/rocksdb/monitoring/thread_status_util.h +2 -2
  92. package/deps/rocksdb/rocksdb/options/cf_options.cc +15 -3
  93. package/deps/rocksdb/rocksdb/options/cf_options.h +7 -0
  94. package/deps/rocksdb/rocksdb/options/db_options.cc +27 -36
  95. package/deps/rocksdb/rocksdb/options/db_options.h +3 -2
  96. package/deps/rocksdb/rocksdb/options/options.cc +4 -0
  97. package/deps/rocksdb/rocksdb/options/options_helper.cc +8 -2
  98. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +4 -1
  99. package/deps/rocksdb/rocksdb/options/options_test.cc +19 -3
  100. package/deps/rocksdb/rocksdb/src.mk +1 -1
  101. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +155 -32
  102. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +7 -3
  103. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +169 -125
  104. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +22 -7
  105. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +43 -24
  106. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +9 -5
  107. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +9 -8
  108. package/deps/rocksdb/rocksdb/table/block_based/filter_block.h +17 -0
  109. package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +15 -5
  110. package/deps/rocksdb/rocksdb/table/block_based/filter_policy_internal.h +13 -18
  111. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +29 -0
  112. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.h +6 -0
  113. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +15 -0
  114. package/deps/rocksdb/rocksdb/table/block_based/index_builder.cc +79 -19
  115. package/deps/rocksdb/rocksdb/table/block_based/index_builder.h +48 -20
  116. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +51 -0
  117. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +19 -0
  118. package/deps/rocksdb/rocksdb/table/block_based/user_defined_index_wrapper.h +1 -1
  119. package/deps/rocksdb/rocksdb/table/external_table.cc +2 -2
  120. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +3 -2
  121. package/deps/rocksdb/rocksdb/table/sst_file_dumper.h +3 -1
  122. package/deps/rocksdb/rocksdb/table/table_builder.h +5 -0
  123. package/deps/rocksdb/rocksdb/table/table_reader.h +4 -2
  124. package/deps/rocksdb/rocksdb/table/table_test.cc +48 -39
  125. package/deps/rocksdb/rocksdb/test_util/sync_point.cc +4 -0
  126. package/deps/rocksdb/rocksdb/test_util/sync_point.h +32 -0
  127. package/deps/rocksdb/rocksdb/test_util/testutil.h +6 -2
  128. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +14 -4
  129. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +8 -5
  130. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +3 -2
  131. package/deps/rocksdb/rocksdb/tools/sst_dump_tool.cc +63 -12
  132. package/deps/rocksdb/rocksdb/util/auto_tune_compressor.cc +16 -1
  133. package/deps/rocksdb/rocksdb/util/auto_tune_compressor.h +5 -1
  134. package/deps/rocksdb/rocksdb/util/bit_fields.h +133 -23
  135. package/deps/rocksdb/rocksdb/util/bloom_test.cc +2 -5
  136. package/deps/rocksdb/rocksdb/util/compression.cc +51 -23
  137. package/deps/rocksdb/rocksdb/util/compression_test.cc +525 -270
  138. package/deps/rocksdb/rocksdb/util/filter_bench.cc +3 -4
  139. package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.cc +11 -2
  140. package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.h +4 -1
  141. package/deps/rocksdb/rocksdb/util/slice_test.cc +92 -0
  142. package/deps/rocksdb/rocksdb/util/thread_list_test.cc +2 -2
  143. package/deps/rocksdb/rocksdb/util/thread_operation.h +2 -2
  144. package/deps/rocksdb/rocksdb/util/threadpool_imp.cc +2 -2
  145. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +19 -2
  146. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +75 -0
  147. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +1 -0
  148. package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration.cc +303 -111
  149. package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration_test.cc +379 -0
  150. package/deps/rocksdb/rocksdb.gyp +1 -0
  151. package/iterator.js +66 -70
  152. package/package.json +6 -6
  153. package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
  154. package/deps/rocksdb/rocksdb/table/block_based/index_builder_test.cc +0 -183
@@ -23,147 +23,339 @@ Options GetNoCompactionOptions(const Options& opts) {
23
23
  return ret_opts;
24
24
  }
25
25
 
26
- Status OpenDb(const Options& options, const std::string& dbname,
27
- std::unique_ptr<DB>* db) {
28
- db->reset();
29
- DB* tmpdb;
30
- Status s = DB::Open(options, dbname, &tmpdb);
31
- if (s.ok()) {
32
- db->reset(tmpdb);
33
- }
34
- return s;
35
- }
26
+ // Compact a specific CF to a specific level
27
+ // cf_handle should not be null
28
+ Status CompactToLevel(DB* db, ColumnFamilyHandle* cf_handle, int dest_level) {
29
+ assert(cf_handle != nullptr);
36
30
 
37
- // l0_file_size specifies size of file on L0. Files will be range partitioned
38
- // after a full compaction so they are likely qualified to put on L0. If
39
- // left as 0, the files are compacted in a single file and put to L0. Otherwise,
40
- // will try to compact the files as size l0_file_size.
41
- Status CompactToLevel(const Options& options, const std::string& dbname,
42
- int dest_level, uint64_t l0_file_size, bool need_reopen) {
43
- std::unique_ptr<DB> db;
44
- Options no_compact_opts = GetNoCompactionOptions(options);
45
- if (dest_level == 0) {
46
- if (l0_file_size == 0) {
47
- // Single file.
48
- l0_file_size = 999999999999999;
49
- }
50
- // L0 has strict sequenceID requirements to files to it. It's safer
51
- // to only put one compacted file to there.
52
- // This is only used for converting to universal compaction with
53
- // only one level. In this case, compacting to one file is also
54
- // optimal.
55
- no_compact_opts.target_file_size_base = l0_file_size;
56
- no_compact_opts.max_compaction_bytes = l0_file_size;
57
- }
58
- Status s = OpenDb(no_compact_opts, dbname, &db);
59
- if (!s.ok()) {
60
- return s;
61
- }
62
31
  CompactRangeOptions cro;
63
32
  cro.change_level = true;
64
33
  cro.target_level = dest_level;
34
+
65
35
  if (dest_level == 0) {
66
36
  // cannot use kForceOptimized because the compaction is expected to
67
- // generate one output file
37
+ // generate one output file so to force the full compaction to skip trivial
38
+ // move to L0
68
39
  cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
69
40
  }
70
- s = db->CompactRange(cro, nullptr, nullptr);
71
41
 
72
- if (s.ok() && need_reopen) {
73
- // Need to restart DB to rewrite the manifest file.
74
- // In order to open a DB with specific num_levels, the manifest file should
75
- // contain no record that mentiones any level beyond num_levels. Issuing a
76
- // full compaction will move all the data to a level not exceeding
77
- // num_levels, but the manifest may still contain previous record mentioning
78
- // a higher level. Reopening the DB will force the manifest to be rewritten
79
- // so that those records will be cleared.
80
- db.reset();
81
- s = OpenDb(no_compact_opts, dbname, &db);
82
- }
83
- return s;
42
+ return db->CompactRange(cro, cf_handle, nullptr, nullptr);
84
43
  }
85
44
 
86
- Status MigrateToUniversal(std::string dbname, const Options& old_opts,
87
- const Options& new_opts) {
88
- if (old_opts.num_levels <= new_opts.num_levels ||
89
- old_opts.compaction_style == CompactionStyle::kCompactionStyleFIFO) {
90
- return Status::OK();
91
- } else {
92
- bool need_compact = false;
93
- {
94
- std::unique_ptr<DB> db;
95
- Options opts = GetNoCompactionOptions(old_opts);
96
- Status s = OpenDb(opts, dbname, &db);
97
- if (!s.ok()) {
98
- return s;
99
- }
100
- ColumnFamilyMetaData metadata;
101
- db->GetColumnFamilyMetaData(&metadata);
102
- if (!metadata.levels.empty() &&
103
- metadata.levels.back().level >= new_opts.num_levels) {
104
- need_compact = true;
105
- }
106
- }
107
- if (need_compact) {
108
- return CompactToLevel(old_opts, dbname, new_opts.num_levels - 1,
109
- /*l0_file_size=*/0, true);
110
- }
45
+ Status MigrateToUniversal(DB* db, ColumnFamilyHandle* cf_handle,
46
+ int old_num_levels, int new_num_levels) {
47
+ assert(cf_handle != nullptr);
48
+
49
+ if (old_num_levels <= new_num_levels) {
111
50
  return Status::OK();
112
51
  }
52
+
53
+ // Check if compaction is needed
54
+ ColumnFamilyMetaData metadata;
55
+ db->GetColumnFamilyMetaData(cf_handle, &metadata);
56
+
57
+ if (!metadata.levels.empty() &&
58
+ metadata.levels.back().level >= new_num_levels) {
59
+ // Need to compact to fit new num_levels
60
+ return CompactToLevel(db, cf_handle, new_num_levels - 1);
61
+ }
62
+
63
+ return Status::OK();
113
64
  }
114
65
 
115
- Status MigrateToLevelBase(std::string dbname, const Options& old_opts,
116
- const Options& new_opts) {
117
- if (!new_opts.level_compaction_dynamic_level_bytes) {
118
- if (old_opts.num_levels == 1) {
66
+ Status MigrateToLevelBase(DB* db, ColumnFamilyHandle* cf_handle,
67
+ int old_num_levels, int new_num_levels,
68
+ bool dynamic_level_bytes) {
69
+ assert(cf_handle != nullptr);
70
+
71
+ if (!dynamic_level_bytes) {
72
+ // Non-dynamic level mode
73
+ if (old_num_levels == 1) {
119
74
  return Status::OK();
120
75
  }
121
- // Compact everything to level 1 to guarantee it can be safely opened.
122
- Options opts = old_opts;
123
- opts.target_file_size_base = new_opts.target_file_size_base;
124
- // Although sometimes we can open the DB with the new option without error,
125
- // We still want to compact the files to avoid the LSM tree to stuck
126
- // in bad shape. For example, if the user changed the level size
127
- // multiplier from 4 to 8, with the same data, we will have fewer
128
- // levels. Unless we issue a full comaction, the LSM tree may stuck
129
- // with more levels than needed and it won't recover automatically.
130
- return CompactToLevel(opts, dbname, 1, /*l0_file_size=*/0, true);
76
+ // Compact to L1
77
+ return CompactToLevel(db, cf_handle, 1);
78
+
131
79
  } else {
132
- // Compact everything to the last level to guarantee it can be safely
133
- // opened.
134
- if (old_opts.num_levels == 1) {
80
+ // Dynamic level mode
81
+ if (old_num_levels == 1) {
135
82
  return Status::OK();
136
- } else if (new_opts.num_levels > old_opts.num_levels) {
137
- // Dynamic level mode requires data to be put in the last level first.
138
- return CompactToLevel(new_opts, dbname, new_opts.num_levels - 1,
139
- /*l0_file_size=*/0, false);
140
- } else {
141
- Options opts = old_opts;
142
- opts.target_file_size_base = new_opts.target_file_size_base;
143
- return CompactToLevel(opts, dbname, new_opts.num_levels - 1,
144
- /*l0_file_size=*/0, true);
145
83
  }
84
+ // Compact to last level
85
+ return CompactToLevel(db, cf_handle, new_num_levels - 1);
146
86
  }
147
87
  }
148
- } // namespace
149
88
 
150
- Status OptionChangeMigration(std::string dbname, const Options& old_opts,
151
- const Options& new_opts) {
89
+ Status MigrateToFIFO(DB* db, ColumnFamilyHandle* cf_handle) {
90
+ assert(cf_handle != nullptr);
91
+ return CompactToLevel(db, cf_handle, 0);
92
+ }
93
+
94
+ Status MigrateSingleColumnFamily(DB* db, ColumnFamilyHandle* cf_handle,
95
+ const Options& old_opts,
96
+ const Options& new_opts) {
97
+ assert(cf_handle != nullptr);
98
+
152
99
  if (old_opts.compaction_style == CompactionStyle::kCompactionStyleFIFO) {
153
- // LSM generated by FIFO compaction can be opened by any compaction.
154
100
  return Status::OK();
155
- } else if (new_opts.compaction_style ==
156
- CompactionStyle::kCompactionStyleUniversal) {
157
- return MigrateToUniversal(dbname, old_opts, new_opts);
101
+ }
102
+
103
+ if (new_opts.compaction_style == CompactionStyle::kCompactionStyleUniversal) {
104
+ return MigrateToUniversal(db, cf_handle, old_opts.num_levels,
105
+ new_opts.num_levels);
158
106
  } else if (new_opts.compaction_style ==
159
107
  CompactionStyle::kCompactionStyleLevel) {
160
- return MigrateToLevelBase(dbname, old_opts, new_opts);
108
+ return MigrateToLevelBase(db, cf_handle, old_opts.num_levels,
109
+ new_opts.num_levels,
110
+ new_opts.level_compaction_dynamic_level_bytes);
161
111
  } else if (new_opts.compaction_style ==
162
112
  CompactionStyle::kCompactionStyleFIFO) {
163
- return CompactToLevel(old_opts, dbname, 0, 0 /* l0_file_size */, true);
113
+ return MigrateToFIFO(db, cf_handle);
114
+ }
115
+
116
+ return Status::NotSupported(
117
+ "Do not know how to migrate to this compaction style");
118
+ }
119
+
120
+ Status ValidateCFDescriptors(
121
+ const std::vector<ColumnFamilyDescriptor>& old_cf_descs,
122
+ const std::vector<ColumnFamilyDescriptor>& new_cf_descs) {
123
+ if (old_cf_descs.size() != new_cf_descs.size()) {
124
+ return Status::InvalidArgument(
125
+ "old_cf_descs and new_cf_descs must have the same number of column "
126
+ "families. Got " +
127
+ std::to_string(old_cf_descs.size()) + " old CFs and " +
128
+ std::to_string(new_cf_descs.size()) +
129
+ " new CFs. Adding or dropping CFs is not supported.");
130
+ }
131
+
132
+ for (size_t i = 0; i < old_cf_descs.size(); ++i) {
133
+ if (old_cf_descs[i].name != new_cf_descs[i].name) {
134
+ return Status::InvalidArgument(
135
+ "Column family mismatch at index " + std::to_string(i) + ": " +
136
+ "old has '" + old_cf_descs[i].name + "', " + "new has '" +
137
+ new_cf_descs[i].name + "'. CF names and order must match exactly.");
138
+ }
139
+ }
140
+
141
+ return Status::OK();
142
+ }
143
+
144
+ struct BaseOptionsResult {
145
+ ColumnFamilyOptions base_opts;
146
+ bool need_reopen = true;
147
+ };
148
+
149
+ BaseOptionsResult DetermineBaseOptions(const ColumnFamilyOptions& old_opts,
150
+ const ColumnFamilyOptions& new_opts) {
151
+ BaseOptionsResult result;
152
+
153
+ if (new_opts.compaction_style == CompactionStyle::kCompactionStyleLevel) {
154
+ if (!new_opts.level_compaction_dynamic_level_bytes) {
155
+ result.base_opts = old_opts;
156
+ result.base_opts.target_file_size_base = new_opts.target_file_size_base;
157
+ } else {
158
+ if (new_opts.num_levels > old_opts.num_levels) {
159
+ result.base_opts = new_opts;
160
+ result.need_reopen = false;
161
+ } else {
162
+ result.base_opts = old_opts;
163
+ result.base_opts.target_file_size_base = new_opts.target_file_size_base;
164
+ }
165
+ }
166
+ } else {
167
+ result.base_opts = old_opts;
168
+ }
169
+
170
+ return result;
171
+ }
172
+
173
+ void ApplySpecialSingleLevelSettings(const ColumnFamilyOptions& new_opts,
174
+ ColumnFamilyOptions* base_opts) {
175
+ if (((new_opts.compaction_style ==
176
+ CompactionStyle::kCompactionStyleUniversal ||
177
+ new_opts.compaction_style == CompactionStyle::kCompactionStyleLevel) &&
178
+ new_opts.num_levels == 1) ||
179
+ new_opts.compaction_style == CompactionStyle::kCompactionStyleFIFO) {
180
+ base_opts->target_file_size_base = 999999999999999;
181
+ base_opts->max_compaction_bytes = 999999999999999;
182
+ }
183
+ }
184
+
185
+ std::vector<ColumnFamilyDescriptor> PrepareNoCompactionCFDescriptors(
186
+ const DBOptions& old_db_opts,
187
+ const std::vector<ColumnFamilyDescriptor>& old_cf_descs,
188
+ const std::vector<ColumnFamilyDescriptor>& new_cf_descs,
189
+ bool* any_need_reopen) {
190
+ assert(old_cf_descs.size() == new_cf_descs.size());
191
+
192
+ std::vector<ColumnFamilyDescriptor> no_compact_cf_descs;
193
+ *any_need_reopen = false;
194
+
195
+ for (size_t i = 0; i < old_cf_descs.size(); ++i) {
196
+ const std::string& cf_name = old_cf_descs[i].name;
197
+ const ColumnFamilyOptions& old_opts = old_cf_descs[i].options;
198
+ const ColumnFamilyOptions& new_opts = new_cf_descs[i].options;
199
+
200
+ BaseOptionsResult result = DetermineBaseOptions(old_opts, new_opts);
201
+ ColumnFamilyOptions base_opts = result.base_opts;
202
+
203
+ if (result.need_reopen) {
204
+ *any_need_reopen = true;
205
+ }
206
+
207
+ ApplySpecialSingleLevelSettings(new_opts, &base_opts);
208
+
209
+ Options tmp_opts(old_db_opts, base_opts);
210
+ Options no_compact_opts = GetNoCompactionOptions(tmp_opts);
211
+
212
+ no_compact_cf_descs.emplace_back(cf_name,
213
+ ColumnFamilyOptions(no_compact_opts));
214
+ }
215
+
216
+ return no_compact_cf_descs;
217
+ }
218
+
219
+ Status OpenDBWithCFs(const DBOptions& db_opts, const std::string& dbname,
220
+ const std::vector<ColumnFamilyDescriptor>& cf_descs,
221
+ std::unique_ptr<DB>* db,
222
+ std::vector<ColumnFamilyHandle*>* handles) {
223
+ handles->clear();
224
+ DB* tmpdb;
225
+ Status s = DB::Open(db_opts, dbname, cf_descs, handles, &tmpdb);
226
+
227
+ if (s.ok()) {
228
+ db->reset(tmpdb);
164
229
  } else {
165
- return Status::NotSupported(
166
- "Do not how to migrate to this compaction style");
230
+ for (auto* handle : *handles) {
231
+ delete handle;
232
+ }
233
+ handles->clear();
167
234
  }
235
+
236
+ return s;
237
+ }
238
+
239
+ Status CleanupCFHandles(DB* db, std::vector<ColumnFamilyHandle*>* handles) {
240
+ Status s;
241
+ for (auto* handle : *handles) {
242
+ if (handle != db->DefaultColumnFamily()) {
243
+ Status destroy_status = db->DestroyColumnFamilyHandle(handle);
244
+ if (!destroy_status.ok() && s.ok()) {
245
+ s = destroy_status;
246
+ }
247
+ }
248
+ }
249
+ handles->clear();
250
+ return s;
251
+ }
252
+
253
+ Status MigrateAllCFs(DB* db, const std::vector<ColumnFamilyHandle*>& handles,
254
+ const DBOptions& old_db_opts, const DBOptions& new_db_opts,
255
+ const std::vector<ColumnFamilyDescriptor>& old_cf_descs,
256
+ const std::vector<ColumnFamilyDescriptor>& new_cf_descs) {
257
+ assert(handles.size() == old_cf_descs.size());
258
+ assert(old_cf_descs.size() == new_cf_descs.size());
259
+
260
+ for (size_t i = 0; i < handles.size(); ++i) {
261
+ const ColumnFamilyOptions& old_cf_opts = old_cf_descs[i].options;
262
+ const ColumnFamilyOptions& new_cf_opts = new_cf_descs[i].options;
263
+
264
+ Options old_opts(old_db_opts, old_cf_opts);
265
+ Options new_opts(new_db_opts, new_cf_opts);
266
+
267
+ Status s = MigrateSingleColumnFamily(db, handles[i], old_opts, new_opts);
268
+ if (!s.ok()) {
269
+ return s;
270
+ }
271
+ }
272
+
273
+ return Status::OK();
274
+ }
275
+ } // namespace
276
+
277
+ Status OptionChangeMigration(
278
+ const std::string& dbname, const DBOptions& old_db_opts,
279
+ const std::vector<ColumnFamilyDescriptor>& old_cf_descs,
280
+ const DBOptions& new_db_opts,
281
+ const std::vector<ColumnFamilyDescriptor>& new_cf_descs) {
282
+ // Step 1: Validate that old and new have same CFs in same order
283
+ Status s = ValidateCFDescriptors(old_cf_descs, new_cf_descs);
284
+ if (!s.ok()) {
285
+ return s;
286
+ }
287
+
288
+ // Step 2: Prepare no-compaction CF descriptors
289
+ bool any_need_reopen = false;
290
+ std::vector<ColumnFamilyDescriptor> no_compact_cf_descs =
291
+ PrepareNoCompactionCFDescriptors(old_db_opts, old_cf_descs, new_cf_descs,
292
+ &any_need_reopen);
293
+
294
+ // Step 3: Open DB with all CFs
295
+ std::unique_ptr<DB> db;
296
+ std::vector<ColumnFamilyHandle*> handles;
297
+ s = OpenDBWithCFs(old_db_opts, dbname, no_compact_cf_descs, &db, &handles);
298
+ if (!s.ok()) {
299
+ return s;
300
+ }
301
+ assert(db != nullptr);
302
+
303
+ // Step 4: Migrate all CFs
304
+ s = MigrateAllCFs(db.get(), handles, old_db_opts, new_db_opts, old_cf_descs,
305
+ new_cf_descs);
306
+
307
+ // Step 5: Cleanup CF handles
308
+ Status cleanup_status = CleanupCFHandles(db.get(), &handles);
309
+ if (s.ok() && !cleanup_status.ok()) {
310
+ s = cleanup_status;
311
+ }
312
+
313
+ // Step 6: Close and reopen DB if needed to rewrite manifest
314
+ if (s.ok() && any_need_reopen) {
315
+ Status close_status = db->Close();
316
+ if (!close_status.ok()) {
317
+ return close_status;
318
+ }
319
+ db.reset();
320
+
321
+ s = OpenDBWithCFs(old_db_opts, dbname, no_compact_cf_descs, &db, &handles);
322
+ if (!s.ok()) {
323
+ return s;
324
+ }
325
+
326
+ // Cleanup CF handles before final close
327
+ cleanup_status = CleanupCFHandles(db.get(), &handles);
328
+ if (!cleanup_status.ok() && s.ok()) {
329
+ s = cleanup_status;
330
+ }
331
+ }
332
+
333
+ // Final step: Close DB (either after reopening or without reopening)
334
+ Status close_status = db->Close();
335
+ if (!close_status.ok() && s.ok()) {
336
+ s = close_status;
337
+ }
338
+
339
+ db.reset();
340
+
341
+ return s;
342
+ }
343
+
344
+ Status OptionChangeMigration(const std::string& dbname, const Options& old_opts,
345
+ const Options& new_opts) {
346
+ DBOptions old_db_opts(old_opts);
347
+ DBOptions new_db_opts(new_opts);
348
+
349
+ ColumnFamilyOptions old_cf_opts(old_opts);
350
+ ColumnFamilyOptions new_cf_opts(new_opts);
351
+
352
+ std::vector<ColumnFamilyDescriptor> old_cf_descs = {
353
+ {kDefaultColumnFamilyName, old_cf_opts}};
354
+
355
+ std::vector<ColumnFamilyDescriptor> new_cf_descs = {
356
+ {kDefaultColumnFamilyName, new_cf_opts}};
357
+
358
+ return OptionChangeMigration(dbname, old_db_opts, old_cf_descs, new_db_opts,
359
+ new_cf_descs);
168
360
  }
169
361
  } // namespace ROCKSDB_NAMESPACE