@nxtedition/rocksdb 14.0.0 → 15.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 (102) hide show
  1. package/binding.cc +52 -179
  2. package/deps/rocksdb/rocksdb/BUCK +7 -0
  3. package/deps/rocksdb/rocksdb/CMakeLists.txt +29 -14
  4. package/deps/rocksdb/rocksdb/Directory.Build.props +9 -0
  5. package/deps/rocksdb/rocksdb/Makefile +6 -1
  6. package/deps/rocksdb/rocksdb/cache/secondary_cache_adapter.cc +4 -4
  7. package/deps/rocksdb/rocksdb/ccache_msvc_compiler.bat +1 -0
  8. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +17 -3
  9. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +8 -3
  10. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +10 -0
  11. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +522 -60
  12. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +69 -10
  13. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +443 -0
  14. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +4 -2
  15. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +14 -3
  16. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +5 -5
  17. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +3 -6
  18. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +1 -1
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +28 -5
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +4 -4
  21. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +6 -3
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +455 -98
  23. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +4 -2
  24. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +13 -1
  25. package/deps/rocksdb/rocksdb/db/db_flush_test.cc +146 -0
  26. package/deps/rocksdb/rocksdb/db/db_follower_test.cc +2 -2
  27. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +6 -0
  28. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +5 -2
  29. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +18 -19
  30. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +5 -0
  31. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +665 -14
  32. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.h +83 -0
  33. package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +68 -0
  34. package/deps/rocksdb/rocksdb/db/db_rate_limiter_test.cc +101 -0
  35. package/deps/rocksdb/rocksdb/db/dbformat_test.cc +44 -0
  36. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +1 -2
  37. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +22 -5
  38. package/deps/rocksdb/rocksdb/db/log_reader.h +4 -4
  39. package/deps/rocksdb/rocksdb/db/log_writer.h +1 -1
  40. package/deps/rocksdb/rocksdb/db/merge_helper.h +1 -1
  41. package/deps/rocksdb/rocksdb/db/version_edit.cc +477 -139
  42. package/deps/rocksdb/rocksdb/db/version_edit.h +228 -8
  43. package/deps/rocksdb/rocksdb/db/version_edit_test.cc +333 -0
  44. package/deps/rocksdb/rocksdb/db/write_thread.h +1 -1
  45. package/deps/rocksdb/rocksdb/db_stress_tool/CMakeLists.txt +1 -0
  46. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +247 -32
  47. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +3 -0
  48. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_compaction_service.cc +61 -0
  49. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_compaction_service.h +17 -28
  50. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +16 -0
  51. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_listener.h +6 -1
  52. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.h +46 -18
  53. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +18 -1
  54. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +8 -7
  55. package/deps/rocksdb/rocksdb/db_stress_tool/expected_value.h +4 -4
  56. package/deps/rocksdb/rocksdb/env/fs_posix.cc +1 -0
  57. package/deps/rocksdb/rocksdb/file/filename.cc +40 -0
  58. package/deps/rocksdb/rocksdb/file/filename.h +14 -1
  59. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +4 -3
  60. package/deps/rocksdb/rocksdb/file/writable_file_writer.h +2 -1
  61. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +26 -7
  62. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +5 -3
  63. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +59 -0
  64. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +3 -0
  65. package/deps/rocksdb/rocksdb/include/rocksdb/table.h +24 -0
  66. package/deps/rocksdb/rocksdb/include/rocksdb/types.h +2 -1
  67. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +4 -0
  68. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +13 -8
  69. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +1 -0
  70. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +2 -0
  71. package/deps/rocksdb/rocksdb/options/options_test.cc +5 -0
  72. package/deps/rocksdb/rocksdb/src.mk +2 -0
  73. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +73 -16
  74. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +10 -5
  75. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +32 -0
  76. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +18 -27
  77. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +0 -3
  78. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +5 -1
  79. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +708 -217
  80. package/deps/rocksdb/rocksdb/table/block_based/block_builder.cc +11 -6
  81. package/deps/rocksdb/rocksdb/table/block_based/block_builder.h +5 -3
  82. package/deps/rocksdb/rocksdb/table/block_based/block_prefetcher.cc +27 -19
  83. package/deps/rocksdb/rocksdb/table/block_based/index_builder.cc +24 -6
  84. package/deps/rocksdb/rocksdb/table/block_based/index_builder.h +51 -18
  85. package/deps/rocksdb/rocksdb/table/block_based/index_builder_test.cc +183 -0
  86. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +4 -2
  87. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_iterator.h +0 -2
  88. package/deps/rocksdb/rocksdb/table/block_based/user_defined_index_wrapper.h +8 -3
  89. package/deps/rocksdb/rocksdb/table/plain/plain_table_reader.cc +3 -1
  90. package/deps/rocksdb/rocksdb/table/table_test.cc +222 -36
  91. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +246 -6
  92. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +86 -0
  93. package/deps/rocksdb/rocksdb/tools/ldb_cmd_impl.h +21 -0
  94. package/deps/rocksdb/rocksdb/tools/ldb_tool.cc +1 -0
  95. package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +1 -1
  96. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +1 -0
  97. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager.cc +0 -2
  98. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.cc +12 -12
  99. package/index.js +27 -37
  100. package/package.json +1 -1
  101. package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
  102. package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
@@ -112,124 +112,9 @@ bool VersionEdit::EncodeTo(std::string* dst,
112
112
  f.epoch_number == kUnknownEpochNumber) {
113
113
  return false;
114
114
  }
115
- PutVarint32(dst, kNewFile4);
116
- PutVarint32Varint64(dst, new_files_[i].first /* level */, f.fd.GetNumber());
117
- PutVarint64(dst, f.fd.GetFileSize());
118
- EncodeFileBoundaries(dst, f, ts_sz.value());
119
- PutVarint64Varint64(dst, f.fd.smallest_seqno, f.fd.largest_seqno);
120
- // Customized fields' format:
121
- // +-----------------------------+
122
- // | 1st field's tag (varint32) |
123
- // +-----------------------------+
124
- // | 1st field's size (varint32) |
125
- // +-----------------------------+
126
- // | bytes for 1st field |
127
- // | (based on size decoded) |
128
- // +-----------------------------+
129
- // | |
130
- // | ...... |
131
- // | |
132
- // +-----------------------------+
133
- // | last field's size (varint32)|
134
- // +-----------------------------+
135
- // | bytes for last field |
136
- // | (based on size decoded) |
137
- // +-----------------------------+
138
- // | terminating tag (varint32) |
139
- // +-----------------------------+
140
- //
141
- // Customized encoding for fields:
142
- // tag kPathId: 1 byte as path_id
143
- // tag kNeedCompaction:
144
- // now only can take one char value 1 indicating need-compaction
145
- //
146
- PutVarint32(dst, NewFileCustomTag::kOldestAncesterTime);
147
- std::string varint_oldest_ancester_time;
148
- PutVarint64(&varint_oldest_ancester_time, f.oldest_ancester_time);
149
- TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:VarintOldestAncesterTime",
150
- &varint_oldest_ancester_time);
151
- PutLengthPrefixedSlice(dst, Slice(varint_oldest_ancester_time));
152
-
153
- PutVarint32(dst, NewFileCustomTag::kFileCreationTime);
154
- std::string varint_file_creation_time;
155
- PutVarint64(&varint_file_creation_time, f.file_creation_time);
156
- TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:VarintFileCreationTime",
157
- &varint_file_creation_time);
158
- PutLengthPrefixedSlice(dst, Slice(varint_file_creation_time));
159
-
160
- PutVarint32(dst, NewFileCustomTag::kEpochNumber);
161
- std::string varint_epoch_number;
162
- PutVarint64(&varint_epoch_number, f.epoch_number);
163
- PutLengthPrefixedSlice(dst, Slice(varint_epoch_number));
164
-
165
- if (f.file_checksum_func_name != kUnknownFileChecksumFuncName) {
166
- PutVarint32(dst, NewFileCustomTag::kFileChecksum);
167
- PutLengthPrefixedSlice(dst, Slice(f.file_checksum));
168
-
169
- PutVarint32(dst, NewFileCustomTag::kFileChecksumFuncName);
170
- PutLengthPrefixedSlice(dst, Slice(f.file_checksum_func_name));
171
- }
172
-
173
- if (f.fd.GetPathId() != 0) {
174
- PutVarint32(dst, NewFileCustomTag::kPathId);
175
- char p = static_cast<char>(f.fd.GetPathId());
176
- PutLengthPrefixedSlice(dst, Slice(&p, 1));
177
- }
178
- if (f.temperature != Temperature::kUnknown) {
179
- PutVarint32(dst, NewFileCustomTag::kTemperature);
180
- char p = static_cast<char>(f.temperature);
181
- PutLengthPrefixedSlice(dst, Slice(&p, 1));
182
- }
183
- if (f.marked_for_compaction) {
184
- PutVarint32(dst, NewFileCustomTag::kNeedCompaction);
185
- char p = static_cast<char>(1);
186
- PutLengthPrefixedSlice(dst, Slice(&p, 1));
187
- }
188
- if (has_min_log_number_to_keep_ && !min_log_num_written) {
189
- PutVarint32(dst, NewFileCustomTag::kMinLogNumberToKeepHack);
190
- std::string varint_log_number;
191
- PutFixed64(&varint_log_number, min_log_number_to_keep_);
192
- PutLengthPrefixedSlice(dst, Slice(varint_log_number));
193
- min_log_num_written = true;
194
- }
195
- if (f.oldest_blob_file_number != kInvalidBlobFileNumber) {
196
- PutVarint32(dst, NewFileCustomTag::kOldestBlobFileNumber);
197
- std::string oldest_blob_file_number;
198
- PutVarint64(&oldest_blob_file_number, f.oldest_blob_file_number);
199
- PutLengthPrefixedSlice(dst, Slice(oldest_blob_file_number));
200
- }
201
- UniqueId64x2 unique_id = f.unique_id;
202
- TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:UniqueId", &unique_id);
203
- if (unique_id != kNullUniqueId64x2) {
204
- PutVarint32(dst, NewFileCustomTag::kUniqueId);
205
- std::string unique_id_str = EncodeUniqueIdBytes(&unique_id);
206
- PutLengthPrefixedSlice(dst, Slice(unique_id_str));
207
- }
208
- if (f.compensated_range_deletion_size) {
209
- PutVarint32(dst, kCompensatedRangeDeletionSize);
210
- std::string compensated_range_deletion_size;
211
- PutVarint64(&compensated_range_deletion_size,
212
- f.compensated_range_deletion_size);
213
- PutLengthPrefixedSlice(dst, Slice(compensated_range_deletion_size));
214
- }
215
- if (f.tail_size) {
216
- PutVarint32(dst, NewFileCustomTag::kTailSize);
217
- std::string varint_tail_size;
218
- PutVarint64(&varint_tail_size, f.tail_size);
219
- PutLengthPrefixedSlice(dst, Slice(varint_tail_size));
220
- }
221
- if (!f.user_defined_timestamps_persisted) {
222
- // The default value for the flag is true, it's only explicitly persisted
223
- // when it's false. We are putting 0 as the value here to signal false
224
- // (i.e. UDTS not persisted).
225
- PutVarint32(dst, NewFileCustomTag::kUserDefinedTimestampsPersisted);
226
- char p = static_cast<char>(0);
227
- PutLengthPrefixedSlice(dst, Slice(&p, 1));
228
- }
229
- TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:NewFile4:CustomizeFields",
230
- dst);
231
-
232
- PutVarint32(dst, NewFileCustomTag::kTerminate);
115
+ EncodeToNewFile4(f, new_files_[i].first, ts_sz.value(),
116
+ has_min_log_number_to_keep_, min_log_number_to_keep_,
117
+ min_log_num_written, dst);
233
118
  }
234
119
 
235
120
  for (const auto& blob_file_addition : blob_file_additions_) {
@@ -288,9 +173,142 @@ bool VersionEdit::EncodeTo(std::string* dst,
288
173
  char p = static_cast<char>(persist_user_defined_timestamps_);
289
174
  PutLengthPrefixedSlice(dst, Slice(&p, 1));
290
175
  }
176
+
177
+ if (HasSubcompactionProgress()) {
178
+ PutVarint32(dst, kSubcompactionProgress);
179
+ std::string progress_data;
180
+ subcompaction_progress_.EncodeTo(&progress_data);
181
+ PutLengthPrefixedSlice(dst, progress_data);
182
+ }
183
+
291
184
  return true;
292
185
  }
293
186
 
187
+ void VersionEdit::EncodeToNewFile4(const FileMetaData& f, int level,
188
+ size_t ts_sz,
189
+ bool has_min_log_number_to_keep,
190
+ uint64_t min_log_number_to_keep,
191
+ bool& min_log_num_written,
192
+ std::string* dst) {
193
+ PutVarint32(dst, kNewFile4);
194
+ PutVarint32Varint64(dst, level, f.fd.GetNumber());
195
+ PutVarint64(dst, f.fd.GetFileSize());
196
+ EncodeFileBoundaries(dst, f, ts_sz);
197
+ PutVarint64Varint64(dst, f.fd.smallest_seqno, f.fd.largest_seqno);
198
+ // Customized fields' format:
199
+ // +-----------------------------+
200
+ // | 1st field's tag (varint32) |
201
+ // +-----------------------------+
202
+ // | 1st field's size (varint32) |
203
+ // +-----------------------------+
204
+ // | bytes for 1st field |
205
+ // | (based on size decoded) |
206
+ // +-----------------------------+
207
+ // | |
208
+ // | ...... |
209
+ // | |
210
+ // +-----------------------------+
211
+ // | last field's size (varint32)|
212
+ // +-----------------------------+
213
+ // | bytes for last field |
214
+ // | (based on size decoded) |
215
+ // +-----------------------------+
216
+ // | terminating tag (varint32) |
217
+ // +-----------------------------+
218
+ //
219
+ // Customized encoding for fields:
220
+ // tag kPathId: 1 byte as path_id
221
+ // tag kNeedCompaction:
222
+ // now only can take one char value 1 indicating need-compaction
223
+ //
224
+ PutVarint32(dst, NewFileCustomTag::kOldestAncesterTime);
225
+ std::string varint_oldest_ancester_time;
226
+ PutVarint64(&varint_oldest_ancester_time, f.oldest_ancester_time);
227
+ TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:VarintOldestAncesterTime",
228
+ &varint_oldest_ancester_time);
229
+ PutLengthPrefixedSlice(dst, Slice(varint_oldest_ancester_time));
230
+
231
+ PutVarint32(dst, NewFileCustomTag::kFileCreationTime);
232
+ std::string varint_file_creation_time;
233
+ PutVarint64(&varint_file_creation_time, f.file_creation_time);
234
+ TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:VarintFileCreationTime",
235
+ &varint_file_creation_time);
236
+ PutLengthPrefixedSlice(dst, Slice(varint_file_creation_time));
237
+
238
+ PutVarint32(dst, NewFileCustomTag::kEpochNumber);
239
+ std::string varint_epoch_number;
240
+ PutVarint64(&varint_epoch_number, f.epoch_number);
241
+ PutLengthPrefixedSlice(dst, Slice(varint_epoch_number));
242
+
243
+ if (f.file_checksum_func_name != kUnknownFileChecksumFuncName) {
244
+ PutVarint32(dst, NewFileCustomTag::kFileChecksum);
245
+ PutLengthPrefixedSlice(dst, Slice(f.file_checksum));
246
+
247
+ PutVarint32(dst, NewFileCustomTag::kFileChecksumFuncName);
248
+ PutLengthPrefixedSlice(dst, Slice(f.file_checksum_func_name));
249
+ }
250
+
251
+ if (f.fd.GetPathId() != 0) {
252
+ PutVarint32(dst, NewFileCustomTag::kPathId);
253
+ char p = static_cast<char>(f.fd.GetPathId());
254
+ PutLengthPrefixedSlice(dst, Slice(&p, 1));
255
+ }
256
+ if (f.temperature != Temperature::kUnknown) {
257
+ PutVarint32(dst, NewFileCustomTag::kTemperature);
258
+ char p = static_cast<char>(f.temperature);
259
+ PutLengthPrefixedSlice(dst, Slice(&p, 1));
260
+ }
261
+ if (f.marked_for_compaction) {
262
+ PutVarint32(dst, NewFileCustomTag::kNeedCompaction);
263
+ char p = static_cast<char>(1);
264
+ PutLengthPrefixedSlice(dst, Slice(&p, 1));
265
+ }
266
+ if (has_min_log_number_to_keep && !min_log_num_written) {
267
+ PutVarint32(dst, NewFileCustomTag::kMinLogNumberToKeepHack);
268
+ std::string varint_log_number;
269
+ PutFixed64(&varint_log_number, min_log_number_to_keep);
270
+ PutLengthPrefixedSlice(dst, Slice(varint_log_number));
271
+ min_log_num_written = true;
272
+ }
273
+ if (f.oldest_blob_file_number != kInvalidBlobFileNumber) {
274
+ PutVarint32(dst, NewFileCustomTag::kOldestBlobFileNumber);
275
+ std::string oldest_blob_file_number;
276
+ PutVarint64(&oldest_blob_file_number, f.oldest_blob_file_number);
277
+ PutLengthPrefixedSlice(dst, Slice(oldest_blob_file_number));
278
+ }
279
+ UniqueId64x2 unique_id = f.unique_id;
280
+ TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:UniqueId", &unique_id);
281
+ if (unique_id != kNullUniqueId64x2) {
282
+ PutVarint32(dst, NewFileCustomTag::kUniqueId);
283
+ std::string unique_id_str = EncodeUniqueIdBytes(&unique_id);
284
+ PutLengthPrefixedSlice(dst, Slice(unique_id_str));
285
+ }
286
+ if (f.compensated_range_deletion_size) {
287
+ PutVarint32(dst, NewFileCustomTag::kCompensatedRangeDeletionSize);
288
+ std::string compensated_range_deletion_size;
289
+ PutVarint64(&compensated_range_deletion_size,
290
+ f.compensated_range_deletion_size);
291
+ PutLengthPrefixedSlice(dst, Slice(compensated_range_deletion_size));
292
+ }
293
+ if (f.tail_size) {
294
+ PutVarint32(dst, NewFileCustomTag::kTailSize);
295
+ std::string varint_tail_size;
296
+ PutVarint64(&varint_tail_size, f.tail_size);
297
+ PutLengthPrefixedSlice(dst, Slice(varint_tail_size));
298
+ }
299
+ if (!f.user_defined_timestamps_persisted) {
300
+ // The default value for the flag is true, it's only explicitly persisted
301
+ // when it's false. We are putting 0 as the value here to signal false
302
+ // (i.e. UDTS not persisted).
303
+ PutVarint32(dst, NewFileCustomTag::kUserDefinedTimestampsPersisted);
304
+ char p = static_cast<char>(0);
305
+ PutLengthPrefixedSlice(dst, Slice(&p, 1));
306
+ }
307
+ TEST_SYNC_POINT_CALLBACK("VersionEdit::EncodeTo:NewFile4:CustomizeFields",
308
+ dst);
309
+
310
+ PutVarint32(dst, NewFileCustomTag::kTerminate);
311
+ }
294
312
  static bool GetInternalKey(Slice* input, InternalKey* dst) {
295
313
  Slice str;
296
314
  if (GetLengthPrefixedSlice(input, &str)) {
@@ -301,12 +319,12 @@ static bool GetInternalKey(Slice* input, InternalKey* dst) {
301
319
  }
302
320
  }
303
321
 
304
- bool VersionEdit::GetLevel(Slice* input, int* level, const char** /*msg*/) {
322
+ bool VersionEdit::GetLevel(Slice* input, int* level, int& max_level) {
305
323
  uint32_t v = 0;
306
324
  if (GetVarint32(input, &v)) {
307
325
  *level = v;
308
- if (max_level_ < *level) {
309
- max_level_ = *level;
326
+ if (max_level < *level) {
327
+ max_level = *level;
310
328
  }
311
329
  return true;
312
330
  } else {
@@ -314,16 +332,18 @@ bool VersionEdit::GetLevel(Slice* input, int* level, const char** /*msg*/) {
314
332
  }
315
333
  }
316
334
 
317
- const char* VersionEdit::DecodeNewFile4From(Slice* input) {
318
- const char* msg = nullptr;
335
+ const char* VersionEdit::DecodeNewFile4From(Slice* input, int& max_level,
336
+ uint64_t& min_log_number_to_keep,
337
+ bool& has_min_log_number_to_keep,
338
+ NewFiles& new_files,
339
+ FileMetaData& f) {
319
340
  int level = 0;
320
- FileMetaData f;
321
341
  uint64_t number = 0;
322
342
  uint32_t path_id = 0;
323
343
  uint64_t file_size = 0;
324
344
  SequenceNumber smallest_seqno = 0;
325
345
  SequenceNumber largest_seqno = kMaxSequenceNumber;
326
- if (GetLevel(input, &level, &msg) && GetVarint64(input, &number) &&
346
+ if (GetLevel(input, &level, max_level) && GetVarint64(input, &number) &&
327
347
  GetVarint64(input, &file_size) && GetInternalKey(input, &f.smallest) &&
328
348
  GetInternalKey(input, &f.largest) &&
329
349
  GetVarint64(input, &smallest_seqno) &&
@@ -381,10 +401,10 @@ const char* VersionEdit::DecodeNewFile4From(Slice* input) {
381
401
  case kMinLogNumberToKeepHack:
382
402
  // This is a hack to encode kMinLogNumberToKeep in a
383
403
  // forward-compatible fashion.
384
- if (!GetFixed64(&field, &min_log_number_to_keep_)) {
404
+ if (!GetFixed64(&field, &min_log_number_to_keep)) {
385
405
  return "deleted log number malformatted";
386
406
  }
387
- has_min_log_number_to_keep_ = true;
407
+ has_min_log_number_to_keep = true;
388
408
  break;
389
409
  case kOldestBlobFileNumber:
390
410
  if (!GetVarint64(&field, &f.oldest_blob_file_number)) {
@@ -436,13 +456,12 @@ const char* VersionEdit::DecodeNewFile4From(Slice* input) {
436
456
  }
437
457
  f.fd =
438
458
  FileDescriptor(number, path_id, file_size, smallest_seqno, largest_seqno);
439
- new_files_.push_back(std::make_pair(level, f));
459
+ new_files.emplace_back(level, f);
440
460
  return nullptr;
441
461
  }
442
462
 
443
463
  void VersionEdit::EncodeFileBoundaries(std::string* dst,
444
- const FileMetaData& meta,
445
- size_t ts_sz) const {
464
+ const FileMetaData& meta, size_t ts_sz) {
446
465
  if (ts_sz == 0 || meta.user_defined_timestamps_persisted) {
447
466
  PutLengthPrefixedSlice(dst, meta.smallest.Encode());
448
467
  PutLengthPrefixedSlice(dst, meta.largest.Encode());
@@ -545,7 +564,8 @@ Status VersionEdit::DecodeFrom(const Slice& src) {
545
564
  break;
546
565
 
547
566
  case kCompactCursor:
548
- if (GetLevel(&input, &level, &msg) && GetInternalKey(&input, &key)) {
567
+ if (GetLevel(&input, &level, max_level_) &&
568
+ GetInternalKey(&input, &key)) {
549
569
  // Here we re-use the output format of compact pointer in LevelDB
550
570
  // to persist compact_cursors_
551
571
  compact_cursors_.push_back(std::make_pair(level, key));
@@ -558,7 +578,8 @@ Status VersionEdit::DecodeFrom(const Slice& src) {
558
578
 
559
579
  case kDeletedFile: {
560
580
  uint64_t number = 0;
561
- if (GetLevel(&input, &level, &msg) && GetVarint64(&input, &number)) {
581
+ if (GetLevel(&input, &level, max_level_) &&
582
+ GetVarint64(&input, &number)) {
562
583
  deleted_files_.insert(std::make_pair(level, number));
563
584
  } else {
564
585
  if (!msg) {
@@ -571,8 +592,8 @@ Status VersionEdit::DecodeFrom(const Slice& src) {
571
592
  case kNewFile: {
572
593
  uint64_t number = 0;
573
594
  uint64_t file_size = 0;
574
- if (GetLevel(&input, &level, &msg) && GetVarint64(&input, &number) &&
575
- GetVarint64(&input, &file_size) &&
595
+ if (GetLevel(&input, &level, max_level_) &&
596
+ GetVarint64(&input, &number) && GetVarint64(&input, &file_size) &&
576
597
  GetInternalKey(&input, &f.smallest) &&
577
598
  GetInternalKey(&input, &f.largest)) {
578
599
  f.fd = FileDescriptor(number, 0, file_size);
@@ -589,8 +610,8 @@ Status VersionEdit::DecodeFrom(const Slice& src) {
589
610
  uint64_t file_size = 0;
590
611
  SequenceNumber smallest_seqno = 0;
591
612
  SequenceNumber largest_seqno = kMaxSequenceNumber;
592
- if (GetLevel(&input, &level, &msg) && GetVarint64(&input, &number) &&
593
- GetVarint64(&input, &file_size) &&
613
+ if (GetLevel(&input, &level, max_level_) &&
614
+ GetVarint64(&input, &number) && GetVarint64(&input, &file_size) &&
594
615
  GetInternalKey(&input, &f.smallest) &&
595
616
  GetInternalKey(&input, &f.largest) &&
596
617
  GetVarint64(&input, &smallest_seqno) &&
@@ -612,8 +633,9 @@ Status VersionEdit::DecodeFrom(const Slice& src) {
612
633
  uint64_t file_size = 0;
613
634
  SequenceNumber smallest_seqno = 0;
614
635
  SequenceNumber largest_seqno = kMaxSequenceNumber;
615
- if (GetLevel(&input, &level, &msg) && GetVarint64(&input, &number) &&
616
- GetVarint32(&input, &path_id) && GetVarint64(&input, &file_size) &&
636
+ if (GetLevel(&input, &level, max_level_) &&
637
+ GetVarint64(&input, &number) && GetVarint32(&input, &path_id) &&
638
+ GetVarint64(&input, &file_size) &&
617
639
  GetInternalKey(&input, &f.smallest) &&
618
640
  GetInternalKey(&input, &f.largest) &&
619
641
  GetVarint64(&input, &smallest_seqno) &&
@@ -630,7 +652,10 @@ Status VersionEdit::DecodeFrom(const Slice& src) {
630
652
  }
631
653
 
632
654
  case kNewFile4: {
633
- msg = DecodeNewFile4From(&input);
655
+ FileMetaData ignored_file;
656
+ msg = DecodeNewFile4From(&input, max_level_, min_log_number_to_keep_,
657
+ has_min_log_number_to_keep_, new_files_,
658
+ ignored_file);
634
659
  break;
635
660
  }
636
661
 
@@ -767,6 +792,23 @@ Status VersionEdit::DecodeFrom(const Slice& src) {
767
792
  }
768
793
  break;
769
794
 
795
+ case kSubcompactionProgress: {
796
+ Slice encoded;
797
+ if (!GetLengthPrefixedSlice(&input, &encoded)) {
798
+ msg = "SubcompactionProgress not prefixed by length";
799
+ break;
800
+ }
801
+
802
+ SubcompactionProgress progress;
803
+ Status s = progress.DecodeFrom(&encoded);
804
+ if (!s.ok()) {
805
+ return s;
806
+ }
807
+
808
+ SetSubcompactionProgress(progress);
809
+ break;
810
+ }
811
+
770
812
  default:
771
813
  if (tag & kTagSafeIgnoreMask) {
772
814
  // Tag from future which can be safely ignored.
@@ -933,6 +975,10 @@ std::string VersionEdit::DebugString(bool hex_key) const {
933
975
  r.append("\n FullHistoryTsLow: ");
934
976
  r.append(Slice(full_history_ts_low_).ToString(hex_key));
935
977
  }
978
+ if (HasSubcompactionProgress()) {
979
+ r.append("\n SubcompactionProgress: ");
980
+ r.append(subcompaction_progress_.ToString());
981
+ }
936
982
  r.append("\n}\n");
937
983
  return r;
938
984
  }
@@ -1082,9 +1128,301 @@ std::string VersionEdit::DebugJSON(int edit_num, bool hex_key) const {
1082
1128
  jw << "FullHistoryTsLow" << Slice(full_history_ts_low_).ToString(hex_key);
1083
1129
  }
1084
1130
 
1131
+ if (HasSubcompactionProgress()) {
1132
+ jw << "SubcompactionProgress" << subcompaction_progress_.ToString();
1133
+ }
1134
+
1085
1135
  jw.EndObject();
1086
1136
 
1087
1137
  return jw.Get();
1088
1138
  }
1089
1139
 
1140
+ void SubcompactionProgressPerLevel::EncodeTo(std::string* dst) const {
1141
+ if (num_processed_output_records_ > 0) {
1142
+ PutVarint32(
1143
+ dst,
1144
+ SubcompactionProgressPerLevelCustomTag::kNumProcessedOutputRecords);
1145
+ std::string varint_records;
1146
+ PutVarint64(&varint_records, num_processed_output_records_);
1147
+ PutLengthPrefixedSlice(dst, varint_records);
1148
+ }
1149
+
1150
+ if (!output_files_.empty()) {
1151
+ PutVarint32(dst, SubcompactionProgressPerLevelCustomTag::kOutputFilesDelta);
1152
+ std::string files_data;
1153
+ EncodeOutputFiles(&files_data);
1154
+ PutLengthPrefixedSlice(dst, files_data);
1155
+ }
1156
+
1157
+ PutVarint32(dst, SubcompactionProgressPerLevelCustomTag::
1158
+ kSubcompactionProgressPerLevelTerminate);
1159
+ }
1160
+
1161
+ Status SubcompactionProgressPerLevel::DecodeFrom(Slice* input) {
1162
+ Clear();
1163
+
1164
+ while (true) {
1165
+ uint32_t tag = 0;
1166
+ if (!GetVarint32(input, &tag)) {
1167
+ return Status::Corruption("SubcompactionProgressPerLevel", "tag error");
1168
+ }
1169
+
1170
+ if (tag == SubcompactionProgressPerLevelCustomTag::
1171
+ kSubcompactionProgressPerLevelTerminate) {
1172
+ break;
1173
+ }
1174
+
1175
+ Slice field;
1176
+ if (!GetLengthPrefixedSlice(input, &field)) {
1177
+ return Status::Corruption("SubcompactionProgressPerLevel",
1178
+ "field length prefixed slice error");
1179
+ }
1180
+
1181
+ switch (tag) {
1182
+ case SubcompactionProgressPerLevelCustomTag::kNumProcessedOutputRecords: {
1183
+ if (!GetVarint64(&field, &num_processed_output_records_)) {
1184
+ return Status::Corruption("SubcompactionProgressPerLevel",
1185
+ "invalid num_processed_output_records_");
1186
+ }
1187
+ break;
1188
+ }
1189
+
1190
+ case SubcompactionProgressPerLevelCustomTag::kOutputFilesDelta: {
1191
+ Status s = DecodeOutputFiles(&field, output_files_);
1192
+ if (!s.ok()) {
1193
+ return s;
1194
+ }
1195
+ break;
1196
+ }
1197
+
1198
+ default:
1199
+ // Forward compatibility: Handle unknown tags
1200
+ if ((tag & SubcompactionProgressPerLevelCustomTag::
1201
+ kSubcompactionProgressPerLevelCustomTagSafeIgnoreMask) !=
1202
+ 0) {
1203
+ break;
1204
+ } else {
1205
+ return Status::NotSupported("SubcompactionProgress",
1206
+ "unsupported critical custom field");
1207
+ }
1208
+ }
1209
+ }
1210
+
1211
+ return Status::OK();
1212
+ }
1213
+
1214
+ void SubcompactionProgressPerLevel::EncodeOutputFiles(std::string* dst) const {
1215
+ size_t new_files_count =
1216
+ output_files_.size() > last_persisted_output_files_count_
1217
+ ? output_files_.size() - last_persisted_output_files_count_
1218
+ : 0;
1219
+
1220
+ assert(new_files_count > 0);
1221
+
1222
+ PutVarint32(dst, static_cast<uint32_t>(new_files_count));
1223
+
1224
+ for (size_t i = last_persisted_output_files_count_; i < output_files_.size();
1225
+ ++i) {
1226
+ std::string file_dst;
1227
+ bool ignored_min_log_written = false;
1228
+
1229
+ VersionEdit::EncodeToNewFile4(
1230
+ output_files_[i], -1 /* level */, 0 /* ts_sz */,
1231
+ false /* has_min_log_number_to_keep */, 0 /* min_log_number_to_keep */,
1232
+ ignored_min_log_written, &file_dst);
1233
+
1234
+ PutLengthPrefixedSlice(dst, file_dst);
1235
+ }
1236
+ }
1237
+
1238
+ Status SubcompactionProgressPerLevel::DecodeOutputFiles(
1239
+ Slice* input, autovector<FileMetaData>& output_files) {
1240
+ uint32_t new_file_count = 0;
1241
+ if (!GetVarint32(input, &new_file_count)) {
1242
+ return Status::Corruption("SubcompactionProgressPerLevel",
1243
+ "new output file count");
1244
+ }
1245
+
1246
+ assert(output_files.size() == 0);
1247
+
1248
+ output_files.reserve(new_file_count);
1249
+
1250
+ for (uint32_t i = 0; i < new_file_count; ++i) {
1251
+ Slice file_input;
1252
+ if (!GetLengthPrefixedSlice(input, &file_input)) {
1253
+ return Status::Corruption("SubcompactionProgressPerLevel",
1254
+ "output file metadata");
1255
+ }
1256
+
1257
+ uint32_t tag = 0;
1258
+ if (!GetVarint32(&file_input, &tag) || tag != kNewFile4) {
1259
+ return Status::Corruption("SubcompactionProgressPerLevel",
1260
+ "expected kNewFile4 tag");
1261
+ }
1262
+
1263
+ int ignored_max_level = -1;
1264
+ uint64_t ignored_min_log_number_to_keep = 0;
1265
+ bool ignored_has_min_log_number_to_keep = false;
1266
+ VersionEdit::NewFiles ignored_new_files;
1267
+ FileMetaData file;
1268
+
1269
+ const char* err = VersionEdit::DecodeNewFile4From(
1270
+ &file_input, ignored_max_level, ignored_min_log_number_to_keep,
1271
+ ignored_has_min_log_number_to_keep, ignored_new_files, file);
1272
+
1273
+ if (err != nullptr) {
1274
+ return Status::Corruption("SubcompactionProgressPerLevel", err);
1275
+ }
1276
+
1277
+ output_files.push_back(std::move(file));
1278
+ }
1279
+
1280
+ return Status::OK();
1281
+ }
1282
+
1283
+ void SubcompactionProgress::EncodeTo(std::string* dst) const {
1284
+ if (!next_internal_key_to_compact.empty()) {
1285
+ PutVarint32(dst, SubcompactionProgressCustomTag::kNextInternalKeyToCompact);
1286
+ PutLengthPrefixedSlice(dst, next_internal_key_to_compact);
1287
+ }
1288
+
1289
+ PutVarint32(dst, SubcompactionProgressCustomTag::kNumProcessedInputRecords);
1290
+ std::string varint_records;
1291
+ PutVarint64(&varint_records, num_processed_input_records);
1292
+ PutLengthPrefixedSlice(dst, varint_records);
1293
+
1294
+ if (output_level_progress.GetOutputFiles().size() >
1295
+ output_level_progress.GetLastPersistedOutputFilesCount()) {
1296
+ PutVarint32(dst, SubcompactionProgressCustomTag::kOutputLevelProgress);
1297
+ std::string level_progress_data;
1298
+ output_level_progress.EncodeTo(&level_progress_data);
1299
+ PutLengthPrefixedSlice(dst, level_progress_data);
1300
+ }
1301
+
1302
+ if (proximal_output_level_progress.GetOutputFiles().size() >
1303
+ proximal_output_level_progress.GetLastPersistedOutputFilesCount()) {
1304
+ PutVarint32(dst,
1305
+ SubcompactionProgressCustomTag::kProximalOutputLevelProgress);
1306
+ std::string level_progress_data;
1307
+ proximal_output_level_progress.EncodeTo(&level_progress_data);
1308
+ PutLengthPrefixedSlice(dst, level_progress_data);
1309
+ }
1310
+ PutVarint32(dst,
1311
+ SubcompactionProgressCustomTag::kSubcompactionProgressTerminate);
1312
+ }
1313
+
1314
+ Status SubcompactionProgress::DecodeFrom(Slice* input) {
1315
+ Clear();
1316
+
1317
+ while (true) {
1318
+ uint32_t custom_tag = 0;
1319
+ if (!GetVarint32(input, &custom_tag)) {
1320
+ return Status::Corruption("SubcompactionProgress",
1321
+ "custom field tag error");
1322
+ }
1323
+
1324
+ if (custom_tag ==
1325
+ SubcompactionProgressCustomTag::kSubcompactionProgressTerminate) {
1326
+ break;
1327
+ }
1328
+
1329
+ Slice field;
1330
+ if (!GetLengthPrefixedSlice(input, &field)) {
1331
+ return Status::Corruption("SubcompactionProgress",
1332
+ "custom field length prefixed slice error");
1333
+ }
1334
+
1335
+ switch (custom_tag) {
1336
+ case SubcompactionProgressCustomTag::kNextInternalKeyToCompact:
1337
+ next_internal_key_to_compact = field.ToString();
1338
+ break;
1339
+
1340
+ case SubcompactionProgressCustomTag::kNumProcessedInputRecords:
1341
+ if (!GetVarint64(&field, &num_processed_input_records)) {
1342
+ return Status::Corruption("SubcompactionProgress",
1343
+ "invalid num_processed_input_records");
1344
+ }
1345
+ break;
1346
+
1347
+ case SubcompactionProgressCustomTag::kOutputLevelProgress: {
1348
+ Status s = output_level_progress.DecodeFrom(&field);
1349
+ if (!s.ok()) {
1350
+ return s;
1351
+ }
1352
+ break;
1353
+ }
1354
+
1355
+ case SubcompactionProgressCustomTag::kProximalOutputLevelProgress: {
1356
+ Status s = proximal_output_level_progress.DecodeFrom(&field);
1357
+ if (!s.ok()) {
1358
+ return s;
1359
+ }
1360
+ break;
1361
+ }
1362
+
1363
+ default:
1364
+ if ((custom_tag & SubcompactionProgressCustomTag::
1365
+ kSubcompactionProgressCustomTagSafeIgnoreMask) !=
1366
+ 0) {
1367
+ break;
1368
+ } else {
1369
+ return Status::NotSupported("SubcompactionProgress",
1370
+ "unsupported critical custom field");
1371
+ }
1372
+ }
1373
+ }
1374
+
1375
+ return Status::OK();
1376
+ }
1377
+
1378
+ bool SubcompactionProgressBuilder::ProcessVersionEdit(const VersionEdit& edit) {
1379
+ if (!edit.HasSubcompactionProgress()) {
1380
+ return false;
1381
+ }
1382
+
1383
+ const SubcompactionProgress& progress = edit.GetSubcompactionProgress();
1384
+
1385
+ MergeDeltaProgress(progress);
1386
+
1387
+ has_subcompaction_progress_ = true;
1388
+
1389
+ return true;
1390
+ }
1391
+
1392
+ void SubcompactionProgressBuilder::MergeDeltaProgress(
1393
+ const SubcompactionProgress& delta_progress) {
1394
+ accumulated_subcompaction_progress_.next_internal_key_to_compact =
1395
+ delta_progress.next_internal_key_to_compact;
1396
+
1397
+ accumulated_subcompaction_progress_.num_processed_input_records =
1398
+ delta_progress.num_processed_input_records;
1399
+
1400
+ MaybeMergeDeltaProgressPerLevel(
1401
+ accumulated_subcompaction_progress_.output_level_progress,
1402
+ delta_progress.output_level_progress);
1403
+
1404
+ MaybeMergeDeltaProgressPerLevel(
1405
+ accumulated_subcompaction_progress_.proximal_output_level_progress,
1406
+ delta_progress.proximal_output_level_progress);
1407
+ }
1408
+
1409
+ void SubcompactionProgressBuilder::MaybeMergeDeltaProgressPerLevel(
1410
+ SubcompactionProgressPerLevel& accumulated_level_progress,
1411
+ const SubcompactionProgressPerLevel& delta_level_progress) {
1412
+ const auto& delta_files = delta_level_progress.GetOutputFiles();
1413
+ if (delta_files.empty()) {
1414
+ return;
1415
+ }
1416
+ for (const FileMetaData& file : delta_files) {
1417
+ accumulated_level_progress.AddToOutputFiles(file); // Stored as copy
1418
+ }
1419
+
1420
+ accumulated_level_progress.SetNumProcessedOutputRecords(
1421
+ delta_level_progress.GetNumProcessedOutputRecords());
1422
+ }
1423
+
1424
+ void SubcompactionProgressBuilder::Clear() {
1425
+ accumulated_subcompaction_progress_.Clear();
1426
+ has_subcompaction_progress_ = false;
1427
+ }
1090
1428
  } // namespace ROCKSDB_NAMESPACE