@nxtedition/rocksdb 13.1.4 → 13.2.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 (237) hide show
  1. package/binding.cc +43 -16
  2. package/deps/rocksdb/rocksdb/{TARGETS → BUCK} +27 -0
  3. package/deps/rocksdb/rocksdb/CMakeLists.txt +3 -1
  4. package/deps/rocksdb/rocksdb/Makefile +2 -2
  5. package/deps/rocksdb/rocksdb/cache/cache.cc +3 -1
  6. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.h +2 -0
  7. package/deps/rocksdb/rocksdb/db/attribute_group_iterator_impl.h +34 -9
  8. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +7 -6
  9. package/deps/rocksdb/rocksdb/db/blob/blob_source.h +5 -1
  10. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +22 -14
  11. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +149 -0
  12. package/deps/rocksdb/rocksdb/db/builder.cc +13 -24
  13. package/deps/rocksdb/rocksdb/db/coalescing_iterator.h +35 -10
  14. package/deps/rocksdb/rocksdb/db/column_family.cc +21 -10
  15. package/deps/rocksdb/rocksdb/db/column_family.h +15 -8
  16. package/deps/rocksdb/rocksdb/db/column_family_test.cc +98 -7
  17. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +126 -16
  18. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +51 -5
  19. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +2 -2
  20. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +2 -8
  21. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +24 -0
  22. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +52 -22
  23. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +9 -7
  24. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +36 -9
  25. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +6 -0
  26. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +30 -17
  27. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +26 -23
  28. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +43 -33
  29. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +6 -5
  30. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +19 -9
  31. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +6 -5
  32. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +632 -411
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +171 -51
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +7 -5
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +37 -10
  36. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +51 -11
  37. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +10 -3
  38. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +350 -154
  39. package/deps/rocksdb/rocksdb/db/convenience.cc +1 -1
  40. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +62 -27
  41. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +68 -1
  42. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +91 -0
  43. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +134 -70
  44. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +71 -23
  45. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +43 -16
  46. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +47 -33
  47. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +27 -19
  48. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +38 -25
  49. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +3 -3
  50. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +7 -4
  51. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +258 -42
  52. package/deps/rocksdb/rocksdb/db/db_io_failure_test.cc +161 -9
  53. package/deps/rocksdb/rocksdb/db/db_iter.cc +118 -86
  54. package/deps/rocksdb/rocksdb/db/db_iter.h +44 -17
  55. package/deps/rocksdb/rocksdb/db/db_options_test.cc +27 -6
  56. package/deps/rocksdb/rocksdb/db/db_test.cc +48 -16
  57. package/deps/rocksdb/rocksdb/db/db_test2.cc +60 -15
  58. package/deps/rocksdb/rocksdb/db/db_test_util.cc +97 -44
  59. package/deps/rocksdb/rocksdb/db/db_test_util.h +7 -1
  60. package/deps/rocksdb/rocksdb/db/dbformat.cc +15 -5
  61. package/deps/rocksdb/rocksdb/db/dbformat.h +137 -55
  62. package/deps/rocksdb/rocksdb/db/event_helpers.cc +1 -0
  63. package/deps/rocksdb/rocksdb/db/experimental.cc +54 -0
  64. package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +663 -8
  65. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +152 -91
  66. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +134 -11
  67. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +55 -9
  68. package/deps/rocksdb/rocksdb/db/flush_job.cc +52 -29
  69. package/deps/rocksdb/rocksdb/db/flush_job.h +5 -3
  70. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +18 -12
  71. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +23 -29
  72. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +3 -2
  73. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +2 -0
  74. package/deps/rocksdb/rocksdb/db/internal_stats.cc +9 -6
  75. package/deps/rocksdb/rocksdb/db/internal_stats.h +54 -0
  76. package/deps/rocksdb/rocksdb/db/job_context.h +1 -1
  77. package/deps/rocksdb/rocksdb/db/log_reader.cc +6 -7
  78. package/deps/rocksdb/rocksdb/db/manifest_ops.cc +47 -0
  79. package/deps/rocksdb/rocksdb/db/manifest_ops.h +20 -0
  80. package/deps/rocksdb/rocksdb/db/memtable.cc +165 -64
  81. package/deps/rocksdb/rocksdb/db/memtable.h +422 -243
  82. package/deps/rocksdb/rocksdb/db/memtable_list.cc +99 -68
  83. package/deps/rocksdb/rocksdb/db/memtable_list.h +63 -38
  84. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +28 -25
  85. package/deps/rocksdb/rocksdb/db/multi_cf_iterator_impl.h +118 -60
  86. package/deps/rocksdb/rocksdb/db/multi_cf_iterator_test.cc +344 -89
  87. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.h +2 -3
  88. package/deps/rocksdb/rocksdb/db/repair.cc +15 -14
  89. package/deps/rocksdb/rocksdb/db/repair_test.cc +0 -13
  90. package/deps/rocksdb/rocksdb/db/snapshot_checker.h +7 -0
  91. package/deps/rocksdb/rocksdb/db/table_cache.cc +62 -65
  92. package/deps/rocksdb/rocksdb/db/table_cache.h +70 -76
  93. package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +5 -6
  94. package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +1 -1
  95. package/deps/rocksdb/rocksdb/db/transaction_log_impl.cc +8 -7
  96. package/deps/rocksdb/rocksdb/db/version_builder.cc +17 -19
  97. package/deps/rocksdb/rocksdb/db/version_builder.h +13 -12
  98. package/deps/rocksdb/rocksdb/db/version_edit.h +30 -0
  99. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +3 -5
  100. package/deps/rocksdb/rocksdb/db/version_set.cc +89 -129
  101. package/deps/rocksdb/rocksdb/db/version_set.h +12 -4
  102. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +1 -2
  103. package/deps/rocksdb/rocksdb/db/version_set_test.cc +12 -8
  104. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +0 -15
  105. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +0 -2
  106. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization_test.cc +9 -7
  107. package/deps/rocksdb/rocksdb/db/wide/wide_columns_helper.cc +0 -8
  108. package/deps/rocksdb/rocksdb/db/wide/wide_columns_helper.h +28 -2
  109. package/deps/rocksdb/rocksdb/db/write_batch.cc +32 -10
  110. package/deps/rocksdb/rocksdb/db/write_batch_internal.h +9 -0
  111. package/deps/rocksdb/rocksdb/db/write_batch_test.cc +2 -1
  112. package/deps/rocksdb/rocksdb/db/write_thread.cc +3 -1
  113. package/deps/rocksdb/rocksdb/db/write_thread.h +6 -2
  114. package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +15 -0
  115. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +7 -0
  116. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +4 -0
  117. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +18 -2
  118. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +100 -22
  119. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +15 -4
  120. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +34 -8
  121. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +223 -78
  122. package/deps/rocksdb/rocksdb/env/file_system.cc +6 -1
  123. package/deps/rocksdb/rocksdb/env/fs_posix.cc +53 -0
  124. package/deps/rocksdb/rocksdb/env/io_posix.cc +63 -17
  125. package/deps/rocksdb/rocksdb/env/io_posix.h +30 -1
  126. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +132 -48
  127. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +92 -24
  128. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +727 -109
  129. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +3 -4
  130. package/deps/rocksdb/rocksdb/file/random_access_file_reader.h +1 -1
  131. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +8 -0
  132. package/deps/rocksdb/rocksdb/include/rocksdb/attribute_groups.h +20 -1
  133. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_job_stats.h +9 -0
  134. package/deps/rocksdb/rocksdb/include/rocksdb/configurable.h +9 -5
  135. package/deps/rocksdb/rocksdb/include/rocksdb/convenience.h +2 -0
  136. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +10 -2
  137. package/deps/rocksdb/rocksdb/include/rocksdb/env.h +1 -0
  138. package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +7 -0
  139. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +34 -37
  140. package/deps/rocksdb/rocksdb/include/rocksdb/iterator_base.h +21 -0
  141. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +56 -28
  142. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +3 -0
  143. package/deps/rocksdb/rocksdb/include/rocksdb/table.h +36 -28
  144. package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +11 -0
  145. package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +1 -0
  146. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_type.h +84 -60
  147. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/secondary_index.h +102 -0
  148. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/table_properties_collectors.h +89 -2
  149. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction.h +32 -0
  150. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db.h +30 -1
  151. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/write_batch_with_index.h +23 -2
  152. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
  153. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +2 -0
  154. package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +79 -21
  155. package/deps/rocksdb/rocksdb/memtable/skiplist.h +41 -18
  156. package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +1 -5
  157. package/deps/rocksdb/rocksdb/memtable/wbwi_memtable.cc +169 -0
  158. package/deps/rocksdb/rocksdb/memtable/wbwi_memtable.h +400 -0
  159. package/deps/rocksdb/rocksdb/monitoring/thread_status_util_debug.cc +2 -0
  160. package/deps/rocksdb/rocksdb/options/cf_options.cc +137 -82
  161. package/deps/rocksdb/rocksdb/options/cf_options.h +18 -6
  162. package/deps/rocksdb/rocksdb/options/configurable.cc +31 -17
  163. package/deps/rocksdb/rocksdb/options/configurable_helper.h +7 -6
  164. package/deps/rocksdb/rocksdb/options/options_helper.cc +10 -8
  165. package/deps/rocksdb/rocksdb/options/options_parser.cc +74 -54
  166. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +89 -0
  167. package/deps/rocksdb/rocksdb/options/options_test.cc +112 -26
  168. package/deps/rocksdb/rocksdb/port/port.h +5 -9
  169. package/deps/rocksdb/rocksdb/src.mk +8 -0
  170. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.h +4 -0
  171. package/deps/rocksdb/rocksdb/table/block_based/block.h +1 -7
  172. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +2 -0
  173. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +62 -80
  174. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +13 -3
  175. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +16 -5
  176. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +38 -7
  177. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +12 -4
  178. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +4 -1
  179. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +4 -1
  180. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +204 -1
  181. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +3 -3
  182. package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +2 -1
  183. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_factory.h +4 -0
  184. package/deps/rocksdb/rocksdb/table/format.cc +3 -3
  185. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +4 -1
  186. package/deps/rocksdb/rocksdb/table/mock_table.cc +0 -50
  187. package/deps/rocksdb/rocksdb/table/mock_table.h +53 -0
  188. package/deps/rocksdb/rocksdb/table/plain/plain_table_factory.h +4 -0
  189. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +1 -1
  190. package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +10 -5
  191. package/deps/rocksdb/rocksdb/table/table_builder.h +3 -1
  192. package/deps/rocksdb/rocksdb/table/table_properties.cc +181 -0
  193. package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +5 -5
  194. package/deps/rocksdb/rocksdb/table/table_test.cc +71 -64
  195. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim.py +45 -45
  196. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim_test.py +35 -35
  197. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py +43 -43
  198. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +41 -4
  199. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +1 -0
  200. package/deps/rocksdb/rocksdb/tools/sst_dump_test.cc +1 -1
  201. package/deps/rocksdb/rocksdb/unreleased_history/add.sh +13 -0
  202. package/deps/rocksdb/rocksdb/util/aligned_buffer.h +24 -5
  203. package/deps/rocksdb/rocksdb/util/compaction_job_stats_impl.cc +7 -0
  204. package/deps/rocksdb/rocksdb/util/file_checksum_helper.cc +0 -52
  205. package/deps/rocksdb/rocksdb/util/file_checksum_helper.h +1 -10
  206. package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +92 -0
  207. package/deps/rocksdb/rocksdb/util/thread_operation.h +1 -0
  208. package/deps/rocksdb/rocksdb/util/udt_util.cc +50 -4
  209. package/deps/rocksdb/rocksdb/util/udt_util.h +24 -11
  210. package/deps/rocksdb/rocksdb/util/udt_util_test.cc +26 -13
  211. package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +1 -16
  212. package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +2 -0
  213. package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index.cc +214 -0
  214. package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index.h +60 -0
  215. package/deps/rocksdb/rocksdb/utilities/secondary_index/faiss_ivf_index_test.cc +124 -0
  216. package/deps/rocksdb/rocksdb/utilities/secondary_index/secondary_index_mixin.h +441 -0
  217. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_for_tiering_collector.cc +34 -3
  218. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_for_tiering_collector.h +7 -2
  219. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_test.cc +437 -0
  220. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.cc +34 -11
  221. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.h +14 -7
  222. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.cc +7 -1
  223. package/deps/rocksdb/rocksdb/utilities/transactions/snapshot_checker.cc +17 -0
  224. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +69 -0
  225. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.h +20 -0
  226. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +1290 -0
  227. package/deps/rocksdb/rocksdb/utilities/transactions/write_committed_transaction_ts_test.cc +324 -0
  228. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +18 -1
  229. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.h +8 -1
  230. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +57 -12
  231. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.cc +32 -3
  232. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +33 -2
  233. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +721 -9
  234. package/deps/rocksdb/rocksdb.gyp +2 -0
  235. package/package.json +1 -1
  236. package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
  237. package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
@@ -35,6 +35,17 @@ void BlockBasedTableIterator::SeekSecondPass(const Slice* target) {
35
35
 
36
36
  void BlockBasedTableIterator::SeekImpl(const Slice* target,
37
37
  bool async_prefetch) {
38
+ // TODO(hx235): set `seek_key_prefix_for_readahead_trimming_`
39
+ // even when `target == nullptr` that is when `SeekToFirst()` is called
40
+ if (target != nullptr && prefix_extractor_ &&
41
+ read_options_.prefix_same_as_start) {
42
+ const Slice& seek_user_key = ExtractUserKey(*target);
43
+ seek_key_prefix_for_readahead_trimming_ =
44
+ prefix_extractor_->InDomain(seek_user_key)
45
+ ? prefix_extractor_->Transform(seek_user_key).ToString()
46
+ : "";
47
+ }
48
+
38
49
  bool is_first_pass = !async_read_in_progress_;
39
50
 
40
51
  if (!is_first_pass) {
@@ -44,9 +55,9 @@ void BlockBasedTableIterator::SeekImpl(const Slice* target,
44
55
 
45
56
  ResetBlockCacheLookupVar();
46
57
 
47
- bool autotune_readaheadsize = is_first_pass &&
48
- read_options_.auto_readahead_size &&
49
- read_options_.iterate_upper_bound;
58
+ bool autotune_readaheadsize =
59
+ is_first_pass && read_options_.auto_readahead_size &&
60
+ (read_options_.iterate_upper_bound || read_options_.prefix_same_as_start);
50
61
 
51
62
  if (autotune_readaheadsize &&
52
63
  table_->get_rep()->table_options.block_cache.get() &&
@@ -778,7 +789,7 @@ void BlockBasedTableIterator::BlockCacheLookupForReadAheadSize(
778
789
 
779
790
  size_t footer = table_->get_rep()->footer.GetBlockTrailerSize();
780
791
  if (read_curr_block && !DoesContainBlockHandles() &&
781
- IsNextBlockOutOfBound()) {
792
+ IsNextBlockOutOfReadaheadBound()) {
782
793
  end_offset = index_iter_->value().handle.offset() + footer +
783
794
  index_iter_->value().handle.size();
784
795
  return;
@@ -850,7 +861,7 @@ void BlockBasedTableIterator::BlockCacheLookupForReadAheadSize(
850
861
  // If curr block's index key >= iterate_upper_bound, it
851
862
  // means all the keys in next block or above are out of
852
863
  // bound.
853
- if (IsNextBlockOutOfBound()) {
864
+ if (IsNextBlockOutOfReadaheadBound()) {
854
865
  is_index_out_of_bound_ = true;
855
866
  break;
856
867
  }
@@ -353,6 +353,11 @@ class BlockBasedTableIterator : public InternalIteratorBase<Slice> {
353
353
  // is used to disable the lookup.
354
354
  IterDirection direction_ = IterDirection::kForward;
355
355
 
356
+ // The prefix of the key called with SeekImpl().
357
+ // This is for readahead trimming so no data blocks containing keys of a
358
+ // different prefix are prefetched
359
+ std::string seek_key_prefix_for_readahead_trimming_ = "";
360
+
356
361
  void SeekSecondPass(const Slice* target);
357
362
 
358
363
  // If `target` is null, seek to first.
@@ -408,15 +413,41 @@ class BlockBasedTableIterator : public InternalIteratorBase<Slice> {
408
413
  ClearBlockHandles();
409
414
  }
410
415
 
411
- bool IsNextBlockOutOfBound() {
416
+ bool IsNextBlockOutOfReadaheadBound() {
417
+ const Slice& index_iter_user_key = index_iter_->user_key();
412
418
  // If curr block's index key >= iterate_upper_bound, it means all the keys
413
419
  // in next block or above are out of bound.
414
- return (user_comparator_.CompareWithoutTimestamp(
415
- index_iter_->user_key(),
416
- /*a_has_ts=*/true, *read_options_.iterate_upper_bound,
417
- /*b_has_ts=*/false) >= 0
418
- ? true
419
- : false);
420
+ bool out_of_upper_bound =
421
+ read_options_.iterate_upper_bound != nullptr &&
422
+ (user_comparator_.CompareWithoutTimestamp(
423
+ index_iter_user_key,
424
+ /*a_has_ts=*/true, *read_options_.iterate_upper_bound,
425
+ /*b_has_ts=*/false) >= 0
426
+ ? true
427
+ : false);
428
+ if (out_of_upper_bound) {
429
+ return true;
430
+ }
431
+
432
+ // If curr block's index key has a different prefix from the seek key's, it
433
+ // means all the keys in next block or above has a different prefix from the
434
+ // seek key's.
435
+ bool out_of_prefix_bound =
436
+ (read_options_.prefix_same_as_start &&
437
+ !seek_key_prefix_for_readahead_trimming_.empty() &&
438
+ (prefix_extractor_->InDomain(index_iter_user_key)
439
+ ? (prefix_extractor_->Transform(index_iter_user_key)
440
+ .compare(seek_key_prefix_for_readahead_trimming_) != 0)
441
+ : user_comparator_.CompareWithoutTimestamp(
442
+ index_iter_user_key,
443
+ /*a_has_ts=*/true, seek_key_prefix_for_readahead_trimming_,
444
+ /*b_has_ts=*/false) > 0));
445
+
446
+ if (out_of_prefix_bound) {
447
+ return true;
448
+ }
449
+
450
+ return false;
420
451
  }
421
452
 
422
453
  void ClearBlockHandles() {
@@ -137,7 +137,13 @@ extern const std::string kHashIndexPrefixesMetadataBlock;
137
137
 
138
138
  BlockBasedTable::~BlockBasedTable() {
139
139
  auto ua = rep_->uncache_aggressiveness.LoadRelaxed();
140
- if (ua > 0 && rep_->table_options.block_cache) {
140
+ // NOTE: there is an undiagnosed incompatibility with mmap reads,
141
+ // where attempting to read the index below can result in bus error.
142
+ // In theory the mmap should remain in place until destruction of
143
+ // rep_, so even a page fault should be satisfiable. But also, combining
144
+ // mmap reads with block cache is weird, so it's not a concerning loss.
145
+ if (ua > 0 && rep_->table_options.block_cache &&
146
+ !rep_->ioptions.allow_mmap_reads) {
141
147
  if (rep_->filter) {
142
148
  rep_->filter->EraseFromCacheBeforeDestruction(ua);
143
149
  }
@@ -647,13 +653,14 @@ Status BlockBasedTable::Open(
647
653
  ro.rate_limiter_priority = read_options.rate_limiter_priority;
648
654
  ro.verify_checksums = read_options.verify_checksums;
649
655
  ro.io_activity = read_options.io_activity;
656
+ ro.fill_cache = read_options.fill_cache;
650
657
 
651
658
  // prefetch both index and filters, down to all partitions
652
659
  const bool prefetch_all = prefetch_index_and_filter_in_cache || level == 0;
653
660
  const bool preload_all = !table_options.cache_index_and_filter_blocks;
654
661
 
655
662
  if (!ioptions.allow_mmap_reads && !env_options.use_mmap_reads) {
656
- s = PrefetchTail(ro, file.get(), file_size, force_direct_prefetch,
663
+ s = PrefetchTail(ro, ioptions, file.get(), file_size, force_direct_prefetch,
657
664
  tail_prefetch_stats, prefetch_all, preload_all,
658
665
  &prefetch_buffer, ioptions.stats, tail_size,
659
666
  ioptions.logger);
@@ -870,7 +877,8 @@ Status BlockBasedTable::Open(
870
877
  }
871
878
 
872
879
  Status BlockBasedTable::PrefetchTail(
873
- const ReadOptions& ro, RandomAccessFileReader* file, uint64_t file_size,
880
+ const ReadOptions& ro, const ImmutableOptions& ioptions,
881
+ RandomAccessFileReader* file, uint64_t file_size,
874
882
  bool force_direct_prefetch, TailPrefetchStats* tail_prefetch_stats,
875
883
  const bool prefetch_all, const bool preload_all,
876
884
  std::unique_ptr<FilePrefetchBuffer>* prefetch_buffer, Statistics* stats,
@@ -941,7 +949,7 @@ Status BlockBasedTable::PrefetchTail(
941
949
  // Use `FilePrefetchBuffer`
942
950
  prefetch_buffer->reset(new FilePrefetchBuffer(
943
951
  ReadaheadParams(), true /* enable */, true /* track_min_offset */,
944
- nullptr /* fs */, nullptr /* clock */, stats,
952
+ ioptions.fs.get() /* fs */, nullptr /* clock */, stats,
945
953
  /* readahead_cb */ nullptr,
946
954
  FilePrefetchBufferUsage::kTableOpenPrefetchTail));
947
955
 
@@ -482,7 +482,8 @@ class BlockBasedTable : public TableReader {
482
482
  // If force_direct_prefetch is true, always prefetching to RocksDB
483
483
  // buffer, rather than calling RandomAccessFile::Prefetch().
484
484
  static Status PrefetchTail(
485
- const ReadOptions& ro, RandomAccessFileReader* file, uint64_t file_size,
485
+ const ReadOptions& ro, const ImmutableOptions& ioptions,
486
+ RandomAccessFileReader* file, uint64_t file_size,
486
487
  bool force_direct_prefetch, TailPrefetchStats* tail_prefetch_stats,
487
488
  const bool prefetch_all, const bool preload_all,
488
489
  std::unique_ptr<FilePrefetchBuffer>* prefetch_buffer, Statistics* stats,
@@ -500,6 +501,8 @@ class BlockBasedTable : public TableReader {
500
501
  InternalIterator* meta_iter,
501
502
  const InternalKeyComparator& internal_comparator,
502
503
  BlockCacheLookupContext* lookup_context);
504
+ // If index and filter blocks do not need to be pinned, `prefetch_all`
505
+ // determines whether they will be read and add to cache.
503
506
  Status PrefetchIndexAndFilterBlocks(
504
507
  const ReadOptions& ro, FilePrefetchBuffer* prefetch_buffer,
505
508
  InternalIterator* meta_iter, BlockBasedTable* new_table,
@@ -303,12 +303,15 @@ DEFINE_SYNC_AND_ASYNC(void, BlockBasedTable::RetrieveMultipleBlocks)
303
303
  /*lookup_context=*/nullptr, &serialized_block,
304
304
  /*async_read=*/false, /*use_block_cache_for_lookup=*/true);
305
305
 
306
+ if (!s.ok()) {
307
+ statuses[idx_in_batch] = s;
308
+ continue;
309
+ }
306
310
  // block_entry value could be null if no block cache is present, i.e
307
311
  // BlockBasedTableOptions::no_block_cache is true and no compressed
308
312
  // block cache is configured. In that case, fall
309
313
  // through and set up the block explicitly
310
314
  if (block_entry->GetValue() != nullptr) {
311
- s.PermitUncheckedError();
312
315
  continue;
313
316
  }
314
317
  }
@@ -141,7 +141,8 @@ class BlockBasedTableReaderBaseTest : public testing::Test {
141
141
  TableBuilderOptions(ioptions, moptions, read_options, write_options,
142
142
  comparator, &factories, compression_type,
143
143
  compression_opts, 0 /* column_family_id */,
144
- kDefaultColumnFamilyName, -1 /* level */),
144
+ kDefaultColumnFamilyName, -1 /* level */,
145
+ kUnknownNewestKeyTime),
145
146
  writer.get()));
146
147
 
147
148
  // Build table.
@@ -722,6 +723,199 @@ TEST_P(ChargeTableReaderTest, Basic) {
722
723
  }
723
724
  }
724
725
 
726
+ class StrictCapacityLimitReaderTest : public BlockBasedTableReaderTest {
727
+ public:
728
+ StrictCapacityLimitReaderTest() : BlockBasedTableReaderTest() {}
729
+
730
+ protected:
731
+ void ConfigureTableFactory() override {
732
+ BlockBasedTableOptions table_options;
733
+
734
+ table_options.block_cache = std::make_shared<
735
+ TargetCacheChargeTrackingCache<CacheEntryRole::kBlockBasedTableReader>>(
736
+ (NewLRUCache(4 * 1024, 0 /* num_shard_bits */,
737
+ true /* strict_capacity_limit */)));
738
+
739
+ table_options.cache_index_and_filter_blocks = false;
740
+ table_options.filter_policy.reset(NewBloomFilterPolicy(10, false));
741
+ table_options.partition_filters = true;
742
+ table_options.index_type = BlockBasedTableOptions::kTwoLevelIndexSearch;
743
+
744
+ options_.table_factory.reset(NewBlockBasedTableFactory(table_options));
745
+ }
746
+ };
747
+
748
+ TEST_P(StrictCapacityLimitReaderTest, Get) {
749
+ // Test that we get error status when we exceed
750
+ // the strict_capacity_limit
751
+ Options options;
752
+ size_t ts_sz = options.comparator->timestamp_size();
753
+ std::vector<std::pair<std::string, std::string>> kv =
754
+ BlockBasedTableReaderBaseTest::GenerateKVMap(
755
+ 2 /* num_block */, true /* mixed_with_human_readable_string_value */,
756
+ ts_sz, false);
757
+
758
+ std::string table_name = "StrictCapacityLimitReaderTest_Get" +
759
+ CompressionTypeToString(compression_type_);
760
+
761
+ ImmutableOptions ioptions(options);
762
+ CreateTable(table_name, ioptions, compression_type_, kv);
763
+
764
+ std::unique_ptr<BlockBasedTable> table;
765
+ FileOptions foptions;
766
+ foptions.use_direct_reads = true;
767
+ InternalKeyComparator comparator(options.comparator);
768
+ NewBlockBasedTableReader(foptions, ioptions, comparator, table_name, &table,
769
+ true /* prefetch_index_and_filter_in_cache */,
770
+ nullptr /* status */);
771
+
772
+ ReadOptions read_opts;
773
+ ASSERT_OK(
774
+ table->VerifyChecksum(read_opts, TableReaderCaller::kUserVerifyChecksum));
775
+
776
+ bool hit_memory_limit = false;
777
+ for (size_t i = 0; i < kv.size(); i += 1) {
778
+ Slice key = kv[i].first;
779
+ Slice lkey = key;
780
+ std::string lookup_ikey;
781
+ // Reading the first entry in a block caches the whole block.
782
+ if (i % kEntriesPerBlock == 0) {
783
+ ASSERT_FALSE(table->TEST_KeyInCache(read_opts, lkey.ToString()));
784
+ } else if (!hit_memory_limit) {
785
+ ASSERT_TRUE(table->TEST_KeyInCache(read_opts, lkey.ToString()));
786
+ }
787
+ PinnableSlice value;
788
+ GetContext get_context(options.comparator, nullptr, nullptr, nullptr,
789
+ GetContext::kNotFound, ExtractUserKey(key), &value,
790
+ nullptr, nullptr, nullptr, nullptr,
791
+ true /* do_merge */, nullptr, nullptr, nullptr,
792
+ nullptr, nullptr, nullptr);
793
+ Status s = table->Get(read_opts, lkey, &get_context, nullptr);
794
+ if (!s.ok()) {
795
+ EXPECT_TRUE(s.IsMemoryLimit());
796
+ EXPECT_TRUE(s.ToString().find("Memory limit reached: Insert failed due "
797
+ "to LRU cache being full") !=
798
+ std::string::npos);
799
+ hit_memory_limit = true;
800
+ } else {
801
+ ASSERT_EQ(value.ToString(), kv[i].second);
802
+ ASSERT_TRUE(table->TEST_KeyInCache(read_opts, lkey.ToString()));
803
+ }
804
+ }
805
+
806
+ ASSERT_TRUE(hit_memory_limit);
807
+ }
808
+
809
+ TEST_P(StrictCapacityLimitReaderTest, MultiGet) {
810
+ // Test that we get error status when we exceed
811
+ // the strict_capacity_limit
812
+ Options options;
813
+ ReadOptions read_opts;
814
+ std::string dummy_ts(sizeof(uint64_t), '\0');
815
+ Slice read_timestamp = dummy_ts;
816
+ if (udt_enabled_) {
817
+ options.comparator = test::BytewiseComparatorWithU64TsWrapper();
818
+ read_opts.timestamp = &read_timestamp;
819
+ }
820
+ options.persist_user_defined_timestamps = persist_udt_;
821
+ size_t ts_sz = options.comparator->timestamp_size();
822
+ std::vector<std::pair<std::string, std::string>> kv =
823
+ BlockBasedTableReaderBaseTest::GenerateKVMap(
824
+ 2 /* num_block */, true /* mixed_with_human_readable_string_value */,
825
+ ts_sz);
826
+
827
+ // Prepare keys, values, and statuses for MultiGet.
828
+ autovector<Slice, MultiGetContext::MAX_BATCH_SIZE> keys;
829
+ autovector<Slice, MultiGetContext::MAX_BATCH_SIZE> keys_without_timestamps;
830
+ autovector<PinnableSlice, MultiGetContext::MAX_BATCH_SIZE> values;
831
+ autovector<Status, MultiGetContext::MAX_BATCH_SIZE> statuses;
832
+ autovector<const std::string*, MultiGetContext::MAX_BATCH_SIZE>
833
+ expected_values;
834
+ {
835
+ const int step =
836
+ static_cast<int>(kv.size()) / MultiGetContext::MAX_BATCH_SIZE;
837
+ auto it = kv.begin();
838
+ for (int i = 0; i < MultiGetContext::MAX_BATCH_SIZE; i++) {
839
+ keys.emplace_back(it->first);
840
+ if (ts_sz > 0) {
841
+ Slice ukey_without_ts =
842
+ ExtractUserKeyAndStripTimestamp(it->first, ts_sz);
843
+ keys_without_timestamps.push_back(ukey_without_ts);
844
+ } else {
845
+ keys_without_timestamps.emplace_back(ExtractUserKey(it->first));
846
+ }
847
+ values.emplace_back();
848
+ statuses.emplace_back();
849
+ expected_values.push_back(&(it->second));
850
+ std::advance(it, step);
851
+ }
852
+ }
853
+
854
+ std::string table_name = "StrictCapacityLimitReaderTest_MultiGet" +
855
+ CompressionTypeToString(compression_type_);
856
+
857
+ ImmutableOptions ioptions(options);
858
+ CreateTable(table_name, ioptions, compression_type_, kv,
859
+ compression_parallel_threads_, compression_dict_bytes_);
860
+
861
+ std::unique_ptr<BlockBasedTable> table;
862
+ FileOptions foptions;
863
+ foptions.use_direct_reads = use_direct_reads_;
864
+ InternalKeyComparator comparator(options.comparator);
865
+ NewBlockBasedTableReader(foptions, ioptions, comparator, table_name, &table,
866
+ true /* bool prefetch_index_and_filter_in_cache */,
867
+ nullptr /* status */, persist_udt_);
868
+
869
+ ASSERT_OK(
870
+ table->VerifyChecksum(read_opts, TableReaderCaller::kUserVerifyChecksum));
871
+
872
+ // Ensure that keys are not in cache before MultiGet.
873
+ for (auto& key : keys) {
874
+ ASSERT_FALSE(table->TEST_KeyInCache(read_opts, key.ToString()));
875
+ }
876
+
877
+ // Prepare MultiGetContext.
878
+ autovector<GetContext, MultiGetContext::MAX_BATCH_SIZE> get_context;
879
+ autovector<KeyContext, MultiGetContext::MAX_BATCH_SIZE> key_context;
880
+ autovector<KeyContext*, MultiGetContext::MAX_BATCH_SIZE> sorted_keys;
881
+ for (size_t i = 0; i < keys.size(); ++i) {
882
+ get_context.emplace_back(options.comparator, nullptr, nullptr, nullptr,
883
+ GetContext::kNotFound, ExtractUserKey(keys[i]),
884
+ &values[i], nullptr, nullptr, nullptr, nullptr,
885
+ true /* do_merge */, nullptr, nullptr, nullptr,
886
+ nullptr, nullptr, nullptr);
887
+ key_context.emplace_back(nullptr, keys_without_timestamps[i], &values[i],
888
+ nullptr, nullptr, &statuses.back());
889
+ key_context.back().get_context = &get_context.back();
890
+ }
891
+ for (auto& key_ctx : key_context) {
892
+ sorted_keys.emplace_back(&key_ctx);
893
+ }
894
+ MultiGetContext ctx(&sorted_keys, 0, sorted_keys.size(), 0, read_opts,
895
+ fs_.get(), nullptr);
896
+
897
+ // Execute MultiGet.
898
+ MultiGetContext::Range range = ctx.GetMultiGetRange();
899
+ PerfContext* perf_ctx = get_perf_context();
900
+ perf_ctx->Reset();
901
+ table->MultiGet(read_opts, &range, nullptr);
902
+
903
+ ASSERT_GE(perf_ctx->block_read_count - perf_ctx->index_block_read_count -
904
+ perf_ctx->filter_block_read_count -
905
+ perf_ctx->compression_dict_block_read_count,
906
+ 1);
907
+ ASSERT_GE(perf_ctx->block_read_byte, 1);
908
+
909
+ bool hit_memory_limit = false;
910
+ for (const Status& status : statuses) {
911
+ if (!status.ok()) {
912
+ EXPECT_TRUE(status.IsMemoryLimit());
913
+ hit_memory_limit = true;
914
+ }
915
+ }
916
+ ASSERT_TRUE(hit_memory_limit);
917
+ }
918
+
725
919
  class BlockBasedTableReaderTestVerifyChecksum
726
920
  : public BlockBasedTableReaderTest {
727
921
  public:
@@ -828,6 +1022,15 @@ INSTANTIATE_TEST_CASE_P(
828
1022
  ::testing::Values(false), ::testing::ValuesIn(test::GetUDTTestModes()),
829
1023
  ::testing::Values(1, 2), ::testing::Values(0, 4096),
830
1024
  ::testing::Values(false, true)));
1025
+ INSTANTIATE_TEST_CASE_P(
1026
+ StrictCapacityLimitReaderTest, StrictCapacityLimitReaderTest,
1027
+ ::testing::Combine(
1028
+ ::testing::ValuesIn(GetSupportedCompressions()), ::testing::Bool(),
1029
+ ::testing::Values(
1030
+ BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch),
1031
+ ::testing::Values(false), ::testing::ValuesIn(test::GetUDTTestModes()),
1032
+ ::testing::Values(1, 2), ::testing::Values(0),
1033
+ ::testing::Values(false, true)));
831
1034
  INSTANTIATE_TEST_CASE_P(
832
1035
  VerifyChecksum, BlockBasedTableReaderTestVerifyChecksum,
833
1036
  ::testing::Combine(
@@ -555,13 +555,13 @@ void TestBoundary(InternalKey& ik1, std::string& v1, InternalKey& ik2,
555
555
  std::string column_family_name;
556
556
  const ReadOptions read_options;
557
557
  const WriteOptions write_options;
558
- builder.reset(ioptions.table_factory->NewTableBuilder(
558
+ builder.reset(moptions.table_factory->NewTableBuilder(
559
559
  TableBuilderOptions(
560
560
  ioptions, moptions, read_options, write_options, internal_comparator,
561
561
  &internal_tbl_prop_coll_factories, options.compression,
562
562
  CompressionOptions(),
563
563
  TablePropertiesCollectorFactory::Context::kUnknownColumnFamily,
564
- column_family_name, level_),
564
+ column_family_name, level_, kUnknownNewestKeyTime),
565
565
  file_writer.get()));
566
566
 
567
567
  builder->Add(ik1.Encode().ToString(), v1);
@@ -581,7 +581,7 @@ void TestBoundary(InternalKey& ik1, std::string& v1, InternalKey& ik2,
581
581
  file_reader.reset(new RandomAccessFileReader(std::move(file), "test"));
582
582
  const bool kSkipFilters = true;
583
583
  const bool kImmortal = true;
584
- ASSERT_OK(ioptions.table_factory->NewTableReader(
584
+ ASSERT_OK(moptions.table_factory->NewTableReader(
585
585
  TableReaderOptions(ioptions, moptions.prefix_extractor, soptions,
586
586
  internal_comparator,
587
587
  0 /* block_protection_bytes_per_key */, !kSkipFilters,
@@ -83,7 +83,8 @@ class BlockFetcherTest : public testing::Test {
83
83
  TableBuilderOptions(ioptions, moptions, read_options, write_options,
84
84
  comparator, &factories, compression_type,
85
85
  CompressionOptions(), 0 /* column_family_id */,
86
- kDefaultColumnFamilyName, -1 /* level */),
86
+ kDefaultColumnFamilyName, -1 /* level */,
87
+ kUnknownNewestKeyTime),
87
88
  writer.get()));
88
89
 
89
90
  // Build table.
@@ -73,6 +73,10 @@ class CuckooTableFactory : public TableFactory {
73
73
 
74
74
  std::string GetPrintableOptions() const override;
75
75
 
76
+ std::unique_ptr<TableFactory> Clone() const override {
77
+ return std::make_unique<CuckooTableFactory>(*this);
78
+ }
79
+
76
80
  private:
77
81
  CuckooTableOptions table_options_;
78
82
  };
@@ -560,9 +560,9 @@ Status ReadFooterFromFile(const IOOptions& opts, RandomAccessFileReader* file,
560
560
  IOOptions new_opts = opts;
561
561
  new_opts.verify_and_reconstruct_read = true;
562
562
  footer->Reset();
563
- s = ReadFooterFromFileInternal(new_opts, file, fs, prefetch_buffer,
564
- file_size, footer,
565
- enforce_table_magic_number);
563
+ s = ReadFooterFromFileInternal(new_opts, file, fs,
564
+ /*prefetch_buffer=*/nullptr, file_size,
565
+ footer, enforce_table_magic_number);
566
566
  RecordTick(stats, FILE_READ_CORRUPTION_RETRY_COUNT);
567
567
  if (s.ok()) {
568
568
  RecordTick(stats, FILE_READ_CORRUPTION_RETRY_SUCCESS_COUNT);
@@ -105,6 +105,7 @@ void PropertyBlockBuilder::AddTableProperty(const TableProperties& props) {
105
105
  Add(TablePropertiesNames::kColumnFamilyId, props.column_family_id);
106
106
  Add(TablePropertiesNames::kCreationTime, props.creation_time);
107
107
  Add(TablePropertiesNames::kOldestKeyTime, props.oldest_key_time);
108
+ Add(TablePropertiesNames::kNewestKeyTime, props.newest_key_time);
108
109
  if (props.file_creation_time > 0) {
109
110
  Add(TablePropertiesNames::kFileCreationTime, props.file_creation_time);
110
111
  }
@@ -368,6 +369,8 @@ Status ReadTablePropertiesHelper(
368
369
  &new_table_properties->creation_time},
369
370
  {TablePropertiesNames::kOldestKeyTime,
370
371
  &new_table_properties->oldest_key_time},
372
+ {TablePropertiesNames::kNewestKeyTime,
373
+ &new_table_properties->newest_key_time},
371
374
  {TablePropertiesNames::kFileCreationTime,
372
375
  &new_table_properties->file_creation_time},
373
376
  {TablePropertiesNames::kSlowCompressionEstimatedDataSize,
@@ -570,7 +573,7 @@ Status ReadMetaIndexBlockInFile(RandomAccessFileReader* file,
570
573
  return s;
571
574
  }
572
575
  s = ReadFooterFromFile(opts, file, *ioptions.fs, prefetch_buffer, file_size,
573
- &footer, table_magic_number);
576
+ &footer, table_magic_number, ioptions.stats);
574
577
  if (!s.ok()) {
575
578
  return s;
576
579
  }
@@ -25,45 +25,6 @@ void SortKVVector(KVVector* kv_vector, const Comparator* ucmp) {
25
25
  });
26
26
  }
27
27
 
28
- class MockTableReader : public TableReader {
29
- public:
30
- explicit MockTableReader(const KVVector& table) : table_(table) {}
31
-
32
- InternalIterator* NewIterator(const ReadOptions&,
33
- const SliceTransform* prefix_extractor,
34
- Arena* arena, bool skip_filters,
35
- TableReaderCaller caller,
36
- size_t compaction_readahead_size = 0,
37
- bool allow_unprepared_value = false) override;
38
-
39
- Status Get(const ReadOptions& readOptions, const Slice& key,
40
- GetContext* get_context, const SliceTransform* prefix_extractor,
41
- bool skip_filters = false) override;
42
-
43
- uint64_t ApproximateOffsetOf(const ReadOptions& /*read_options*/,
44
- const Slice& /*key*/,
45
- TableReaderCaller /*caller*/) override {
46
- return 0;
47
- }
48
-
49
- uint64_t ApproximateSize(const ReadOptions& /*read_options*/,
50
- const Slice& /*start*/, const Slice& /*end*/,
51
- TableReaderCaller /*caller*/) override {
52
- return 0;
53
- }
54
-
55
- size_t ApproximateMemoryUsage() const override { return 0; }
56
-
57
- void SetupForCompaction() override {}
58
-
59
- std::shared_ptr<const TableProperties> GetTableProperties() const override;
60
-
61
- ~MockTableReader() = default;
62
-
63
- private:
64
- const KVVector& table_;
65
- };
66
-
67
28
  class MockTableIterator : public InternalIterator {
68
29
  public:
69
30
  explicit MockTableIterator(const KVVector& table) : table_(table) {
@@ -233,17 +194,6 @@ Status MockTableReader::Get(const ReadOptions&, const Slice& key,
233
194
  return Status::OK();
234
195
  }
235
196
 
236
- std::shared_ptr<const TableProperties> MockTableReader::GetTableProperties()
237
- const {
238
- TableProperties* tp = new TableProperties();
239
- tp->num_entries = table_.size();
240
- tp->num_range_deletions = 0;
241
- tp->raw_key_size = 1;
242
- tp->raw_value_size = 1;
243
-
244
- return std::shared_ptr<const TableProperties>(tp);
245
- }
246
-
247
197
  MockTableFactory::MockTableFactory()
248
198
  : next_id_(1), corrupt_mode_(MockTableFactory::kCorruptNone) {}
249
199
 
@@ -76,6 +76,9 @@ class MockTableFactory : public TableFactory {
76
76
  // contents are equal to file_contents
77
77
  void AssertSingleFile(const KVVector& file_contents);
78
78
  void AssertLatestFiles(const std::vector<KVVector>& files_contents);
79
+ std::unique_ptr<TableFactory> Clone() const override {
80
+ return nullptr; // Not implemented
81
+ }
79
82
 
80
83
  private:
81
84
  Status GetAndWriteNextID(WritableFileWriter* file, uint32_t* id) const;
@@ -88,5 +91,55 @@ class MockTableFactory : public TableFactory {
88
91
  size_t key_value_size_ = 1;
89
92
  };
90
93
 
94
+ class MockTableReader : public TableReader {
95
+ public:
96
+ explicit MockTableReader(const mock::KVVector& table) : table_(table) {
97
+ tp_.num_entries = table_.size();
98
+ tp_.num_range_deletions = 0;
99
+ tp_.raw_key_size = 1;
100
+ tp_.raw_value_size = 1;
101
+ }
102
+ explicit MockTableReader(const mock::KVVector& table,
103
+ const TableProperties& tp)
104
+ : table_(table), tp_(tp) {}
105
+
106
+ virtual InternalIterator* NewIterator(
107
+ const ReadOptions&, const SliceTransform* prefix_extractor, Arena* arena,
108
+ bool skip_filters, TableReaderCaller caller,
109
+ size_t compaction_readahead_size = 0,
110
+ bool allow_unprepared_value = false) override;
111
+
112
+ virtual Status Get(const ReadOptions& readOptions, const Slice& key,
113
+ GetContext* get_context,
114
+ const SliceTransform* prefix_extractor,
115
+ bool skip_filters = false) override;
116
+
117
+ virtual uint64_t ApproximateOffsetOf(const ReadOptions& /*read_options*/,
118
+ const Slice& /*key*/,
119
+ TableReaderCaller /*caller*/) override {
120
+ return 0;
121
+ }
122
+
123
+ virtual uint64_t ApproximateSize(const ReadOptions& /*read_options*/,
124
+ const Slice& /*start*/, const Slice& /*end*/,
125
+ TableReaderCaller /*caller*/) override {
126
+ return 0;
127
+ }
128
+
129
+ virtual size_t ApproximateMemoryUsage() const override { return 0; }
130
+
131
+ virtual void SetupForCompaction() override {}
132
+
133
+ virtual std::shared_ptr<const TableProperties> GetTableProperties()
134
+ const override {
135
+ return std::make_shared<const TableProperties>(tp_);
136
+ }
137
+
138
+ ~MockTableReader() = default;
139
+
140
+ private:
141
+ const KVVector& table_;
142
+ TableProperties tp_;
143
+ };
91
144
  } // namespace mock
92
145
  } // namespace ROCKSDB_NAMESPACE
@@ -173,6 +173,10 @@ class PlainTableFactory : public TableFactory {
173
173
  std::string GetPrintableOptions() const override;
174
174
  static const char kValueTypeSeqId0 = char(~0);
175
175
 
176
+ std::unique_ptr<TableFactory> Clone() const override {
177
+ return std::make_unique<PlainTableFactory>(*this);
178
+ }
179
+
176
180
  private:
177
181
  PlainTableOptions table_options_;
178
182
  };
@@ -311,7 +311,7 @@ Status SstFileDumper::ShowCompressionSize(
311
311
  imoptions, moptions, read_options, write_options, ikc,
312
312
  &block_based_table_factories, compress_type, compress_opt,
313
313
  TablePropertiesCollectorFactory::Context::kUnknownColumnFamily,
314
- column_family_name, unknown_level);
314
+ column_family_name, unknown_level, kUnknownNewestKeyTime);
315
315
  uint64_t num_data_blocks = 0;
316
316
  std::chrono::steady_clock::time_point start =
317
317
  std::chrono::steady_clock::now();