@nxtedition/rocksdb 1.0.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 (1088) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/LICENSE +21 -0
  3. package/README.md +102 -0
  4. package/UPGRADING.md +91 -0
  5. package/binding.cc +1276 -0
  6. package/binding.gyp +73 -0
  7. package/binding.js +1 -0
  8. package/chained-batch.js +44 -0
  9. package/deps/rocksdb/build_version.cc +4 -0
  10. package/deps/rocksdb/rocksdb/CMakeLists.txt +1356 -0
  11. package/deps/rocksdb/rocksdb/COPYING +339 -0
  12. package/deps/rocksdb/rocksdb/LICENSE.Apache +202 -0
  13. package/deps/rocksdb/rocksdb/LICENSE.leveldb +29 -0
  14. package/deps/rocksdb/rocksdb/Makefile +2521 -0
  15. package/deps/rocksdb/rocksdb/TARGETS +2100 -0
  16. package/deps/rocksdb/rocksdb/cache/cache.cc +63 -0
  17. package/deps/rocksdb/rocksdb/cache/cache_bench.cc +381 -0
  18. package/deps/rocksdb/rocksdb/cache/cache_helpers.h +114 -0
  19. package/deps/rocksdb/rocksdb/cache/cache_test.cc +775 -0
  20. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +769 -0
  21. package/deps/rocksdb/rocksdb/cache/clock_cache.h +16 -0
  22. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +574 -0
  23. package/deps/rocksdb/rocksdb/cache/lru_cache.h +339 -0
  24. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +199 -0
  25. package/deps/rocksdb/rocksdb/cache/sharded_cache.cc +162 -0
  26. package/deps/rocksdb/rocksdb/cache/sharded_cache.h +111 -0
  27. package/deps/rocksdb/rocksdb/cmake/RocksDBConfig.cmake.in +54 -0
  28. package/deps/rocksdb/rocksdb/cmake/modules/CxxFlags.cmake +7 -0
  29. package/deps/rocksdb/rocksdb/cmake/modules/FindJeMalloc.cmake +29 -0
  30. package/deps/rocksdb/rocksdb/cmake/modules/FindNUMA.cmake +29 -0
  31. package/deps/rocksdb/rocksdb/cmake/modules/FindSnappy.cmake +29 -0
  32. package/deps/rocksdb/rocksdb/cmake/modules/FindTBB.cmake +33 -0
  33. package/deps/rocksdb/rocksdb/cmake/modules/Findgflags.cmake +29 -0
  34. package/deps/rocksdb/rocksdb/cmake/modules/Findlz4.cmake +29 -0
  35. package/deps/rocksdb/rocksdb/cmake/modules/Findzstd.cmake +29 -0
  36. package/deps/rocksdb/rocksdb/cmake/modules/ReadVersion.cmake +10 -0
  37. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.cc +108 -0
  38. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.h +115 -0
  39. package/deps/rocksdb/rocksdb/db/blob/blob_constants.h +16 -0
  40. package/deps/rocksdb/rocksdb/db/blob/blob_file_addition.cc +154 -0
  41. package/deps/rocksdb/rocksdb/db/blob/blob_file_addition.h +67 -0
  42. package/deps/rocksdb/rocksdb/db/blob/blob_file_addition_test.cc +206 -0
  43. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.cc +316 -0
  44. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.h +91 -0
  45. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder_test.cc +660 -0
  46. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.cc +99 -0
  47. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.h +49 -0
  48. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache_test.cc +268 -0
  49. package/deps/rocksdb/rocksdb/db/blob/blob_file_garbage.cc +134 -0
  50. package/deps/rocksdb/rocksdb/db/blob/blob_file_garbage.h +57 -0
  51. package/deps/rocksdb/rocksdb/db/blob/blob_file_garbage_test.cc +173 -0
  52. package/deps/rocksdb/rocksdb/db/blob/blob_file_meta.cc +55 -0
  53. package/deps/rocksdb/rocksdb/db/blob/blob_file_meta.h +164 -0
  54. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +423 -0
  55. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.h +81 -0
  56. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader_test.cc +771 -0
  57. package/deps/rocksdb/rocksdb/db/blob/blob_index.h +184 -0
  58. package/deps/rocksdb/rocksdb/db/blob/blob_log_format.cc +145 -0
  59. package/deps/rocksdb/rocksdb/db/blob/blob_log_format.h +148 -0
  60. package/deps/rocksdb/rocksdb/db/blob/blob_log_sequential_reader.cc +132 -0
  61. package/deps/rocksdb/rocksdb/db/blob/blob_log_sequential_reader.h +76 -0
  62. package/deps/rocksdb/rocksdb/db/blob/blob_log_writer.cc +168 -0
  63. package/deps/rocksdb/rocksdb/db/blob/blob_log_writer.h +83 -0
  64. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +307 -0
  65. package/deps/rocksdb/rocksdb/db/blob/db_blob_index_test.cc +464 -0
  66. package/deps/rocksdb/rocksdb/db/builder.cc +358 -0
  67. package/deps/rocksdb/rocksdb/db/builder.h +95 -0
  68. package/deps/rocksdb/rocksdb/db/c.cc +5281 -0
  69. package/deps/rocksdb/rocksdb/db/c_test.c +2883 -0
  70. package/deps/rocksdb/rocksdb/db/column_family.cc +1602 -0
  71. package/deps/rocksdb/rocksdb/db/column_family.h +787 -0
  72. package/deps/rocksdb/rocksdb/db/column_family_test.cc +3427 -0
  73. package/deps/rocksdb/rocksdb/db/compact_files_test.cc +425 -0
  74. package/deps/rocksdb/rocksdb/db/compacted_db_impl.cc +169 -0
  75. package/deps/rocksdb/rocksdb/db/compacted_db_impl.h +118 -0
  76. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +591 -0
  77. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +389 -0
  78. package/deps/rocksdb/rocksdb/db/compaction/compaction_iteration_stats.h +37 -0
  79. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +1023 -0
  80. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +353 -0
  81. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +1254 -0
  82. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +1917 -0
  83. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +208 -0
  84. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_stats_test.cc +1037 -0
  85. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +1224 -0
  86. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +1135 -0
  87. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +318 -0
  88. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +255 -0
  89. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +57 -0
  90. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +510 -0
  91. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +33 -0
  92. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +2190 -0
  93. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +1103 -0
  94. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +32 -0
  95. package/deps/rocksdb/rocksdb/db/compaction/sst_partitioner.cc +44 -0
  96. package/deps/rocksdb/rocksdb/db/comparator_db_test.cc +660 -0
  97. package/deps/rocksdb/rocksdb/db/convenience.cc +78 -0
  98. package/deps/rocksdb/rocksdb/db/corruption_test.cc +921 -0
  99. package/deps/rocksdb/rocksdb/db/cuckoo_table_db_test.cc +359 -0
  100. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +3820 -0
  101. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +1058 -0
  102. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +2128 -0
  103. package/deps/rocksdb/rocksdb/db/db_compaction_filter_test.cc +851 -0
  104. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +6292 -0
  105. package/deps/rocksdb/rocksdb/db/db_dynamic_level_test.cc +509 -0
  106. package/deps/rocksdb/rocksdb/db/db_encryption_test.cc +130 -0
  107. package/deps/rocksdb/rocksdb/db/db_filesnapshot.cc +137 -0
  108. package/deps/rocksdb/rocksdb/db/db_flush_test.cc +1119 -0
  109. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +5057 -0
  110. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +2274 -0
  111. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +3421 -0
  112. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +298 -0
  113. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +151 -0
  114. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +967 -0
  115. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +1806 -0
  116. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +270 -0
  117. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.h +146 -0
  118. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +683 -0
  119. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.h +333 -0
  120. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +2024 -0
  121. package/deps/rocksdb/rocksdb/db/db_impl/db_secondary_test.cc +932 -0
  122. package/deps/rocksdb/rocksdb/db/db_info_dumper.cc +137 -0
  123. package/deps/rocksdb/rocksdb/db/db_info_dumper.h +15 -0
  124. package/deps/rocksdb/rocksdb/db/db_inplace_update_test.cc +178 -0
  125. package/deps/rocksdb/rocksdb/db/db_io_failure_test.cc +592 -0
  126. package/deps/rocksdb/rocksdb/db/db_iter.cc +1493 -0
  127. package/deps/rocksdb/rocksdb/db/db_iter.h +390 -0
  128. package/deps/rocksdb/rocksdb/db/db_iter_stress_test.cc +657 -0
  129. package/deps/rocksdb/rocksdb/db/db_iter_test.cc +3268 -0
  130. package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +3197 -0
  131. package/deps/rocksdb/rocksdb/db/db_log_iter_test.cc +299 -0
  132. package/deps/rocksdb/rocksdb/db/db_logical_block_size_cache_test.cc +513 -0
  133. package/deps/rocksdb/rocksdb/db/db_memtable_test.cc +329 -0
  134. package/deps/rocksdb/rocksdb/db/db_merge_operand_test.cc +241 -0
  135. package/deps/rocksdb/rocksdb/db/db_merge_operator_test.cc +671 -0
  136. package/deps/rocksdb/rocksdb/db/db_options_test.cc +1022 -0
  137. package/deps/rocksdb/rocksdb/db/db_properties_test.cc +1723 -0
  138. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +1694 -0
  139. package/deps/rocksdb/rocksdb/db/db_sst_test.cc +1261 -0
  140. package/deps/rocksdb/rocksdb/db/db_statistics_test.cc +164 -0
  141. package/deps/rocksdb/rocksdb/db/db_table_properties_test.cc +488 -0
  142. package/deps/rocksdb/rocksdb/db/db_tailing_iter_test.cc +567 -0
  143. package/deps/rocksdb/rocksdb/db/db_test.cc +6736 -0
  144. package/deps/rocksdb/rocksdb/db/db_test2.cc +5408 -0
  145. package/deps/rocksdb/rocksdb/db/db_test_util.cc +1633 -0
  146. package/deps/rocksdb/rocksdb/db/db_test_util.h +1194 -0
  147. package/deps/rocksdb/rocksdb/db/db_universal_compaction_test.cc +2235 -0
  148. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +1780 -0
  149. package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +2520 -0
  150. package/deps/rocksdb/rocksdb/db/db_with_timestamp_compaction_test.cc +119 -0
  151. package/deps/rocksdb/rocksdb/db/db_write_test.cc +465 -0
  152. package/deps/rocksdb/rocksdb/db/dbformat.cc +222 -0
  153. package/deps/rocksdb/rocksdb/db/dbformat.h +786 -0
  154. package/deps/rocksdb/rocksdb/db/dbformat_test.cc +206 -0
  155. package/deps/rocksdb/rocksdb/db/deletefile_test.cc +580 -0
  156. package/deps/rocksdb/rocksdb/db/error_handler.cc +726 -0
  157. package/deps/rocksdb/rocksdb/db/error_handler.h +117 -0
  158. package/deps/rocksdb/rocksdb/db/error_handler_fs_test.cc +2598 -0
  159. package/deps/rocksdb/rocksdb/db/event_helpers.cc +233 -0
  160. package/deps/rocksdb/rocksdb/db/event_helpers.h +57 -0
  161. package/deps/rocksdb/rocksdb/db/experimental.cc +50 -0
  162. package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +1559 -0
  163. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +910 -0
  164. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +195 -0
  165. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +2936 -0
  166. package/deps/rocksdb/rocksdb/db/fault_injection_test.cc +556 -0
  167. package/deps/rocksdb/rocksdb/db/file_indexer.cc +216 -0
  168. package/deps/rocksdb/rocksdb/db/file_indexer.h +142 -0
  169. package/deps/rocksdb/rocksdb/db/file_indexer_test.cc +350 -0
  170. package/deps/rocksdb/rocksdb/db/filename_test.cc +179 -0
  171. package/deps/rocksdb/rocksdb/db/flush_job.cc +514 -0
  172. package/deps/rocksdb/rocksdb/db/flush_job.h +169 -0
  173. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +647 -0
  174. package/deps/rocksdb/rocksdb/db/flush_scheduler.cc +86 -0
  175. package/deps/rocksdb/rocksdb/db/flush_scheduler.h +54 -0
  176. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +1023 -0
  177. package/deps/rocksdb/rocksdb/db/forward_iterator.h +163 -0
  178. package/deps/rocksdb/rocksdb/db/forward_iterator_bench.cc +377 -0
  179. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +282 -0
  180. package/deps/rocksdb/rocksdb/db/import_column_family_job.h +75 -0
  181. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +632 -0
  182. package/deps/rocksdb/rocksdb/db/internal_stats.cc +1461 -0
  183. package/deps/rocksdb/rocksdb/db/internal_stats.h +712 -0
  184. package/deps/rocksdb/rocksdb/db/job_context.h +226 -0
  185. package/deps/rocksdb/rocksdb/db/listener_test.cc +1118 -0
  186. package/deps/rocksdb/rocksdb/db/log_format.h +48 -0
  187. package/deps/rocksdb/rocksdb/db/log_reader.cc +654 -0
  188. package/deps/rocksdb/rocksdb/db/log_reader.h +192 -0
  189. package/deps/rocksdb/rocksdb/db/log_test.cc +901 -0
  190. package/deps/rocksdb/rocksdb/db/log_writer.cc +164 -0
  191. package/deps/rocksdb/rocksdb/db/log_writer.h +115 -0
  192. package/deps/rocksdb/rocksdb/db/logs_with_prep_tracker.cc +67 -0
  193. package/deps/rocksdb/rocksdb/db/logs_with_prep_tracker.h +63 -0
  194. package/deps/rocksdb/rocksdb/db/lookup_key.h +66 -0
  195. package/deps/rocksdb/rocksdb/db/malloc_stats.cc +54 -0
  196. package/deps/rocksdb/rocksdb/db/malloc_stats.h +24 -0
  197. package/deps/rocksdb/rocksdb/db/manual_compaction_test.cc +296 -0
  198. package/deps/rocksdb/rocksdb/db/memtable.cc +1169 -0
  199. package/deps/rocksdb/rocksdb/db/memtable.h +554 -0
  200. package/deps/rocksdb/rocksdb/db/memtable_list.cc +888 -0
  201. package/deps/rocksdb/rocksdb/db/memtable_list.h +438 -0
  202. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +935 -0
  203. package/deps/rocksdb/rocksdb/db/merge_context.h +134 -0
  204. package/deps/rocksdb/rocksdb/db/merge_helper.cc +421 -0
  205. package/deps/rocksdb/rocksdb/db/merge_helper.h +197 -0
  206. package/deps/rocksdb/rocksdb/db/merge_helper_test.cc +290 -0
  207. package/deps/rocksdb/rocksdb/db/merge_operator.cc +86 -0
  208. package/deps/rocksdb/rocksdb/db/merge_test.cc +608 -0
  209. package/deps/rocksdb/rocksdb/db/obsolete_files_test.cc +338 -0
  210. package/deps/rocksdb/rocksdb/db/options_file_test.cc +119 -0
  211. package/deps/rocksdb/rocksdb/db/output_validator.cc +30 -0
  212. package/deps/rocksdb/rocksdb/db/output_validator.h +47 -0
  213. package/deps/rocksdb/rocksdb/db/perf_context_test.cc +993 -0
  214. package/deps/rocksdb/rocksdb/db/periodic_work_scheduler.cc +113 -0
  215. package/deps/rocksdb/rocksdb/db/periodic_work_scheduler.h +76 -0
  216. package/deps/rocksdb/rocksdb/db/periodic_work_scheduler_test.cc +231 -0
  217. package/deps/rocksdb/rocksdb/db/pinned_iterators_manager.h +87 -0
  218. package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +1374 -0
  219. package/deps/rocksdb/rocksdb/db/pre_release_callback.h +38 -0
  220. package/deps/rocksdb/rocksdb/db/prefix_test.cc +910 -0
  221. package/deps/rocksdb/rocksdb/db/range_del_aggregator.cc +489 -0
  222. package/deps/rocksdb/rocksdb/db/range_del_aggregator.h +446 -0
  223. package/deps/rocksdb/rocksdb/db/range_del_aggregator_bench.cc +260 -0
  224. package/deps/rocksdb/rocksdb/db/range_del_aggregator_test.cc +709 -0
  225. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.cc +439 -0
  226. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.h +256 -0
  227. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter_test.cc +552 -0
  228. package/deps/rocksdb/rocksdb/db/read_callback.h +53 -0
  229. package/deps/rocksdb/rocksdb/db/repair.cc +722 -0
  230. package/deps/rocksdb/rocksdb/db/repair_test.cc +390 -0
  231. package/deps/rocksdb/rocksdb/db/snapshot_checker.h +61 -0
  232. package/deps/rocksdb/rocksdb/db/snapshot_impl.cc +26 -0
  233. package/deps/rocksdb/rocksdb/db/snapshot_impl.h +167 -0
  234. package/deps/rocksdb/rocksdb/db/table_cache.cc +704 -0
  235. package/deps/rocksdb/rocksdb/db/table_cache.h +233 -0
  236. package/deps/rocksdb/rocksdb/db/table_properties_collector.cc +75 -0
  237. package/deps/rocksdb/rocksdb/db/table_properties_collector.h +107 -0
  238. package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +517 -0
  239. package/deps/rocksdb/rocksdb/db/transaction_log_impl.cc +318 -0
  240. package/deps/rocksdb/rocksdb/db/transaction_log_impl.h +128 -0
  241. package/deps/rocksdb/rocksdb/db/trim_history_scheduler.cc +54 -0
  242. package/deps/rocksdb/rocksdb/db/trim_history_scheduler.h +44 -0
  243. package/deps/rocksdb/rocksdb/db/version_builder.cc +1078 -0
  244. package/deps/rocksdb/rocksdb/db/version_builder.h +69 -0
  245. package/deps/rocksdb/rocksdb/db/version_builder_test.cc +1551 -0
  246. package/deps/rocksdb/rocksdb/db/version_edit.cc +955 -0
  247. package/deps/rocksdb/rocksdb/db/version_edit.h +609 -0
  248. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +699 -0
  249. package/deps/rocksdb/rocksdb/db/version_edit_handler.h +252 -0
  250. package/deps/rocksdb/rocksdb/db/version_edit_test.cc +597 -0
  251. package/deps/rocksdb/rocksdb/db/version_set.cc +6333 -0
  252. package/deps/rocksdb/rocksdb/db/version_set.h +1485 -0
  253. package/deps/rocksdb/rocksdb/db/version_set_test.cc +3035 -0
  254. package/deps/rocksdb/rocksdb/db/wal_edit.cc +204 -0
  255. package/deps/rocksdb/rocksdb/db/wal_edit.h +166 -0
  256. package/deps/rocksdb/rocksdb/db/wal_edit_test.cc +214 -0
  257. package/deps/rocksdb/rocksdb/db/wal_manager.cc +517 -0
  258. package/deps/rocksdb/rocksdb/db/wal_manager.h +119 -0
  259. package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +340 -0
  260. package/deps/rocksdb/rocksdb/db/write_batch.cc +2174 -0
  261. package/deps/rocksdb/rocksdb/db/write_batch_base.cc +94 -0
  262. package/deps/rocksdb/rocksdb/db/write_batch_internal.h +250 -0
  263. package/deps/rocksdb/rocksdb/db/write_batch_test.cc +907 -0
  264. package/deps/rocksdb/rocksdb/db/write_callback.h +27 -0
  265. package/deps/rocksdb/rocksdb/db/write_callback_test.cc +457 -0
  266. package/deps/rocksdb/rocksdb/db/write_controller.cc +128 -0
  267. package/deps/rocksdb/rocksdb/db/write_controller.h +144 -0
  268. package/deps/rocksdb/rocksdb/db/write_controller_test.cc +135 -0
  269. package/deps/rocksdb/rocksdb/db/write_thread.cc +796 -0
  270. package/deps/rocksdb/rocksdb/db/write_thread.h +433 -0
  271. package/deps/rocksdb/rocksdb/db_stress_tool/CMakeLists.txt +14 -0
  272. package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +341 -0
  273. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +520 -0
  274. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress.cc +23 -0
  275. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +337 -0
  276. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +554 -0
  277. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_compaction_filter.h +79 -0
  278. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +173 -0
  279. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.h +17 -0
  280. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_env_wrapper.h +38 -0
  281. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +763 -0
  282. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_listener.h +222 -0
  283. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.cc +27 -0
  284. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.h +428 -0
  285. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_stat.h +218 -0
  286. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_table_properties_collector.h +64 -0
  287. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +2430 -0
  288. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +237 -0
  289. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +343 -0
  290. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +800 -0
  291. package/deps/rocksdb/rocksdb/env/composite_env_wrapper.h +920 -0
  292. package/deps/rocksdb/rocksdb/env/env.cc +733 -0
  293. package/deps/rocksdb/rocksdb/env/env_basic_test.cc +352 -0
  294. package/deps/rocksdb/rocksdb/env/env_chroot.cc +346 -0
  295. package/deps/rocksdb/rocksdb/env/env_chroot.h +22 -0
  296. package/deps/rocksdb/rocksdb/env/env_encryption.cc +1148 -0
  297. package/deps/rocksdb/rocksdb/env/env_encryption_ctr.h +137 -0
  298. package/deps/rocksdb/rocksdb/env/env_hdfs.cc +648 -0
  299. package/deps/rocksdb/rocksdb/env/env_posix.cc +514 -0
  300. package/deps/rocksdb/rocksdb/env/env_test.cc +2230 -0
  301. package/deps/rocksdb/rocksdb/env/file_system.cc +132 -0
  302. package/deps/rocksdb/rocksdb/env/file_system_tracer.cc +448 -0
  303. package/deps/rocksdb/rocksdb/env/file_system_tracer.h +415 -0
  304. package/deps/rocksdb/rocksdb/env/fs_posix.cc +1086 -0
  305. package/deps/rocksdb/rocksdb/env/io_posix.cc +1499 -0
  306. package/deps/rocksdb/rocksdb/env/io_posix.h +402 -0
  307. package/deps/rocksdb/rocksdb/env/io_posix_test.cc +140 -0
  308. package/deps/rocksdb/rocksdb/env/mock_env.cc +1066 -0
  309. package/deps/rocksdb/rocksdb/env/mock_env.h +41 -0
  310. package/deps/rocksdb/rocksdb/env/mock_env_test.cc +85 -0
  311. package/deps/rocksdb/rocksdb/file/delete_scheduler.cc +402 -0
  312. package/deps/rocksdb/rocksdb/file/delete_scheduler.h +150 -0
  313. package/deps/rocksdb/rocksdb/file/delete_scheduler_test.cc +717 -0
  314. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +156 -0
  315. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +99 -0
  316. package/deps/rocksdb/rocksdb/file/file_util.cc +268 -0
  317. package/deps/rocksdb/rocksdb/file/file_util.h +96 -0
  318. package/deps/rocksdb/rocksdb/file/filename.cc +473 -0
  319. package/deps/rocksdb/rocksdb/file/filename.h +182 -0
  320. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +188 -0
  321. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +315 -0
  322. package/deps/rocksdb/rocksdb/file/random_access_file_reader.h +142 -0
  323. package/deps/rocksdb/rocksdb/file/random_access_file_reader_test.cc +482 -0
  324. package/deps/rocksdb/rocksdb/file/read_write_util.cc +67 -0
  325. package/deps/rocksdb/rocksdb/file/read_write_util.h +34 -0
  326. package/deps/rocksdb/rocksdb/file/readahead_raf.cc +169 -0
  327. package/deps/rocksdb/rocksdb/file/readahead_raf.h +29 -0
  328. package/deps/rocksdb/rocksdb/file/sequence_file_reader.cc +237 -0
  329. package/deps/rocksdb/rocksdb/file/sequence_file_reader.h +63 -0
  330. package/deps/rocksdb/rocksdb/file/sst_file_manager_impl.cc +552 -0
  331. package/deps/rocksdb/rocksdb/file/sst_file_manager_impl.h +203 -0
  332. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +523 -0
  333. package/deps/rocksdb/rocksdb/file/writable_file_writer.h +251 -0
  334. package/deps/rocksdb/rocksdb/hdfs/env_hdfs.h +386 -0
  335. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +839 -0
  336. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +2218 -0
  337. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +294 -0
  338. package/deps/rocksdb/rocksdb/include/rocksdb/cleanable.h +71 -0
  339. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_filter.h +214 -0
  340. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_job_stats.h +98 -0
  341. package/deps/rocksdb/rocksdb/include/rocksdb/comparator.h +137 -0
  342. package/deps/rocksdb/rocksdb/include/rocksdb/compression_type.h +40 -0
  343. package/deps/rocksdb/rocksdb/include/rocksdb/concurrent_task_limiter.h +46 -0
  344. package/deps/rocksdb/rocksdb/include/rocksdb/configurable.h +359 -0
  345. package/deps/rocksdb/rocksdb/include/rocksdb/convenience.h +499 -0
  346. package/deps/rocksdb/rocksdb/include/rocksdb/customizable.h +138 -0
  347. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +1697 -0
  348. package/deps/rocksdb/rocksdb/include/rocksdb/db_bench_tool.h +11 -0
  349. package/deps/rocksdb/rocksdb/include/rocksdb/db_dump_tool.h +45 -0
  350. package/deps/rocksdb/rocksdb/include/rocksdb/db_stress_tool.h +11 -0
  351. package/deps/rocksdb/rocksdb/include/rocksdb/env.h +1671 -0
  352. package/deps/rocksdb/rocksdb/include/rocksdb/env_encryption.h +405 -0
  353. package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +29 -0
  354. package/deps/rocksdb/rocksdb/include/rocksdb/file_checksum.h +129 -0
  355. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +1472 -0
  356. package/deps/rocksdb/rocksdb/include/rocksdb/filter_policy.h +238 -0
  357. package/deps/rocksdb/rocksdb/include/rocksdb/flush_block_policy.h +61 -0
  358. package/deps/rocksdb/rocksdb/include/rocksdb/io_status.h +269 -0
  359. package/deps/rocksdb/rocksdb/include/rocksdb/iostats_context.h +56 -0
  360. package/deps/rocksdb/rocksdb/include/rocksdb/iterator.h +128 -0
  361. package/deps/rocksdb/rocksdb/include/rocksdb/ldb_tool.h +43 -0
  362. package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +556 -0
  363. package/deps/rocksdb/rocksdb/include/rocksdb/memory_allocator.h +77 -0
  364. package/deps/rocksdb/rocksdb/include/rocksdb/memtablerep.h +385 -0
  365. package/deps/rocksdb/rocksdb/include/rocksdb/merge_operator.h +257 -0
  366. package/deps/rocksdb/rocksdb/include/rocksdb/metadata.h +155 -0
  367. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +1702 -0
  368. package/deps/rocksdb/rocksdb/include/rocksdb/perf_context.h +237 -0
  369. package/deps/rocksdb/rocksdb/include/rocksdb/perf_level.h +35 -0
  370. package/deps/rocksdb/rocksdb/include/rocksdb/persistent_cache.h +73 -0
  371. package/deps/rocksdb/rocksdb/include/rocksdb/rate_limiter.h +139 -0
  372. package/deps/rocksdb/rocksdb/include/rocksdb/rocksdb_namespace.h +10 -0
  373. package/deps/rocksdb/rocksdb/include/rocksdb/slice.h +269 -0
  374. package/deps/rocksdb/rocksdb/include/rocksdb/slice_transform.h +103 -0
  375. package/deps/rocksdb/rocksdb/include/rocksdb/snapshot.h +48 -0
  376. package/deps/rocksdb/rocksdb/include/rocksdb/sst_dump_tool.h +19 -0
  377. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_manager.h +136 -0
  378. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_reader.h +47 -0
  379. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +145 -0
  380. package/deps/rocksdb/rocksdb/include/rocksdb/sst_partitioner.h +135 -0
  381. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +592 -0
  382. package/deps/rocksdb/rocksdb/include/rocksdb/stats_history.h +69 -0
  383. package/deps/rocksdb/rocksdb/include/rocksdb/status.h +608 -0
  384. package/deps/rocksdb/rocksdb/include/rocksdb/table.h +711 -0
  385. package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +280 -0
  386. package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +188 -0
  387. package/deps/rocksdb/rocksdb/include/rocksdb/threadpool.h +58 -0
  388. package/deps/rocksdb/rocksdb/include/rocksdb/trace_reader_writer.h +48 -0
  389. package/deps/rocksdb/rocksdb/include/rocksdb/transaction_log.h +121 -0
  390. package/deps/rocksdb/rocksdb/include/rocksdb/types.h +74 -0
  391. package/deps/rocksdb/rocksdb/include/rocksdb/universal_compaction.h +86 -0
  392. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/backupable_db.h +535 -0
  393. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/checkpoint.h +61 -0
  394. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/convenience.h +10 -0
  395. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/db_ttl.h +72 -0
  396. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/debug.h +49 -0
  397. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/env_librados.h +175 -0
  398. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/env_mirror.h +180 -0
  399. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/info_log_finder.h +19 -0
  400. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd.h +288 -0
  401. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd_execute_result.h +71 -0
  402. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/leveldb_options.h +145 -0
  403. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/lua/rocks_lua_custom_library.h +43 -0
  404. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/lua/rocks_lua_util.h +55 -0
  405. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/memory_util.h +50 -0
  406. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/object_registry.h +205 -0
  407. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/optimistic_transaction_db.h +100 -0
  408. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/option_change_migration.h +19 -0
  409. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_type.h +876 -0
  410. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_util.h +128 -0
  411. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/sim_cache.h +94 -0
  412. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +504 -0
  413. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/table_properties_collectors.h +95 -0
  414. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction.h +626 -0
  415. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db.h +432 -0
  416. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db_mutex.h +92 -0
  417. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/utility_db.h +34 -0
  418. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/write_batch_with_index.h +279 -0
  419. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +16 -0
  420. package/deps/rocksdb/rocksdb/include/rocksdb/wal_filter.h +102 -0
  421. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +377 -0
  422. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch_base.h +127 -0
  423. package/deps/rocksdb/rocksdb/include/rocksdb/write_buffer_manager.h +106 -0
  424. package/deps/rocksdb/rocksdb/logging/auto_roll_logger.cc +300 -0
  425. package/deps/rocksdb/rocksdb/logging/auto_roll_logger.h +165 -0
  426. package/deps/rocksdb/rocksdb/logging/auto_roll_logger_test.cc +684 -0
  427. package/deps/rocksdb/rocksdb/logging/env_logger.h +165 -0
  428. package/deps/rocksdb/rocksdb/logging/env_logger_test.cc +162 -0
  429. package/deps/rocksdb/rocksdb/logging/event_logger.cc +70 -0
  430. package/deps/rocksdb/rocksdb/logging/event_logger.h +203 -0
  431. package/deps/rocksdb/rocksdb/logging/event_logger_test.cc +43 -0
  432. package/deps/rocksdb/rocksdb/logging/log_buffer.cc +92 -0
  433. package/deps/rocksdb/rocksdb/logging/log_buffer.h +56 -0
  434. package/deps/rocksdb/rocksdb/logging/logging.h +68 -0
  435. package/deps/rocksdb/rocksdb/logging/posix_logger.h +185 -0
  436. package/deps/rocksdb/rocksdb/memory/allocator.h +57 -0
  437. package/deps/rocksdb/rocksdb/memory/arena.cc +233 -0
  438. package/deps/rocksdb/rocksdb/memory/arena.h +141 -0
  439. package/deps/rocksdb/rocksdb/memory/arena_test.cc +204 -0
  440. package/deps/rocksdb/rocksdb/memory/concurrent_arena.cc +47 -0
  441. package/deps/rocksdb/rocksdb/memory/concurrent_arena.h +218 -0
  442. package/deps/rocksdb/rocksdb/memory/jemalloc_nodump_allocator.cc +206 -0
  443. package/deps/rocksdb/rocksdb/memory/jemalloc_nodump_allocator.h +78 -0
  444. package/deps/rocksdb/rocksdb/memory/memkind_kmem_allocator.cc +33 -0
  445. package/deps/rocksdb/rocksdb/memory/memkind_kmem_allocator.h +27 -0
  446. package/deps/rocksdb/rocksdb/memory/memkind_kmem_allocator_test.cc +102 -0
  447. package/deps/rocksdb/rocksdb/memory/memory_allocator.h +38 -0
  448. package/deps/rocksdb/rocksdb/memory/memory_usage.h +25 -0
  449. package/deps/rocksdb/rocksdb/memtable/alloc_tracker.cc +62 -0
  450. package/deps/rocksdb/rocksdb/memtable/hash_linklist_rep.cc +844 -0
  451. package/deps/rocksdb/rocksdb/memtable/hash_linklist_rep.h +49 -0
  452. package/deps/rocksdb/rocksdb/memtable/hash_skiplist_rep.cc +349 -0
  453. package/deps/rocksdb/rocksdb/memtable/hash_skiplist_rep.h +44 -0
  454. package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +997 -0
  455. package/deps/rocksdb/rocksdb/memtable/inlineskiplist_test.cc +663 -0
  456. package/deps/rocksdb/rocksdb/memtable/memtablerep_bench.cc +677 -0
  457. package/deps/rocksdb/rocksdb/memtable/skiplist.h +496 -0
  458. package/deps/rocksdb/rocksdb/memtable/skiplist_test.cc +388 -0
  459. package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +280 -0
  460. package/deps/rocksdb/rocksdb/memtable/stl_wrappers.h +33 -0
  461. package/deps/rocksdb/rocksdb/memtable/vectorrep.cc +301 -0
  462. package/deps/rocksdb/rocksdb/memtable/write_buffer_manager.cc +148 -0
  463. package/deps/rocksdb/rocksdb/memtable/write_buffer_manager_test.cc +203 -0
  464. package/deps/rocksdb/rocksdb/monitoring/file_read_sample.h +23 -0
  465. package/deps/rocksdb/rocksdb/monitoring/histogram.cc +287 -0
  466. package/deps/rocksdb/rocksdb/monitoring/histogram.h +149 -0
  467. package/deps/rocksdb/rocksdb/monitoring/histogram_test.cc +231 -0
  468. package/deps/rocksdb/rocksdb/monitoring/histogram_windowing.cc +200 -0
  469. package/deps/rocksdb/rocksdb/monitoring/histogram_windowing.h +84 -0
  470. package/deps/rocksdb/rocksdb/monitoring/in_memory_stats_history.cc +49 -0
  471. package/deps/rocksdb/rocksdb/monitoring/in_memory_stats_history.h +74 -0
  472. package/deps/rocksdb/rocksdb/monitoring/instrumented_mutex.cc +71 -0
  473. package/deps/rocksdb/rocksdb/monitoring/instrumented_mutex.h +98 -0
  474. package/deps/rocksdb/rocksdb/monitoring/iostats_context.cc +62 -0
  475. package/deps/rocksdb/rocksdb/monitoring/iostats_context_imp.h +60 -0
  476. package/deps/rocksdb/rocksdb/monitoring/iostats_context_test.cc +29 -0
  477. package/deps/rocksdb/rocksdb/monitoring/perf_context.cc +566 -0
  478. package/deps/rocksdb/rocksdb/monitoring/perf_context_imp.h +97 -0
  479. package/deps/rocksdb/rocksdb/monitoring/perf_level.cc +28 -0
  480. package/deps/rocksdb/rocksdb/monitoring/perf_level_imp.h +18 -0
  481. package/deps/rocksdb/rocksdb/monitoring/perf_step_timer.h +79 -0
  482. package/deps/rocksdb/rocksdb/monitoring/persistent_stats_history.cc +169 -0
  483. package/deps/rocksdb/rocksdb/monitoring/persistent_stats_history.h +83 -0
  484. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +431 -0
  485. package/deps/rocksdb/rocksdb/monitoring/statistics.h +138 -0
  486. package/deps/rocksdb/rocksdb/monitoring/statistics_test.cc +47 -0
  487. package/deps/rocksdb/rocksdb/monitoring/stats_history_test.cc +652 -0
  488. package/deps/rocksdb/rocksdb/monitoring/thread_status_impl.cc +163 -0
  489. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.cc +314 -0
  490. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.h +233 -0
  491. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater_debug.cc +43 -0
  492. package/deps/rocksdb/rocksdb/monitoring/thread_status_util.cc +206 -0
  493. package/deps/rocksdb/rocksdb/monitoring/thread_status_util.h +134 -0
  494. package/deps/rocksdb/rocksdb/monitoring/thread_status_util_debug.cc +32 -0
  495. package/deps/rocksdb/rocksdb/options/cf_options.cc +1026 -0
  496. package/deps/rocksdb/rocksdb/options/cf_options.h +308 -0
  497. package/deps/rocksdb/rocksdb/options/configurable.cc +681 -0
  498. package/deps/rocksdb/rocksdb/options/configurable_helper.h +251 -0
  499. package/deps/rocksdb/rocksdb/options/configurable_test.cc +757 -0
  500. package/deps/rocksdb/rocksdb/options/configurable_test.h +127 -0
  501. package/deps/rocksdb/rocksdb/options/customizable.cc +77 -0
  502. package/deps/rocksdb/rocksdb/options/customizable_helper.h +216 -0
  503. package/deps/rocksdb/rocksdb/options/customizable_test.cc +625 -0
  504. package/deps/rocksdb/rocksdb/options/db_options.cc +835 -0
  505. package/deps/rocksdb/rocksdb/options/db_options.h +126 -0
  506. package/deps/rocksdb/rocksdb/options/options.cc +664 -0
  507. package/deps/rocksdb/rocksdb/options/options_helper.cc +1391 -0
  508. package/deps/rocksdb/rocksdb/options/options_helper.h +118 -0
  509. package/deps/rocksdb/rocksdb/options/options_parser.cc +721 -0
  510. package/deps/rocksdb/rocksdb/options/options_parser.h +151 -0
  511. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +583 -0
  512. package/deps/rocksdb/rocksdb/options/options_test.cc +3794 -0
  513. package/deps/rocksdb/rocksdb/port/jemalloc_helper.h +106 -0
  514. package/deps/rocksdb/rocksdb/port/lang.h +16 -0
  515. package/deps/rocksdb/rocksdb/port/likely.h +18 -0
  516. package/deps/rocksdb/rocksdb/port/malloc.h +17 -0
  517. package/deps/rocksdb/rocksdb/port/port.h +21 -0
  518. package/deps/rocksdb/rocksdb/port/port_dirent.h +44 -0
  519. package/deps/rocksdb/rocksdb/port/port_example.h +101 -0
  520. package/deps/rocksdb/rocksdb/port/port_posix.cc +266 -0
  521. package/deps/rocksdb/rocksdb/port/port_posix.h +223 -0
  522. package/deps/rocksdb/rocksdb/port/stack_trace.cc +179 -0
  523. package/deps/rocksdb/rocksdb/port/stack_trace.h +28 -0
  524. package/deps/rocksdb/rocksdb/port/sys_time.h +47 -0
  525. package/deps/rocksdb/rocksdb/port/util_logger.h +20 -0
  526. package/deps/rocksdb/rocksdb/port/win/env_default.cc +45 -0
  527. package/deps/rocksdb/rocksdb/port/win/env_win.cc +1449 -0
  528. package/deps/rocksdb/rocksdb/port/win/env_win.h +294 -0
  529. package/deps/rocksdb/rocksdb/port/win/io_win.cc +1084 -0
  530. package/deps/rocksdb/rocksdb/port/win/io_win.h +494 -0
  531. package/deps/rocksdb/rocksdb/port/win/port_win.cc +283 -0
  532. package/deps/rocksdb/rocksdb/port/win/port_win.h +411 -0
  533. package/deps/rocksdb/rocksdb/port/win/win_jemalloc.cc +79 -0
  534. package/deps/rocksdb/rocksdb/port/win/win_logger.cc +194 -0
  535. package/deps/rocksdb/rocksdb/port/win/win_logger.h +67 -0
  536. package/deps/rocksdb/rocksdb/port/win/win_thread.cc +183 -0
  537. package/deps/rocksdb/rocksdb/port/win/win_thread.h +122 -0
  538. package/deps/rocksdb/rocksdb/port/win/xpress_win.cc +221 -0
  539. package/deps/rocksdb/rocksdb/port/win/xpress_win.h +26 -0
  540. package/deps/rocksdb/rocksdb/port/xpress.h +17 -0
  541. package/deps/rocksdb/rocksdb/src.mk +631 -0
  542. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.cc +126 -0
  543. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.h +57 -0
  544. package/deps/rocksdb/rocksdb/table/block_based/binary_search_index_reader.cc +73 -0
  545. package/deps/rocksdb/rocksdb/table/block_based/binary_search_index_reader.h +48 -0
  546. package/deps/rocksdb/rocksdb/table/block_based/block.cc +1049 -0
  547. package/deps/rocksdb/rocksdb/table/block_based/block.h +720 -0
  548. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.cc +348 -0
  549. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.h +119 -0
  550. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block_test.cc +434 -0
  551. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +1835 -0
  552. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +193 -0
  553. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +839 -0
  554. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +95 -0
  555. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +383 -0
  556. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +251 -0
  557. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +3563 -0
  558. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +681 -0
  559. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +190 -0
  560. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +347 -0
  561. package/deps/rocksdb/rocksdb/table/block_based/block_builder.cc +201 -0
  562. package/deps/rocksdb/rocksdb/table/block_based/block_builder.h +78 -0
  563. package/deps/rocksdb/rocksdb/table/block_based/block_prefetcher.cc +66 -0
  564. package/deps/rocksdb/rocksdb/table/block_based/block_prefetcher.h +32 -0
  565. package/deps/rocksdb/rocksdb/table/block_based/block_prefix_index.cc +232 -0
  566. package/deps/rocksdb/rocksdb/table/block_based/block_prefix_index.h +66 -0
  567. package/deps/rocksdb/rocksdb/table/block_based/block_test.cc +623 -0
  568. package/deps/rocksdb/rocksdb/table/block_based/block_type.h +30 -0
  569. package/deps/rocksdb/rocksdb/table/block_based/cachable_entry.h +220 -0
  570. package/deps/rocksdb/rocksdb/table/block_based/data_block_footer.cc +59 -0
  571. package/deps/rocksdb/rocksdb/table/block_based/data_block_footer.h +25 -0
  572. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index.cc +93 -0
  573. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index.h +136 -0
  574. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +717 -0
  575. package/deps/rocksdb/rocksdb/table/block_based/filter_block.h +180 -0
  576. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +102 -0
  577. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.h +55 -0
  578. package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +1407 -0
  579. package/deps/rocksdb/rocksdb/table/block_based/filter_policy_internal.h +168 -0
  580. package/deps/rocksdb/rocksdb/table/block_based/flush_block_policy.cc +88 -0
  581. package/deps/rocksdb/rocksdb/table/block_based/flush_block_policy.h +41 -0
  582. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +344 -0
  583. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.h +139 -0
  584. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +333 -0
  585. package/deps/rocksdb/rocksdb/table/block_based/hash_index_reader.cc +147 -0
  586. package/deps/rocksdb/rocksdb/table/block_based/hash_index_reader.h +49 -0
  587. package/deps/rocksdb/rocksdb/table/block_based/index_builder.cc +248 -0
  588. package/deps/rocksdb/rocksdb/table/block_based/index_builder.h +444 -0
  589. package/deps/rocksdb/rocksdb/table/block_based/index_reader_common.cc +54 -0
  590. package/deps/rocksdb/rocksdb/table/block_based/index_reader_common.h +85 -0
  591. package/deps/rocksdb/rocksdb/table/block_based/mock_block_based_table.h +56 -0
  592. package/deps/rocksdb/rocksdb/table/block_based/parsed_full_filter_block.cc +22 -0
  593. package/deps/rocksdb/rocksdb/table/block_based/parsed_full_filter_block.h +40 -0
  594. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +521 -0
  595. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +144 -0
  596. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +424 -0
  597. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_iterator.cc +163 -0
  598. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_iterator.h +142 -0
  599. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_reader.cc +186 -0
  600. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_reader.h +51 -0
  601. package/deps/rocksdb/rocksdb/table/block_based/reader_common.cc +64 -0
  602. package/deps/rocksdb/rocksdb/table/block_based/reader_common.h +38 -0
  603. package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.cc +120 -0
  604. package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.h +59 -0
  605. package/deps/rocksdb/rocksdb/table/block_fetcher.cc +324 -0
  606. package/deps/rocksdb/rocksdb/table/block_fetcher.h +129 -0
  607. package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +534 -0
  608. package/deps/rocksdb/rocksdb/table/cleanable_test.cc +277 -0
  609. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder.cc +543 -0
  610. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder.h +136 -0
  611. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder_test.cc +663 -0
  612. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_factory.cc +107 -0
  613. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_factory.h +81 -0
  614. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader.cc +404 -0
  615. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader.h +101 -0
  616. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader_test.cc +585 -0
  617. package/deps/rocksdb/rocksdb/table/format.cc +422 -0
  618. package/deps/rocksdb/rocksdb/table/format.h +348 -0
  619. package/deps/rocksdb/rocksdb/table/get_context.cc +408 -0
  620. package/deps/rocksdb/rocksdb/table/get_context.h +212 -0
  621. package/deps/rocksdb/rocksdb/table/internal_iterator.h +205 -0
  622. package/deps/rocksdb/rocksdb/table/iter_heap.h +42 -0
  623. package/deps/rocksdb/rocksdb/table/iterator.cc +210 -0
  624. package/deps/rocksdb/rocksdb/table/iterator_wrapper.h +180 -0
  625. package/deps/rocksdb/rocksdb/table/merger_test.cc +180 -0
  626. package/deps/rocksdb/rocksdb/table/merging_iterator.cc +481 -0
  627. package/deps/rocksdb/rocksdb/table/merging_iterator.h +64 -0
  628. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +541 -0
  629. package/deps/rocksdb/rocksdb/table/meta_blocks.h +154 -0
  630. package/deps/rocksdb/rocksdb/table/mock_table.cc +328 -0
  631. package/deps/rocksdb/rocksdb/table/mock_table.h +89 -0
  632. package/deps/rocksdb/rocksdb/table/multiget_context.h +282 -0
  633. package/deps/rocksdb/rocksdb/table/persistent_cache_helper.cc +116 -0
  634. package/deps/rocksdb/rocksdb/table/persistent_cache_helper.h +44 -0
  635. package/deps/rocksdb/rocksdb/table/persistent_cache_options.h +34 -0
  636. package/deps/rocksdb/rocksdb/table/plain/plain_table_bloom.cc +78 -0
  637. package/deps/rocksdb/rocksdb/table/plain/plain_table_bloom.h +135 -0
  638. package/deps/rocksdb/rocksdb/table/plain/plain_table_builder.cc +332 -0
  639. package/deps/rocksdb/rocksdb/table/plain/plain_table_builder.h +153 -0
  640. package/deps/rocksdb/rocksdb/table/plain/plain_table_factory.cc +263 -0
  641. package/deps/rocksdb/rocksdb/table/plain/plain_table_factory.h +182 -0
  642. package/deps/rocksdb/rocksdb/table/plain/plain_table_index.cc +211 -0
  643. package/deps/rocksdb/rocksdb/table/plain/plain_table_index.h +249 -0
  644. package/deps/rocksdb/rocksdb/table/plain/plain_table_key_coding.cc +506 -0
  645. package/deps/rocksdb/rocksdb/table/plain/plain_table_key_coding.h +201 -0
  646. package/deps/rocksdb/rocksdb/table/plain/plain_table_reader.cc +781 -0
  647. package/deps/rocksdb/rocksdb/table/plain/plain_table_reader.h +247 -0
  648. package/deps/rocksdb/rocksdb/table/scoped_arena_iterator.h +61 -0
  649. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +502 -0
  650. package/deps/rocksdb/rocksdb/table/sst_file_dumper.h +96 -0
  651. package/deps/rocksdb/rocksdb/table/sst_file_reader.cc +98 -0
  652. package/deps/rocksdb/rocksdb/table/sst_file_reader_test.cc +228 -0
  653. package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +340 -0
  654. package/deps/rocksdb/rocksdb/table/sst_file_writer_collectors.h +94 -0
  655. package/deps/rocksdb/rocksdb/table/table_builder.h +203 -0
  656. package/deps/rocksdb/rocksdb/table/table_factory.cc +38 -0
  657. package/deps/rocksdb/rocksdb/table/table_properties.cc +300 -0
  658. package/deps/rocksdb/rocksdb/table/table_properties_internal.h +30 -0
  659. package/deps/rocksdb/rocksdb/table/table_reader.h +147 -0
  660. package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +347 -0
  661. package/deps/rocksdb/rocksdb/table/table_reader_caller.h +39 -0
  662. package/deps/rocksdb/rocksdb/table/table_test.cc +4769 -0
  663. package/deps/rocksdb/rocksdb/table/two_level_iterator.cc +215 -0
  664. package/deps/rocksdb/rocksdb/table/two_level_iterator.h +43 -0
  665. package/deps/rocksdb/rocksdb/test_util/mock_time_env.cc +38 -0
  666. package/deps/rocksdb/rocksdb/test_util/mock_time_env.h +74 -0
  667. package/deps/rocksdb/rocksdb/test_util/sync_point.cc +93 -0
  668. package/deps/rocksdb/rocksdb/test_util/sync_point.h +161 -0
  669. package/deps/rocksdb/rocksdb/test_util/sync_point_impl.cc +129 -0
  670. package/deps/rocksdb/rocksdb/test_util/sync_point_impl.h +74 -0
  671. package/deps/rocksdb/rocksdb/test_util/testharness.cc +56 -0
  672. package/deps/rocksdb/rocksdb/test_util/testharness.h +53 -0
  673. package/deps/rocksdb/rocksdb/test_util/testutil.cc +566 -0
  674. package/deps/rocksdb/rocksdb/test_util/testutil.h +887 -0
  675. package/deps/rocksdb/rocksdb/test_util/testutil_test.cc +43 -0
  676. package/deps/rocksdb/rocksdb/test_util/transaction_test_util.cc +388 -0
  677. package/deps/rocksdb/rocksdb/test_util/transaction_test_util.h +132 -0
  678. package/deps/rocksdb/rocksdb/third-party/folly/folly/CPortability.h +27 -0
  679. package/deps/rocksdb/rocksdb/third-party/folly/folly/ConstexprMath.h +45 -0
  680. package/deps/rocksdb/rocksdb/third-party/folly/folly/Indestructible.h +166 -0
  681. package/deps/rocksdb/rocksdb/third-party/folly/folly/Optional.h +570 -0
  682. package/deps/rocksdb/rocksdb/third-party/folly/folly/Portability.h +92 -0
  683. package/deps/rocksdb/rocksdb/third-party/folly/folly/ScopeGuard.h +54 -0
  684. package/deps/rocksdb/rocksdb/third-party/folly/folly/Traits.h +152 -0
  685. package/deps/rocksdb/rocksdb/third-party/folly/folly/Unit.h +59 -0
  686. package/deps/rocksdb/rocksdb/third-party/folly/folly/Utility.h +141 -0
  687. package/deps/rocksdb/rocksdb/third-party/folly/folly/chrono/Hardware.h +33 -0
  688. package/deps/rocksdb/rocksdb/third-party/folly/folly/container/Array.h +74 -0
  689. package/deps/rocksdb/rocksdb/third-party/folly/folly/detail/Futex-inl.h +117 -0
  690. package/deps/rocksdb/rocksdb/third-party/folly/folly/detail/Futex.cpp +263 -0
  691. package/deps/rocksdb/rocksdb/third-party/folly/folly/detail/Futex.h +96 -0
  692. package/deps/rocksdb/rocksdb/third-party/folly/folly/functional/Invoke.h +40 -0
  693. package/deps/rocksdb/rocksdb/third-party/folly/folly/hash/Hash.h +29 -0
  694. package/deps/rocksdb/rocksdb/third-party/folly/folly/lang/Align.h +144 -0
  695. package/deps/rocksdb/rocksdb/third-party/folly/folly/lang/Bits.h +30 -0
  696. package/deps/rocksdb/rocksdb/third-party/folly/folly/lang/Launder.h +51 -0
  697. package/deps/rocksdb/rocksdb/third-party/folly/folly/portability/Asm.h +28 -0
  698. package/deps/rocksdb/rocksdb/third-party/folly/folly/portability/SysSyscall.h +10 -0
  699. package/deps/rocksdb/rocksdb/third-party/folly/folly/portability/SysTypes.h +26 -0
  700. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicNotification-inl.h +138 -0
  701. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicNotification.cpp +23 -0
  702. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicNotification.h +57 -0
  703. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicUtil-inl.h +260 -0
  704. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicUtil.h +52 -0
  705. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/Baton.h +328 -0
  706. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/DistributedMutex-inl.h +1703 -0
  707. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/DistributedMutex.cpp +16 -0
  708. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/DistributedMutex.h +304 -0
  709. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/DistributedMutexSpecializations.h +39 -0
  710. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/ParkingLot.cpp +26 -0
  711. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/ParkingLot.h +318 -0
  712. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/WaitOptions.cpp +12 -0
  713. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/WaitOptions.h +57 -0
  714. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/InlineFunctionRef.h +219 -0
  715. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/ProxyLockable-inl.h +207 -0
  716. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/ProxyLockable.h +164 -0
  717. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/Sleeper.h +57 -0
  718. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/Spin.h +77 -0
  719. package/deps/rocksdb/rocksdb/third-party/gcc/ppc-asm.h +390 -0
  720. package/deps/rocksdb/rocksdb/thirdparty.inc +268 -0
  721. package/deps/rocksdb/rocksdb/tools/CMakeLists.txt +30 -0
  722. package/deps/rocksdb/rocksdb/tools/blob_dump.cc +110 -0
  723. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/__init__.py +2 -0
  724. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim.py +2000 -0
  725. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim.sh +156 -0
  726. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_pysim_test.py +734 -0
  727. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer.cc +2307 -0
  728. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer.h +395 -0
  729. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_plot.py +721 -0
  730. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc +719 -0
  731. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_tool.cc +25 -0
  732. package/deps/rocksdb/rocksdb/tools/db_bench.cc +21 -0
  733. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +7416 -0
  734. package/deps/rocksdb/rocksdb/tools/db_bench_tool_test.cc +328 -0
  735. package/deps/rocksdb/rocksdb/tools/db_repl_stress.cc +130 -0
  736. package/deps/rocksdb/rocksdb/tools/db_sanity_test.cc +297 -0
  737. package/deps/rocksdb/rocksdb/tools/dump/db_dump_tool.cc +259 -0
  738. package/deps/rocksdb/rocksdb/tools/dump/rocksdb_dump.cc +63 -0
  739. package/deps/rocksdb/rocksdb/tools/dump/rocksdb_undump.cc +62 -0
  740. package/deps/rocksdb/rocksdb/tools/io_tracer_parser.cc +25 -0
  741. package/deps/rocksdb/rocksdb/tools/io_tracer_parser_test.cc +187 -0
  742. package/deps/rocksdb/rocksdb/tools/io_tracer_parser_tool.cc +120 -0
  743. package/deps/rocksdb/rocksdb/tools/io_tracer_parser_tool.h +40 -0
  744. package/deps/rocksdb/rocksdb/tools/ldb.cc +21 -0
  745. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +3609 -0
  746. package/deps/rocksdb/rocksdb/tools/ldb_cmd_impl.h +665 -0
  747. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +746 -0
  748. package/deps/rocksdb/rocksdb/tools/ldb_tool.cc +159 -0
  749. package/deps/rocksdb/rocksdb/tools/reduce_levels_test.cc +221 -0
  750. package/deps/rocksdb/rocksdb/tools/sst_dump.cc +20 -0
  751. package/deps/rocksdb/rocksdb/tools/sst_dump_test.cc +427 -0
  752. package/deps/rocksdb/rocksdb/tools/sst_dump_tool.cc +541 -0
  753. package/deps/rocksdb/rocksdb/tools/trace_analyzer.cc +25 -0
  754. package/deps/rocksdb/rocksdb/tools/trace_analyzer_test.cc +752 -0
  755. package/deps/rocksdb/rocksdb/tools/trace_analyzer_tool.cc +2001 -0
  756. package/deps/rocksdb/rocksdb/tools/trace_analyzer_tool.h +292 -0
  757. package/deps/rocksdb/rocksdb/tools/write_stress.cc +305 -0
  758. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer.cc +496 -0
  759. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer.h +294 -0
  760. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer_test.cc +379 -0
  761. package/deps/rocksdb/rocksdb/trace_replay/io_tracer.cc +229 -0
  762. package/deps/rocksdb/rocksdb/trace_replay/io_tracer.h +174 -0
  763. package/deps/rocksdb/rocksdb/trace_replay/io_tracer_test.cc +215 -0
  764. package/deps/rocksdb/rocksdb/trace_replay/trace_replay.cc +491 -0
  765. package/deps/rocksdb/rocksdb/trace_replay/trace_replay.h +195 -0
  766. package/deps/rocksdb/rocksdb/util/aligned_buffer.h +255 -0
  767. package/deps/rocksdb/rocksdb/util/autovector.h +367 -0
  768. package/deps/rocksdb/rocksdb/util/autovector_test.cc +330 -0
  769. package/deps/rocksdb/rocksdb/util/bloom_impl.h +485 -0
  770. package/deps/rocksdb/rocksdb/util/bloom_test.cc +1191 -0
  771. package/deps/rocksdb/rocksdb/util/build_version.cc.in +5 -0
  772. package/deps/rocksdb/rocksdb/util/build_version.h +15 -0
  773. package/deps/rocksdb/rocksdb/util/cast_util.h +20 -0
  774. package/deps/rocksdb/rocksdb/util/channel.h +67 -0
  775. package/deps/rocksdb/rocksdb/util/coding.cc +89 -0
  776. package/deps/rocksdb/rocksdb/util/coding.h +419 -0
  777. package/deps/rocksdb/rocksdb/util/coding_lean.h +101 -0
  778. package/deps/rocksdb/rocksdb/util/coding_test.cc +217 -0
  779. package/deps/rocksdb/rocksdb/util/compaction_job_stats_impl.cc +92 -0
  780. package/deps/rocksdb/rocksdb/util/comparator.cc +219 -0
  781. package/deps/rocksdb/rocksdb/util/compression.h +1529 -0
  782. package/deps/rocksdb/rocksdb/util/compression_context_cache.cc +108 -0
  783. package/deps/rocksdb/rocksdb/util/compression_context_cache.h +47 -0
  784. package/deps/rocksdb/rocksdb/util/concurrent_task_limiter_impl.cc +67 -0
  785. package/deps/rocksdb/rocksdb/util/concurrent_task_limiter_impl.h +67 -0
  786. package/deps/rocksdb/rocksdb/util/core_local.h +83 -0
  787. package/deps/rocksdb/rocksdb/util/crc32c.cc +1283 -0
  788. package/deps/rocksdb/rocksdb/util/crc32c.h +51 -0
  789. package/deps/rocksdb/rocksdb/util/crc32c_arm64.cc +169 -0
  790. package/deps/rocksdb/rocksdb/util/crc32c_arm64.h +50 -0
  791. package/deps/rocksdb/rocksdb/util/crc32c_ppc.c +94 -0
  792. package/deps/rocksdb/rocksdb/util/crc32c_ppc.h +19 -0
  793. package/deps/rocksdb/rocksdb/util/crc32c_ppc_asm.S +756 -0
  794. package/deps/rocksdb/rocksdb/util/crc32c_ppc_constants.h +900 -0
  795. package/deps/rocksdb/rocksdb/util/crc32c_test.cc +180 -0
  796. package/deps/rocksdb/rocksdb/util/defer.h +52 -0
  797. package/deps/rocksdb/rocksdb/util/defer_test.cc +39 -0
  798. package/deps/rocksdb/rocksdb/util/duplicate_detector.h +68 -0
  799. package/deps/rocksdb/rocksdb/util/dynamic_bloom.cc +70 -0
  800. package/deps/rocksdb/rocksdb/util/dynamic_bloom.h +214 -0
  801. package/deps/rocksdb/rocksdb/util/dynamic_bloom_test.cc +323 -0
  802. package/deps/rocksdb/rocksdb/util/fastrange.h +112 -0
  803. package/deps/rocksdb/rocksdb/util/file_checksum_helper.cc +136 -0
  804. package/deps/rocksdb/rocksdb/util/file_checksum_helper.h +98 -0
  805. package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +449 -0
  806. package/deps/rocksdb/rocksdb/util/filelock_test.cc +152 -0
  807. package/deps/rocksdb/rocksdb/util/filter_bench.cc +781 -0
  808. package/deps/rocksdb/rocksdb/util/gflags_compat.h +20 -0
  809. package/deps/rocksdb/rocksdb/util/hash.cc +83 -0
  810. package/deps/rocksdb/rocksdb/util/hash.h +107 -0
  811. package/deps/rocksdb/rocksdb/util/hash_map.h +67 -0
  812. package/deps/rocksdb/rocksdb/util/hash_test.cc +593 -0
  813. package/deps/rocksdb/rocksdb/util/heap.h +166 -0
  814. package/deps/rocksdb/rocksdb/util/heap_test.cc +139 -0
  815. package/deps/rocksdb/rocksdb/util/kv_map.h +33 -0
  816. package/deps/rocksdb/rocksdb/util/log_write_bench.cc +86 -0
  817. package/deps/rocksdb/rocksdb/util/math.h +186 -0
  818. package/deps/rocksdb/rocksdb/util/math128.h +298 -0
  819. package/deps/rocksdb/rocksdb/util/murmurhash.cc +191 -0
  820. package/deps/rocksdb/rocksdb/util/murmurhash.h +42 -0
  821. package/deps/rocksdb/rocksdb/util/mutexlock.h +186 -0
  822. package/deps/rocksdb/rocksdb/util/ppc-opcode.h +27 -0
  823. package/deps/rocksdb/rocksdb/util/random.cc +56 -0
  824. package/deps/rocksdb/rocksdb/util/random.h +186 -0
  825. package/deps/rocksdb/rocksdb/util/random_test.cc +105 -0
  826. package/deps/rocksdb/rocksdb/util/rate_limiter.cc +340 -0
  827. package/deps/rocksdb/rocksdb/util/rate_limiter.h +113 -0
  828. package/deps/rocksdb/rocksdb/util/rate_limiter_test.cc +251 -0
  829. package/deps/rocksdb/rocksdb/util/repeatable_thread.h +151 -0
  830. package/deps/rocksdb/rocksdb/util/repeatable_thread_test.cc +107 -0
  831. package/deps/rocksdb/rocksdb/util/ribbon_alg.h +1201 -0
  832. package/deps/rocksdb/rocksdb/util/ribbon_impl.h +1062 -0
  833. package/deps/rocksdb/rocksdb/util/ribbon_test.cc +931 -0
  834. package/deps/rocksdb/rocksdb/util/set_comparator.h +22 -0
  835. package/deps/rocksdb/rocksdb/util/slice.cc +243 -0
  836. package/deps/rocksdb/rocksdb/util/slice_test.cc +163 -0
  837. package/deps/rocksdb/rocksdb/util/slice_transform_test.cc +153 -0
  838. package/deps/rocksdb/rocksdb/util/status.cc +149 -0
  839. package/deps/rocksdb/rocksdb/util/stderr_logger.h +31 -0
  840. package/deps/rocksdb/rocksdb/util/stop_watch.h +118 -0
  841. package/deps/rocksdb/rocksdb/util/string_util.cc +422 -0
  842. package/deps/rocksdb/rocksdb/util/string_util.h +144 -0
  843. package/deps/rocksdb/rocksdb/util/thread_list_test.cc +354 -0
  844. package/deps/rocksdb/rocksdb/util/thread_local.cc +554 -0
  845. package/deps/rocksdb/rocksdb/util/thread_local.h +101 -0
  846. package/deps/rocksdb/rocksdb/util/thread_local_test.cc +583 -0
  847. package/deps/rocksdb/rocksdb/util/thread_operation.h +121 -0
  848. package/deps/rocksdb/rocksdb/util/threadpool_imp.cc +506 -0
  849. package/deps/rocksdb/rocksdb/util/threadpool_imp.h +112 -0
  850. package/deps/rocksdb/rocksdb/util/timer.h +331 -0
  851. package/deps/rocksdb/rocksdb/util/timer_queue.h +230 -0
  852. package/deps/rocksdb/rocksdb/util/timer_queue_test.cc +72 -0
  853. package/deps/rocksdb/rocksdb/util/timer_test.cc +399 -0
  854. package/deps/rocksdb/rocksdb/util/user_comparator_wrapper.h +80 -0
  855. package/deps/rocksdb/rocksdb/util/vector_iterator.h +101 -0
  856. package/deps/rocksdb/rocksdb/util/work_queue.h +148 -0
  857. package/deps/rocksdb/rocksdb/util/work_queue_test.cc +268 -0
  858. package/deps/rocksdb/rocksdb/util/xxh3p.h +1392 -0
  859. package/deps/rocksdb/rocksdb/util/xxhash.cc +1158 -0
  860. package/deps/rocksdb/rocksdb/util/xxhash.h +598 -0
  861. package/deps/rocksdb/rocksdb/utilities/backupable/backupable_db.cc +2354 -0
  862. package/deps/rocksdb/rocksdb/utilities/backupable/backupable_db_test.cc +2955 -0
  863. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.cc +488 -0
  864. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.h +199 -0
  865. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.cc +112 -0
  866. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.h +266 -0
  867. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_gc_stats.h +52 -0
  868. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.cc +2167 -0
  869. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.h +500 -0
  870. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl_filesnapshot.cc +113 -0
  871. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_iterator.h +147 -0
  872. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_listener.h +66 -0
  873. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_test.cc +2386 -0
  874. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_dump_tool.cc +281 -0
  875. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_dump_tool.h +58 -0
  876. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.cc +314 -0
  877. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.h +244 -0
  878. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_compaction_filter.cc +47 -0
  879. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_compaction_filter.h +42 -0
  880. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_format_test.cc +375 -0
  881. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_functional_test.cc +327 -0
  882. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_row_merge_test.cc +114 -0
  883. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_serialize_test.cc +187 -0
  884. package/deps/rocksdb/rocksdb/utilities/cassandra/format.cc +390 -0
  885. package/deps/rocksdb/rocksdb/utilities/cassandra/format.h +184 -0
  886. package/deps/rocksdb/rocksdb/utilities/cassandra/merge_operator.cc +67 -0
  887. package/deps/rocksdb/rocksdb/utilities/cassandra/merge_operator.h +44 -0
  888. package/deps/rocksdb/rocksdb/utilities/cassandra/serialize.h +75 -0
  889. package/deps/rocksdb/rocksdb/utilities/cassandra/test_utils.cc +72 -0
  890. package/deps/rocksdb/rocksdb/utilities/cassandra/test_utils.h +43 -0
  891. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.cc +588 -0
  892. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.h +82 -0
  893. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +821 -0
  894. package/deps/rocksdb/rocksdb/utilities/compaction_filters/layered_compaction_filter_base.h +37 -0
  895. package/deps/rocksdb/rocksdb/utilities/compaction_filters/remove_emptyvalue_compactionfilter.cc +29 -0
  896. package/deps/rocksdb/rocksdb/utilities/compaction_filters/remove_emptyvalue_compactionfilter.h +27 -0
  897. package/deps/rocksdb/rocksdb/utilities/convenience/info_log_finder.cc +25 -0
  898. package/deps/rocksdb/rocksdb/utilities/debug.cc +82 -0
  899. package/deps/rocksdb/rocksdb/utilities/env_librados.cc +1497 -0
  900. package/deps/rocksdb/rocksdb/utilities/env_librados_test.cc +1146 -0
  901. package/deps/rocksdb/rocksdb/utilities/env_mirror.cc +262 -0
  902. package/deps/rocksdb/rocksdb/utilities/env_mirror_test.cc +223 -0
  903. package/deps/rocksdb/rocksdb/utilities/env_timed.cc +145 -0
  904. package/deps/rocksdb/rocksdb/utilities/env_timed_test.cc +44 -0
  905. package/deps/rocksdb/rocksdb/utilities/fault_injection_env.cc +490 -0
  906. package/deps/rocksdb/rocksdb/utilities/fault_injection_env.h +242 -0
  907. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.cc +581 -0
  908. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.h +437 -0
  909. package/deps/rocksdb/rocksdb/utilities/leveldb_options/leveldb_options.cc +56 -0
  910. package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +275 -0
  911. package/deps/rocksdb/rocksdb/utilities/memory/memory_util.cc +52 -0
  912. package/deps/rocksdb/rocksdb/utilities/merge_operators/bytesxor.cc +59 -0
  913. package/deps/rocksdb/rocksdb/utilities/merge_operators/bytesxor.h +39 -0
  914. package/deps/rocksdb/rocksdb/utilities/merge_operators/max.cc +77 -0
  915. package/deps/rocksdb/rocksdb/utilities/merge_operators/put.cc +83 -0
  916. package/deps/rocksdb/rocksdb/utilities/merge_operators/sortlist.cc +97 -0
  917. package/deps/rocksdb/rocksdb/utilities/merge_operators/sortlist.h +38 -0
  918. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend.cc +59 -0
  919. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend.h +31 -0
  920. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend2.cc +117 -0
  921. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend2.h +49 -0
  922. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend_test.cc +598 -0
  923. package/deps/rocksdb/rocksdb/utilities/merge_operators/uint64add.cc +69 -0
  924. package/deps/rocksdb/rocksdb/utilities/merge_operators.h +55 -0
  925. package/deps/rocksdb/rocksdb/utilities/object_registry.cc +87 -0
  926. package/deps/rocksdb/rocksdb/utilities/object_registry_test.cc +174 -0
  927. package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration.cc +168 -0
  928. package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration_test.cc +431 -0
  929. package/deps/rocksdb/rocksdb/utilities/options/options_util.cc +159 -0
  930. package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +655 -0
  931. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier.cc +425 -0
  932. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier.h +156 -0
  933. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.cc +609 -0
  934. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.h +296 -0
  935. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file_buffer.h +127 -0
  936. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_metadata.cc +86 -0
  937. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_metadata.h +125 -0
  938. package/deps/rocksdb/rocksdb/utilities/persistent_cache/hash_table.h +238 -0
  939. package/deps/rocksdb/rocksdb/utilities/persistent_cache/hash_table_bench.cc +308 -0
  940. package/deps/rocksdb/rocksdb/utilities/persistent_cache/hash_table_evictable.h +168 -0
  941. package/deps/rocksdb/rocksdb/utilities/persistent_cache/hash_table_test.cc +160 -0
  942. package/deps/rocksdb/rocksdb/utilities/persistent_cache/lrulist.h +174 -0
  943. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_bench.cc +360 -0
  944. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_test.cc +456 -0
  945. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_test.h +286 -0
  946. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_tier.cc +167 -0
  947. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_tier.h +339 -0
  948. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_util.h +67 -0
  949. package/deps/rocksdb/rocksdb/utilities/persistent_cache/volatile_tier_impl.cc +140 -0
  950. package/deps/rocksdb/rocksdb/utilities/persistent_cache/volatile_tier_impl.h +142 -0
  951. package/deps/rocksdb/rocksdb/utilities/simulator_cache/cache_simulator.cc +285 -0
  952. package/deps/rocksdb/rocksdb/utilities/simulator_cache/cache_simulator.h +231 -0
  953. package/deps/rocksdb/rocksdb/utilities/simulator_cache/cache_simulator_test.cc +494 -0
  954. package/deps/rocksdb/rocksdb/utilities/simulator_cache/sim_cache.cc +356 -0
  955. package/deps/rocksdb/rocksdb/utilities/simulator_cache/sim_cache_test.cc +224 -0
  956. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_on_deletion_collector.cc +122 -0
  957. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_on_deletion_collector.h +72 -0
  958. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_on_deletion_collector_test.cc +244 -0
  959. package/deps/rocksdb/rocksdb/utilities/trace/file_trace_reader_writer.cc +125 -0
  960. package/deps/rocksdb/rocksdb/utilities/trace/file_trace_reader_writer.h +48 -0
  961. package/deps/rocksdb/rocksdb/utilities/transactions/lock/lock_manager.cc +29 -0
  962. package/deps/rocksdb/rocksdb/utilities/transactions/lock/lock_manager.h +82 -0
  963. package/deps/rocksdb/rocksdb/utilities/transactions/lock/lock_tracker.h +209 -0
  964. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager.cc +720 -0
  965. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager.h +223 -0
  966. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager_test.cc +181 -0
  967. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager_test.h +319 -0
  968. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_tracker.cc +270 -0
  969. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_tracker.h +99 -0
  970. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_lock_manager.h +30 -0
  971. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_locking_test.cc +306 -0
  972. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/COPYING.AGPLv3 +661 -0
  973. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/COPYING.APACHEv2 +174 -0
  974. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/COPYING.GPLv2 +339 -0
  975. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/db.h +76 -0
  976. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/ft/comparator.h +138 -0
  977. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/ft/ft-status.h +102 -0
  978. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/concurrent_tree.cc +139 -0
  979. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/concurrent_tree.h +174 -0
  980. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/keyrange.cc +222 -0
  981. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/keyrange.h +141 -0
  982. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/lock_request.cc +525 -0
  983. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/lock_request.h +253 -0
  984. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/locktree.cc +1007 -0
  985. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/locktree.h +560 -0
  986. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/manager.cc +527 -0
  987. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/range_buffer.cc +265 -0
  988. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/range_buffer.h +178 -0
  989. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/treenode.cc +520 -0
  990. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/treenode.h +302 -0
  991. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/txnid_set.cc +120 -0
  992. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/txnid_set.h +92 -0
  993. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/wfg.cc +213 -0
  994. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/wfg.h +124 -0
  995. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/memory.h +215 -0
  996. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_assert_subst.h +39 -0
  997. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_atomic.h +130 -0
  998. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_external_pthread.h +82 -0
  999. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_instrumentation.h +286 -0
  1000. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_portability.h +87 -0
  1001. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_pthread.h +520 -0
  1002. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_race_tools.h +179 -0
  1003. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_time.h +172 -0
  1004. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/txn_subst.h +27 -0
  1005. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/standalone_port.cc +132 -0
  1006. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/util/dbt.cc +153 -0
  1007. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/util/dbt.h +98 -0
  1008. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/util/growable_array.h +144 -0
  1009. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/util/memarena.cc +201 -0
  1010. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/util/memarena.h +141 -0
  1011. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/util/omt.h +794 -0
  1012. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/util/omt_impl.h +1295 -0
  1013. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/util/partitioned_counter.h +165 -0
  1014. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/util/status.h +76 -0
  1015. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/range_tree_lock_manager.cc +479 -0
  1016. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/range_tree_lock_manager.h +130 -0
  1017. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/range_tree_lock_tracker.cc +156 -0
  1018. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/range_tree_lock_tracker.h +146 -0
  1019. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction.cc +196 -0
  1020. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction.h +101 -0
  1021. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_db_impl.cc +111 -0
  1022. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_db_impl.h +87 -0
  1023. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_test.cc +1418 -0
  1024. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.cc +752 -0
  1025. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.h +232 -0
  1026. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.cc +628 -0
  1027. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.h +228 -0
  1028. package/deps/rocksdb/rocksdb/utilities/transactions/snapshot_checker.cc +49 -0
  1029. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +678 -0
  1030. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.h +373 -0
  1031. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_db_mutex_impl.cc +135 -0
  1032. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_db_mutex_impl.h +26 -0
  1033. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +6350 -0
  1034. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.h +522 -0
  1035. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_util.cc +188 -0
  1036. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_util.h +80 -0
  1037. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +3531 -0
  1038. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +483 -0
  1039. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.h +119 -0
  1040. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.cc +999 -0
  1041. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.h +1109 -0
  1042. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_transaction_test.cc +786 -0
  1043. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn.cc +1039 -0
  1044. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn.h +341 -0
  1045. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn_db.cc +470 -0
  1046. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn_db.h +108 -0
  1047. package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.cc +332 -0
  1048. package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.h +353 -0
  1049. package/deps/rocksdb/rocksdb/utilities/ttl/ttl_test.cc +703 -0
  1050. package/deps/rocksdb/rocksdb/utilities/util_merge_operators_test.cc +99 -0
  1051. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +617 -0
  1052. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.cc +345 -0
  1053. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +569 -0
  1054. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +1867 -0
  1055. package/deps/rocksdb/rocksdb.gyp +475 -0
  1056. package/deps/snappy/freebsd/config.h +135 -0
  1057. package/deps/snappy/freebsd/snappy-stubs-public.h +100 -0
  1058. package/deps/snappy/linux/config.h +135 -0
  1059. package/deps/snappy/linux/snappy-stubs-public.h +100 -0
  1060. package/deps/snappy/mac/config.h +137 -0
  1061. package/deps/snappy/mac/snappy-stubs-public.h +100 -0
  1062. package/deps/snappy/openbsd/config.h +135 -0
  1063. package/deps/snappy/openbsd/snappy-stubs-public.h +100 -0
  1064. package/deps/snappy/snappy-1.1.7/COPYING +54 -0
  1065. package/deps/snappy/snappy-1.1.7/cmake/SnappyConfig.cmake +1 -0
  1066. package/deps/snappy/snappy-1.1.7/cmake/config.h.in +62 -0
  1067. package/deps/snappy/snappy-1.1.7/snappy-c.cc +90 -0
  1068. package/deps/snappy/snappy-1.1.7/snappy-c.h +138 -0
  1069. package/deps/snappy/snappy-1.1.7/snappy-internal.h +224 -0
  1070. package/deps/snappy/snappy-1.1.7/snappy-sinksource.cc +104 -0
  1071. package/deps/snappy/snappy-1.1.7/snappy-sinksource.h +182 -0
  1072. package/deps/snappy/snappy-1.1.7/snappy-stubs-internal.cc +42 -0
  1073. package/deps/snappy/snappy-1.1.7/snappy-stubs-internal.h +561 -0
  1074. package/deps/snappy/snappy-1.1.7/snappy-stubs-public.h.in +94 -0
  1075. package/deps/snappy/snappy-1.1.7/snappy-test.cc +612 -0
  1076. package/deps/snappy/snappy-1.1.7/snappy-test.h +573 -0
  1077. package/deps/snappy/snappy-1.1.7/snappy.cc +1515 -0
  1078. package/deps/snappy/snappy-1.1.7/snappy.h +203 -0
  1079. package/deps/snappy/snappy-1.1.7/snappy_unittest.cc +1410 -0
  1080. package/deps/snappy/snappy.gyp +90 -0
  1081. package/deps/snappy/solaris/config.h +135 -0
  1082. package/deps/snappy/solaris/snappy-stubs-public.h +100 -0
  1083. package/deps/snappy/win32/config.h +29 -0
  1084. package/deps/snappy/win32/snappy-stubs-public.h +100 -0
  1085. package/iterator.js +55 -0
  1086. package/leveldown.js +113 -0
  1087. package/package-lock.json +23687 -0
  1088. package/package.json +70 -0
@@ -0,0 +1,2936 @@
1
+ // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2
+ // This source code is licensed under both the GPLv2 (found in the
3
+ // COPYING file in the root directory) and Apache 2.0 License
4
+ // (found in the LICENSE.Apache file in the root directory).
5
+
6
+ #ifndef ROCKSDB_LITE
7
+
8
+ #include <functional>
9
+
10
+ #include "db/db_test_util.h"
11
+ #include "db/dbformat.h"
12
+ #include "file/filename.h"
13
+ #include "port/port.h"
14
+ #include "port/stack_trace.h"
15
+ #include "rocksdb/sst_file_reader.h"
16
+ #include "rocksdb/sst_file_writer.h"
17
+ #include "test_util/testutil.h"
18
+ #include "util/random.h"
19
+ #include "utilities/fault_injection_env.h"
20
+
21
+ namespace ROCKSDB_NAMESPACE {
22
+
23
+ // A test environment that can be configured to fail the Link operation.
24
+ class ExternalSSTTestEnv : public EnvWrapper {
25
+ public:
26
+ ExternalSSTTestEnv(Env* t, bool fail_link)
27
+ : EnvWrapper(t), fail_link_(fail_link) {}
28
+
29
+ Status LinkFile(const std::string& s, const std::string& t) override {
30
+ if (fail_link_) {
31
+ return Status::NotSupported("Link failed");
32
+ }
33
+ return target()->LinkFile(s, t);
34
+ }
35
+
36
+ void set_fail_link(bool fail_link) { fail_link_ = fail_link; }
37
+
38
+ private:
39
+ bool fail_link_;
40
+ };
41
+
42
+ class ExternSSTFileLinkFailFallbackTest
43
+ : public DBTestBase,
44
+ public ::testing::WithParamInterface<std::tuple<bool, bool>> {
45
+ public:
46
+ ExternSSTFileLinkFailFallbackTest()
47
+ : DBTestBase("/external_sst_file_test", /*env_do_fsync=*/true),
48
+ test_env_(new ExternalSSTTestEnv(env_, true)) {
49
+ sst_files_dir_ = dbname_ + "/sst_files/";
50
+ EXPECT_EQ(DestroyDir(env_, sst_files_dir_), Status::OK());
51
+ EXPECT_EQ(env_->CreateDir(sst_files_dir_), Status::OK());
52
+ options_ = CurrentOptions();
53
+ options_.disable_auto_compactions = true;
54
+ options_.env = test_env_;
55
+ }
56
+
57
+ void TearDown() override {
58
+ delete db_;
59
+ db_ = nullptr;
60
+ ASSERT_OK(DestroyDB(dbname_, options_));
61
+ delete test_env_;
62
+ test_env_ = nullptr;
63
+ }
64
+
65
+ protected:
66
+ std::string sst_files_dir_;
67
+ Options options_;
68
+ ExternalSSTTestEnv* test_env_;
69
+ };
70
+
71
+ class ExternalSSTFileTest
72
+ : public DBTestBase,
73
+ public ::testing::WithParamInterface<std::tuple<bool, bool>> {
74
+ public:
75
+ ExternalSSTFileTest()
76
+ : DBTestBase("/external_sst_file_test", /*env_do_fsync=*/true) {
77
+ sst_files_dir_ = dbname_ + "/sst_files/";
78
+ DestroyAndRecreateExternalSSTFilesDir();
79
+ }
80
+
81
+ void DestroyAndRecreateExternalSSTFilesDir() {
82
+ ASSERT_OK(DestroyDir(env_, sst_files_dir_));
83
+ ASSERT_OK(env_->CreateDir(sst_files_dir_));
84
+ }
85
+
86
+ Status GenerateOneExternalFile(
87
+ const Options& options, ColumnFamilyHandle* cfh,
88
+ std::vector<std::pair<std::string, std::string>>& data, int file_id,
89
+ bool sort_data, std::string* external_file_path,
90
+ std::map<std::string, std::string>* true_data) {
91
+ // Generate a file id if not provided
92
+ if (-1 == file_id) {
93
+ file_id = (++last_file_id_);
94
+ }
95
+ // Sort data if asked to do so
96
+ if (sort_data) {
97
+ std::sort(data.begin(), data.end(),
98
+ [&](const std::pair<std::string, std::string>& e1,
99
+ const std::pair<std::string, std::string>& e2) {
100
+ return options.comparator->Compare(e1.first, e2.first) < 0;
101
+ });
102
+ auto uniq_iter = std::unique(
103
+ data.begin(), data.end(),
104
+ [&](const std::pair<std::string, std::string>& e1,
105
+ const std::pair<std::string, std::string>& e2) {
106
+ return options.comparator->Compare(e1.first, e2.first) == 0;
107
+ });
108
+ data.resize(uniq_iter - data.begin());
109
+ }
110
+ std::string file_path = sst_files_dir_ + ToString(file_id);
111
+ SstFileWriter sst_file_writer(EnvOptions(), options, cfh);
112
+ Status s = sst_file_writer.Open(file_path);
113
+ if (!s.ok()) {
114
+ return s;
115
+ }
116
+ for (const auto& entry : data) {
117
+ s = sst_file_writer.Put(entry.first, entry.second);
118
+ if (!s.ok()) {
119
+ sst_file_writer.Finish().PermitUncheckedError();
120
+ return s;
121
+ }
122
+ }
123
+ s = sst_file_writer.Finish();
124
+ if (s.ok() && external_file_path != nullptr) {
125
+ *external_file_path = file_path;
126
+ }
127
+ if (s.ok() && nullptr != true_data) {
128
+ for (const auto& entry : data) {
129
+ true_data->insert({entry.first, entry.second});
130
+ }
131
+ }
132
+ return s;
133
+ }
134
+
135
+ Status GenerateAndAddExternalFile(
136
+ const Options options,
137
+ std::vector<std::pair<std::string, std::string>> data, int file_id = -1,
138
+ bool allow_global_seqno = false, bool write_global_seqno = false,
139
+ bool verify_checksums_before_ingest = true, bool ingest_behind = false,
140
+ bool sort_data = false,
141
+ std::map<std::string, std::string>* true_data = nullptr,
142
+ ColumnFamilyHandle* cfh = nullptr) {
143
+ // Generate a file id if not provided
144
+ if (file_id == -1) {
145
+ file_id = last_file_id_ + 1;
146
+ last_file_id_++;
147
+ }
148
+
149
+ // Sort data if asked to do so
150
+ if (sort_data) {
151
+ std::sort(data.begin(), data.end(),
152
+ [&](const std::pair<std::string, std::string>& e1,
153
+ const std::pair<std::string, std::string>& e2) {
154
+ return options.comparator->Compare(e1.first, e2.first) < 0;
155
+ });
156
+ auto uniq_iter = std::unique(
157
+ data.begin(), data.end(),
158
+ [&](const std::pair<std::string, std::string>& e1,
159
+ const std::pair<std::string, std::string>& e2) {
160
+ return options.comparator->Compare(e1.first, e2.first) == 0;
161
+ });
162
+ data.resize(uniq_iter - data.begin());
163
+ }
164
+ std::string file_path = sst_files_dir_ + ToString(file_id);
165
+ SstFileWriter sst_file_writer(EnvOptions(), options, cfh);
166
+
167
+ Status s = sst_file_writer.Open(file_path);
168
+ if (!s.ok()) {
169
+ return s;
170
+ }
171
+ for (auto& entry : data) {
172
+ s = sst_file_writer.Put(entry.first, entry.second);
173
+ if (!s.ok()) {
174
+ sst_file_writer.Finish().PermitUncheckedError();
175
+ return s;
176
+ }
177
+ }
178
+ s = sst_file_writer.Finish();
179
+
180
+ if (s.ok()) {
181
+ IngestExternalFileOptions ifo;
182
+ ifo.allow_global_seqno = allow_global_seqno;
183
+ ifo.write_global_seqno = allow_global_seqno ? write_global_seqno : false;
184
+ ifo.verify_checksums_before_ingest = verify_checksums_before_ingest;
185
+ ifo.ingest_behind = ingest_behind;
186
+ if (cfh) {
187
+ s = db_->IngestExternalFile(cfh, {file_path}, ifo);
188
+ } else {
189
+ s = db_->IngestExternalFile({file_path}, ifo);
190
+ }
191
+ }
192
+
193
+ if (s.ok() && true_data) {
194
+ for (auto& entry : data) {
195
+ (*true_data)[entry.first] = entry.second;
196
+ }
197
+ }
198
+
199
+ return s;
200
+ }
201
+
202
+ Status GenerateAndAddExternalFiles(
203
+ const Options& options,
204
+ const std::vector<ColumnFamilyHandle*>& column_families,
205
+ const std::vector<IngestExternalFileOptions>& ifos,
206
+ std::vector<std::vector<std::pair<std::string, std::string>>>& data,
207
+ int file_id, bool sort_data,
208
+ std::vector<std::map<std::string, std::string>>& true_data) {
209
+ if (-1 == file_id) {
210
+ file_id = (++last_file_id_);
211
+ }
212
+ // Generate external SST files, one for each column family
213
+ size_t num_cfs = column_families.size();
214
+ assert(ifos.size() == num_cfs);
215
+ assert(data.size() == num_cfs);
216
+ std::vector<IngestExternalFileArg> args(num_cfs);
217
+ for (size_t i = 0; i != num_cfs; ++i) {
218
+ std::string external_file_path;
219
+ Status s = GenerateOneExternalFile(
220
+ options, column_families[i], data[i], file_id, sort_data,
221
+ &external_file_path,
222
+ true_data.size() == num_cfs ? &true_data[i] : nullptr);
223
+ if (!s.ok()) {
224
+ return s;
225
+ }
226
+ ++file_id;
227
+
228
+ args[i].column_family = column_families[i];
229
+ args[i].external_files.push_back(external_file_path);
230
+ args[i].options = ifos[i];
231
+ }
232
+ return db_->IngestExternalFiles(args);
233
+ }
234
+
235
+ Status GenerateAndAddExternalFile(
236
+ const Options options, std::vector<std::pair<int, std::string>> data,
237
+ int file_id = -1, bool allow_global_seqno = false,
238
+ bool write_global_seqno = false,
239
+ bool verify_checksums_before_ingest = true, bool ingest_behind = false,
240
+ bool sort_data = false,
241
+ std::map<std::string, std::string>* true_data = nullptr,
242
+ ColumnFamilyHandle* cfh = nullptr) {
243
+ std::vector<std::pair<std::string, std::string>> file_data;
244
+ for (auto& entry : data) {
245
+ file_data.emplace_back(Key(entry.first), entry.second);
246
+ }
247
+ return GenerateAndAddExternalFile(options, file_data, file_id,
248
+ allow_global_seqno, write_global_seqno,
249
+ verify_checksums_before_ingest,
250
+ ingest_behind, sort_data, true_data, cfh);
251
+ }
252
+
253
+ Status GenerateAndAddExternalFile(
254
+ const Options options, std::vector<int> keys, int file_id = -1,
255
+ bool allow_global_seqno = false, bool write_global_seqno = false,
256
+ bool verify_checksums_before_ingest = true, bool ingest_behind = false,
257
+ bool sort_data = false,
258
+ std::map<std::string, std::string>* true_data = nullptr,
259
+ ColumnFamilyHandle* cfh = nullptr) {
260
+ std::vector<std::pair<std::string, std::string>> file_data;
261
+ for (auto& k : keys) {
262
+ file_data.emplace_back(Key(k), Key(k) + ToString(file_id));
263
+ }
264
+ return GenerateAndAddExternalFile(options, file_data, file_id,
265
+ allow_global_seqno, write_global_seqno,
266
+ verify_checksums_before_ingest,
267
+ ingest_behind, sort_data, true_data, cfh);
268
+ }
269
+
270
+ Status DeprecatedAddFile(const std::vector<std::string>& files,
271
+ bool move_files = false,
272
+ bool skip_snapshot_check = false,
273
+ bool skip_write_global_seqno = false) {
274
+ IngestExternalFileOptions opts;
275
+ opts.move_files = move_files;
276
+ opts.snapshot_consistency = !skip_snapshot_check;
277
+ opts.allow_global_seqno = false;
278
+ opts.allow_blocking_flush = false;
279
+ opts.write_global_seqno = !skip_write_global_seqno;
280
+ return db_->IngestExternalFile(files, opts);
281
+ }
282
+
283
+ ~ExternalSSTFileTest() override {
284
+ DestroyDir(env_, sst_files_dir_).PermitUncheckedError();
285
+ }
286
+
287
+ protected:
288
+ int last_file_id_ = 0;
289
+ std::string sst_files_dir_;
290
+ };
291
+
292
+ TEST_F(ExternalSSTFileTest, Basic) {
293
+ do {
294
+ Options options = CurrentOptions();
295
+
296
+ SstFileWriter sst_file_writer(EnvOptions(), options);
297
+
298
+ // Current file size should be 0 after sst_file_writer init and before open a file.
299
+ ASSERT_EQ(sst_file_writer.FileSize(), 0);
300
+
301
+ // file1.sst (0 => 99)
302
+ std::string file1 = sst_files_dir_ + "file1.sst";
303
+ ASSERT_OK(sst_file_writer.Open(file1));
304
+ for (int k = 0; k < 100; k++) {
305
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
306
+ }
307
+ ExternalSstFileInfo file1_info;
308
+ ASSERT_OK(sst_file_writer.Finish(&file1_info));
309
+
310
+ // Current file size should be non-zero after success write.
311
+ ASSERT_GT(sst_file_writer.FileSize(), 0);
312
+
313
+ ASSERT_EQ(file1_info.file_path, file1);
314
+ ASSERT_EQ(file1_info.num_entries, 100);
315
+ ASSERT_EQ(file1_info.smallest_key, Key(0));
316
+ ASSERT_EQ(file1_info.largest_key, Key(99));
317
+ ASSERT_EQ(file1_info.num_range_del_entries, 0);
318
+ ASSERT_EQ(file1_info.smallest_range_del_key, "");
319
+ ASSERT_EQ(file1_info.largest_range_del_key, "");
320
+ // sst_file_writer already finished, cannot add this value
321
+ ASSERT_NOK(sst_file_writer.Put(Key(100), "bad_val"));
322
+
323
+ // file2.sst (100 => 199)
324
+ std::string file2 = sst_files_dir_ + "file2.sst";
325
+ ASSERT_OK(sst_file_writer.Open(file2));
326
+ for (int k = 100; k < 200; k++) {
327
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
328
+ }
329
+ // Cannot add this key because it's not after last added key
330
+ ASSERT_NOK(sst_file_writer.Put(Key(99), "bad_val"));
331
+ ExternalSstFileInfo file2_info;
332
+ ASSERT_OK(sst_file_writer.Finish(&file2_info));
333
+ ASSERT_EQ(file2_info.file_path, file2);
334
+ ASSERT_EQ(file2_info.num_entries, 100);
335
+ ASSERT_EQ(file2_info.smallest_key, Key(100));
336
+ ASSERT_EQ(file2_info.largest_key, Key(199));
337
+
338
+ // file3.sst (195 => 299)
339
+ // This file values overlap with file2 values
340
+ std::string file3 = sst_files_dir_ + "file3.sst";
341
+ ASSERT_OK(sst_file_writer.Open(file3));
342
+ for (int k = 195; k < 300; k++) {
343
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap"));
344
+ }
345
+ ExternalSstFileInfo file3_info;
346
+ ASSERT_OK(sst_file_writer.Finish(&file3_info));
347
+
348
+ // Current file size should be non-zero after success finish.
349
+ ASSERT_GT(sst_file_writer.FileSize(), 0);
350
+ ASSERT_EQ(file3_info.file_path, file3);
351
+ ASSERT_EQ(file3_info.num_entries, 105);
352
+ ASSERT_EQ(file3_info.smallest_key, Key(195));
353
+ ASSERT_EQ(file3_info.largest_key, Key(299));
354
+
355
+ // file4.sst (30 => 39)
356
+ // This file values overlap with file1 values
357
+ std::string file4 = sst_files_dir_ + "file4.sst";
358
+ ASSERT_OK(sst_file_writer.Open(file4));
359
+ for (int k = 30; k < 40; k++) {
360
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap"));
361
+ }
362
+ ExternalSstFileInfo file4_info;
363
+ ASSERT_OK(sst_file_writer.Finish(&file4_info));
364
+ ASSERT_EQ(file4_info.file_path, file4);
365
+ ASSERT_EQ(file4_info.num_entries, 10);
366
+ ASSERT_EQ(file4_info.smallest_key, Key(30));
367
+ ASSERT_EQ(file4_info.largest_key, Key(39));
368
+
369
+ // file5.sst (400 => 499)
370
+ std::string file5 = sst_files_dir_ + "file5.sst";
371
+ ASSERT_OK(sst_file_writer.Open(file5));
372
+ for (int k = 400; k < 500; k++) {
373
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
374
+ }
375
+ ExternalSstFileInfo file5_info;
376
+ ASSERT_OK(sst_file_writer.Finish(&file5_info));
377
+ ASSERT_EQ(file5_info.file_path, file5);
378
+ ASSERT_EQ(file5_info.num_entries, 100);
379
+ ASSERT_EQ(file5_info.smallest_key, Key(400));
380
+ ASSERT_EQ(file5_info.largest_key, Key(499));
381
+
382
+ // file6.sst (delete 400 => 500)
383
+ std::string file6 = sst_files_dir_ + "file6.sst";
384
+ ASSERT_OK(sst_file_writer.Open(file6));
385
+ ASSERT_OK(sst_file_writer.DeleteRange(Key(400), Key(500)));
386
+ ExternalSstFileInfo file6_info;
387
+ ASSERT_OK(sst_file_writer.Finish(&file6_info));
388
+ ASSERT_EQ(file6_info.file_path, file6);
389
+ ASSERT_EQ(file6_info.num_entries, 0);
390
+ ASSERT_EQ(file6_info.smallest_key, "");
391
+ ASSERT_EQ(file6_info.largest_key, "");
392
+ ASSERT_EQ(file6_info.num_range_del_entries, 1);
393
+ ASSERT_EQ(file6_info.smallest_range_del_key, Key(400));
394
+ ASSERT_EQ(file6_info.largest_range_del_key, Key(500));
395
+
396
+ // file7.sst (delete 500 => 570, put 520 => 599 divisible by 2)
397
+ std::string file7 = sst_files_dir_ + "file7.sst";
398
+ ASSERT_OK(sst_file_writer.Open(file7));
399
+ ASSERT_OK(sst_file_writer.DeleteRange(Key(500), Key(550)));
400
+ for (int k = 520; k < 560; k += 2) {
401
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
402
+ }
403
+ ASSERT_OK(sst_file_writer.DeleteRange(Key(525), Key(575)));
404
+ for (int k = 560; k < 600; k += 2) {
405
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
406
+ }
407
+ ExternalSstFileInfo file7_info;
408
+ ASSERT_OK(sst_file_writer.Finish(&file7_info));
409
+ ASSERT_EQ(file7_info.file_path, file7);
410
+ ASSERT_EQ(file7_info.num_entries, 40);
411
+ ASSERT_EQ(file7_info.smallest_key, Key(520));
412
+ ASSERT_EQ(file7_info.largest_key, Key(598));
413
+ ASSERT_EQ(file7_info.num_range_del_entries, 2);
414
+ ASSERT_EQ(file7_info.smallest_range_del_key, Key(500));
415
+ ASSERT_EQ(file7_info.largest_range_del_key, Key(575));
416
+
417
+ // file8.sst (delete 600 => 700)
418
+ std::string file8 = sst_files_dir_ + "file8.sst";
419
+ ASSERT_OK(sst_file_writer.Open(file8));
420
+ ASSERT_OK(sst_file_writer.DeleteRange(Key(600), Key(700)));
421
+ ExternalSstFileInfo file8_info;
422
+ ASSERT_OK(sst_file_writer.Finish(&file8_info));
423
+ ASSERT_EQ(file8_info.file_path, file8);
424
+ ASSERT_EQ(file8_info.num_entries, 0);
425
+ ASSERT_EQ(file8_info.smallest_key, "");
426
+ ASSERT_EQ(file8_info.largest_key, "");
427
+ ASSERT_EQ(file8_info.num_range_del_entries, 1);
428
+ ASSERT_EQ(file8_info.smallest_range_del_key, Key(600));
429
+ ASSERT_EQ(file8_info.largest_range_del_key, Key(700));
430
+
431
+ // Cannot create an empty sst file
432
+ std::string file_empty = sst_files_dir_ + "file_empty.sst";
433
+ ExternalSstFileInfo file_empty_info;
434
+ ASSERT_NOK(sst_file_writer.Finish(&file_empty_info));
435
+
436
+ DestroyAndReopen(options);
437
+ // Add file using file path
438
+ ASSERT_OK(DeprecatedAddFile({file1}));
439
+ ASSERT_EQ(db_->GetLatestSequenceNumber(), 0U);
440
+ for (int k = 0; k < 100; k++) {
441
+ ASSERT_EQ(Get(Key(k)), Key(k) + "_val");
442
+ }
443
+
444
+ // Add file while holding a snapshot will fail
445
+ const Snapshot* s1 = db_->GetSnapshot();
446
+ if (s1 != nullptr) {
447
+ ASSERT_NOK(DeprecatedAddFile({file2}));
448
+ db_->ReleaseSnapshot(s1);
449
+ }
450
+ // We can add the file after releaseing the snapshot
451
+ ASSERT_OK(DeprecatedAddFile({file2}));
452
+
453
+ ASSERT_EQ(db_->GetLatestSequenceNumber(), 0U);
454
+ for (int k = 0; k < 200; k++) {
455
+ ASSERT_EQ(Get(Key(k)), Key(k) + "_val");
456
+ }
457
+
458
+ // This file has overlapping values with the existing data
459
+ ASSERT_NOK(DeprecatedAddFile({file3}));
460
+
461
+ // This file has overlapping values with the existing data
462
+ ASSERT_NOK(DeprecatedAddFile({file4}));
463
+
464
+ // Overwrite values of keys divisible by 5
465
+ for (int k = 0; k < 200; k += 5) {
466
+ ASSERT_OK(Put(Key(k), Key(k) + "_val_new"));
467
+ }
468
+ ASSERT_NE(db_->GetLatestSequenceNumber(), 0U);
469
+
470
+ // Key range of file5 (400 => 499) don't overlap with any keys in DB
471
+ ASSERT_OK(DeprecatedAddFile({file5}));
472
+
473
+ // This file has overlapping values with the existing data
474
+ ASSERT_NOK(DeprecatedAddFile({file6}));
475
+
476
+ // Key range of file7 (500 => 598) don't overlap with any keys in DB
477
+ ASSERT_OK(DeprecatedAddFile({file7}));
478
+
479
+ // Key range of file7 (600 => 700) don't overlap with any keys in DB
480
+ ASSERT_OK(DeprecatedAddFile({file8}));
481
+
482
+ // Make sure values are correct before and after flush/compaction
483
+ for (int i = 0; i < 2; i++) {
484
+ for (int k = 0; k < 200; k++) {
485
+ std::string value = Key(k) + "_val";
486
+ if (k % 5 == 0) {
487
+ value += "_new";
488
+ }
489
+ ASSERT_EQ(Get(Key(k)), value);
490
+ }
491
+ for (int k = 400; k < 500; k++) {
492
+ std::string value = Key(k) + "_val";
493
+ ASSERT_EQ(Get(Key(k)), value);
494
+ }
495
+ for (int k = 500; k < 600; k++) {
496
+ std::string value = Key(k) + "_val";
497
+ if (k < 520 || k % 2 == 1) {
498
+ value = "NOT_FOUND";
499
+ }
500
+ ASSERT_EQ(Get(Key(k)), value);
501
+ }
502
+ ASSERT_OK(Flush());
503
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
504
+ }
505
+
506
+ Close();
507
+ options.disable_auto_compactions = true;
508
+ Reopen(options);
509
+
510
+ // Delete keys in range (400 => 499)
511
+ for (int k = 400; k < 500; k++) {
512
+ ASSERT_OK(Delete(Key(k)));
513
+ }
514
+ // We deleted range (400 => 499) but cannot add file5 because
515
+ // of the range tombstones
516
+ ASSERT_NOK(DeprecatedAddFile({file5}));
517
+
518
+ // Compacting the DB will remove the tombstones
519
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
520
+
521
+ // Now we can add the file
522
+ ASSERT_OK(DeprecatedAddFile({file5}));
523
+
524
+ // Verify values of file5 in DB
525
+ for (int k = 400; k < 500; k++) {
526
+ std::string value = Key(k) + "_val";
527
+ ASSERT_EQ(Get(Key(k)), value);
528
+ }
529
+ DestroyAndRecreateExternalSSTFilesDir();
530
+ } while (ChangeOptions(kSkipPlainTable | kSkipFIFOCompaction |
531
+ kRangeDelSkipConfigs));
532
+ }
533
+
534
+ class SstFileWriterCollector : public TablePropertiesCollector {
535
+ public:
536
+ explicit SstFileWriterCollector(const std::string prefix) : prefix_(prefix) {
537
+ name_ = prefix_ + "_SstFileWriterCollector";
538
+ }
539
+
540
+ const char* Name() const override { return name_.c_str(); }
541
+
542
+ Status Finish(UserCollectedProperties* properties) override {
543
+ std::string count = std::to_string(count_);
544
+ *properties = UserCollectedProperties{
545
+ {prefix_ + "_SstFileWriterCollector", "YES"},
546
+ {prefix_ + "_Count", count},
547
+ };
548
+ return Status::OK();
549
+ }
550
+
551
+ Status AddUserKey(const Slice& /*user_key*/, const Slice& /*value*/,
552
+ EntryType /*type*/, SequenceNumber /*seq*/,
553
+ uint64_t /*file_size*/) override {
554
+ ++count_;
555
+ return Status::OK();
556
+ }
557
+
558
+ UserCollectedProperties GetReadableProperties() const override {
559
+ return UserCollectedProperties{};
560
+ }
561
+
562
+ private:
563
+ uint32_t count_ = 0;
564
+ std::string prefix_;
565
+ std::string name_;
566
+ };
567
+
568
+ class SstFileWriterCollectorFactory : public TablePropertiesCollectorFactory {
569
+ public:
570
+ explicit SstFileWriterCollectorFactory(std::string prefix)
571
+ : prefix_(prefix), num_created_(0) {}
572
+ TablePropertiesCollector* CreateTablePropertiesCollector(
573
+ TablePropertiesCollectorFactory::Context /*context*/) override {
574
+ num_created_++;
575
+ return new SstFileWriterCollector(prefix_);
576
+ }
577
+ const char* Name() const override { return "SstFileWriterCollectorFactory"; }
578
+
579
+ std::string prefix_;
580
+ uint32_t num_created_;
581
+ };
582
+
583
+ TEST_F(ExternalSSTFileTest, AddList) {
584
+ do {
585
+ Options options = CurrentOptions();
586
+
587
+ auto abc_collector = std::make_shared<SstFileWriterCollectorFactory>("abc");
588
+ auto xyz_collector = std::make_shared<SstFileWriterCollectorFactory>("xyz");
589
+
590
+ options.table_properties_collector_factories.emplace_back(abc_collector);
591
+ options.table_properties_collector_factories.emplace_back(xyz_collector);
592
+
593
+ SstFileWriter sst_file_writer(EnvOptions(), options);
594
+
595
+ // file1.sst (0 => 99)
596
+ std::string file1 = sst_files_dir_ + "file1.sst";
597
+ ASSERT_OK(sst_file_writer.Open(file1));
598
+ for (int k = 0; k < 100; k++) {
599
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
600
+ }
601
+ ExternalSstFileInfo file1_info;
602
+ ASSERT_OK(sst_file_writer.Finish(&file1_info));
603
+ ASSERT_EQ(file1_info.file_path, file1);
604
+ ASSERT_EQ(file1_info.num_entries, 100);
605
+ ASSERT_EQ(file1_info.smallest_key, Key(0));
606
+ ASSERT_EQ(file1_info.largest_key, Key(99));
607
+ // sst_file_writer already finished, cannot add this value
608
+ ASSERT_NOK(sst_file_writer.Put(Key(100), "bad_val"));
609
+
610
+ // file2.sst (100 => 199)
611
+ std::string file2 = sst_files_dir_ + "file2.sst";
612
+ ASSERT_OK(sst_file_writer.Open(file2));
613
+ for (int k = 100; k < 200; k++) {
614
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
615
+ }
616
+ // Cannot add this key because it's not after last added key
617
+ ASSERT_NOK(sst_file_writer.Put(Key(99), "bad_val"));
618
+ ExternalSstFileInfo file2_info;
619
+ ASSERT_OK(sst_file_writer.Finish(&file2_info));
620
+ ASSERT_EQ(file2_info.file_path, file2);
621
+ ASSERT_EQ(file2_info.num_entries, 100);
622
+ ASSERT_EQ(file2_info.smallest_key, Key(100));
623
+ ASSERT_EQ(file2_info.largest_key, Key(199));
624
+
625
+ // file3.sst (195 => 199)
626
+ // This file values overlap with file2 values
627
+ std::string file3 = sst_files_dir_ + "file3.sst";
628
+ ASSERT_OK(sst_file_writer.Open(file3));
629
+ for (int k = 195; k < 200; k++) {
630
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap"));
631
+ }
632
+ ExternalSstFileInfo file3_info;
633
+ ASSERT_OK(sst_file_writer.Finish(&file3_info));
634
+ ASSERT_EQ(file3_info.file_path, file3);
635
+ ASSERT_EQ(file3_info.num_entries, 5);
636
+ ASSERT_EQ(file3_info.smallest_key, Key(195));
637
+ ASSERT_EQ(file3_info.largest_key, Key(199));
638
+
639
+ // file4.sst (30 => 39)
640
+ // This file values overlap with file1 values
641
+ std::string file4 = sst_files_dir_ + "file4.sst";
642
+ ASSERT_OK(sst_file_writer.Open(file4));
643
+ for (int k = 30; k < 40; k++) {
644
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap"));
645
+ }
646
+ ExternalSstFileInfo file4_info;
647
+ ASSERT_OK(sst_file_writer.Finish(&file4_info));
648
+ ASSERT_EQ(file4_info.file_path, file4);
649
+ ASSERT_EQ(file4_info.num_entries, 10);
650
+ ASSERT_EQ(file4_info.smallest_key, Key(30));
651
+ ASSERT_EQ(file4_info.largest_key, Key(39));
652
+
653
+ // file5.sst (200 => 299)
654
+ std::string file5 = sst_files_dir_ + "file5.sst";
655
+ ASSERT_OK(sst_file_writer.Open(file5));
656
+ for (int k = 200; k < 300; k++) {
657
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
658
+ }
659
+ ExternalSstFileInfo file5_info;
660
+ ASSERT_OK(sst_file_writer.Finish(&file5_info));
661
+ ASSERT_EQ(file5_info.file_path, file5);
662
+ ASSERT_EQ(file5_info.num_entries, 100);
663
+ ASSERT_EQ(file5_info.smallest_key, Key(200));
664
+ ASSERT_EQ(file5_info.largest_key, Key(299));
665
+
666
+ // file6.sst (delete 0 => 100)
667
+ std::string file6 = sst_files_dir_ + "file6.sst";
668
+ ASSERT_OK(sst_file_writer.Open(file6));
669
+ ASSERT_OK(sst_file_writer.DeleteRange(Key(0), Key(75)));
670
+ ASSERT_OK(sst_file_writer.DeleteRange(Key(25), Key(100)));
671
+ ExternalSstFileInfo file6_info;
672
+ ASSERT_OK(sst_file_writer.Finish(&file6_info));
673
+ ASSERT_EQ(file6_info.file_path, file6);
674
+ ASSERT_EQ(file6_info.num_entries, 0);
675
+ ASSERT_EQ(file6_info.smallest_key, "");
676
+ ASSERT_EQ(file6_info.largest_key, "");
677
+ ASSERT_EQ(file6_info.num_range_del_entries, 2);
678
+ ASSERT_EQ(file6_info.smallest_range_del_key, Key(0));
679
+ ASSERT_EQ(file6_info.largest_range_del_key, Key(100));
680
+
681
+ // file7.sst (delete 99 => 201)
682
+ std::string file7 = sst_files_dir_ + "file7.sst";
683
+ ASSERT_OK(sst_file_writer.Open(file7));
684
+ ASSERT_OK(sst_file_writer.DeleteRange(Key(99), Key(201)));
685
+ ExternalSstFileInfo file7_info;
686
+ ASSERT_OK(sst_file_writer.Finish(&file7_info));
687
+ ASSERT_EQ(file7_info.file_path, file7);
688
+ ASSERT_EQ(file7_info.num_entries, 0);
689
+ ASSERT_EQ(file7_info.smallest_key, "");
690
+ ASSERT_EQ(file7_info.largest_key, "");
691
+ ASSERT_EQ(file7_info.num_range_del_entries, 1);
692
+ ASSERT_EQ(file7_info.smallest_range_del_key, Key(99));
693
+ ASSERT_EQ(file7_info.largest_range_del_key, Key(201));
694
+
695
+ // list 1 has internal key range conflict
696
+ std::vector<std::string> file_list0({file1, file2});
697
+ std::vector<std::string> file_list1({file3, file2, file1});
698
+ std::vector<std::string> file_list2({file5});
699
+ std::vector<std::string> file_list3({file3, file4});
700
+ std::vector<std::string> file_list4({file5, file7});
701
+ std::vector<std::string> file_list5({file6, file7});
702
+
703
+ DestroyAndReopen(options);
704
+
705
+ // These lists of files have key ranges that overlap with each other
706
+ ASSERT_NOK(DeprecatedAddFile(file_list1));
707
+ // Both of the following overlap on the range deletion tombstone.
708
+ ASSERT_NOK(DeprecatedAddFile(file_list4));
709
+ ASSERT_NOK(DeprecatedAddFile(file_list5));
710
+
711
+ // Add files using file path list
712
+ ASSERT_OK(DeprecatedAddFile(file_list0));
713
+ ASSERT_EQ(db_->GetLatestSequenceNumber(), 0U);
714
+ for (int k = 0; k < 200; k++) {
715
+ ASSERT_EQ(Get(Key(k)), Key(k) + "_val");
716
+ }
717
+
718
+ TablePropertiesCollection props;
719
+ ASSERT_OK(db_->GetPropertiesOfAllTables(&props));
720
+ ASSERT_EQ(props.size(), 2);
721
+ for (auto file_props : props) {
722
+ auto user_props = file_props.second->user_collected_properties;
723
+ ASSERT_EQ(user_props["abc_SstFileWriterCollector"], "YES");
724
+ ASSERT_EQ(user_props["xyz_SstFileWriterCollector"], "YES");
725
+ ASSERT_EQ(user_props["abc_Count"], "100");
726
+ ASSERT_EQ(user_props["xyz_Count"], "100");
727
+ }
728
+
729
+ // Add file while holding a snapshot will fail
730
+ const Snapshot* s1 = db_->GetSnapshot();
731
+ if (s1 != nullptr) {
732
+ ASSERT_NOK(DeprecatedAddFile(file_list2));
733
+ db_->ReleaseSnapshot(s1);
734
+ }
735
+ // We can add the file after releaseing the snapshot
736
+ ASSERT_OK(DeprecatedAddFile(file_list2));
737
+ ASSERT_EQ(db_->GetLatestSequenceNumber(), 0U);
738
+ for (int k = 0; k < 300; k++) {
739
+ ASSERT_EQ(Get(Key(k)), Key(k) + "_val");
740
+ }
741
+
742
+ ASSERT_OK(db_->GetPropertiesOfAllTables(&props));
743
+ ASSERT_EQ(props.size(), 3);
744
+ for (auto file_props : props) {
745
+ auto user_props = file_props.second->user_collected_properties;
746
+ ASSERT_EQ(user_props["abc_SstFileWriterCollector"], "YES");
747
+ ASSERT_EQ(user_props["xyz_SstFileWriterCollector"], "YES");
748
+ ASSERT_EQ(user_props["abc_Count"], "100");
749
+ ASSERT_EQ(user_props["xyz_Count"], "100");
750
+ }
751
+
752
+ // This file list has overlapping values with the existing data
753
+ ASSERT_NOK(DeprecatedAddFile(file_list3));
754
+
755
+ // Overwrite values of keys divisible by 5
756
+ for (int k = 0; k < 200; k += 5) {
757
+ ASSERT_OK(Put(Key(k), Key(k) + "_val_new"));
758
+ }
759
+ ASSERT_NE(db_->GetLatestSequenceNumber(), 0U);
760
+
761
+ // Make sure values are correct before and after flush/compaction
762
+ for (int i = 0; i < 2; i++) {
763
+ for (int k = 0; k < 200; k++) {
764
+ std::string value = Key(k) + "_val";
765
+ if (k % 5 == 0) {
766
+ value += "_new";
767
+ }
768
+ ASSERT_EQ(Get(Key(k)), value);
769
+ }
770
+ for (int k = 200; k < 300; k++) {
771
+ std::string value = Key(k) + "_val";
772
+ ASSERT_EQ(Get(Key(k)), value);
773
+ }
774
+ ASSERT_OK(Flush());
775
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
776
+ }
777
+
778
+ // Delete keys in range (200 => 299)
779
+ for (int k = 200; k < 300; k++) {
780
+ ASSERT_OK(Delete(Key(k)));
781
+ }
782
+ // We deleted range (200 => 299) but cannot add file5 because
783
+ // of the range tombstones
784
+ ASSERT_NOK(DeprecatedAddFile(file_list2));
785
+
786
+ // Compacting the DB will remove the tombstones
787
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
788
+
789
+ // Now we can add the file
790
+ ASSERT_OK(DeprecatedAddFile(file_list2));
791
+
792
+ // Verify values of file5 in DB
793
+ for (int k = 200; k < 300; k++) {
794
+ std::string value = Key(k) + "_val";
795
+ ASSERT_EQ(Get(Key(k)), value);
796
+ }
797
+ DestroyAndRecreateExternalSSTFilesDir();
798
+ } while (ChangeOptions(kSkipPlainTable | kSkipFIFOCompaction |
799
+ kRangeDelSkipConfigs));
800
+ }
801
+
802
+ TEST_F(ExternalSSTFileTest, AddListAtomicity) {
803
+ do {
804
+ Options options = CurrentOptions();
805
+
806
+ SstFileWriter sst_file_writer(EnvOptions(), options);
807
+
808
+ // files[0].sst (0 => 99)
809
+ // files[1].sst (100 => 199)
810
+ // ...
811
+ // file[8].sst (800 => 899)
812
+ int n = 9;
813
+ std::vector<std::string> files(n);
814
+ std::vector<ExternalSstFileInfo> files_info(n);
815
+ for (int i = 0; i < n; i++) {
816
+ files[i] = sst_files_dir_ + "file" + std::to_string(i) + ".sst";
817
+ ASSERT_OK(sst_file_writer.Open(files[i]));
818
+ for (int k = i * 100; k < (i + 1) * 100; k++) {
819
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
820
+ }
821
+ ASSERT_OK(sst_file_writer.Finish(&files_info[i]));
822
+ ASSERT_EQ(files_info[i].file_path, files[i]);
823
+ ASSERT_EQ(files_info[i].num_entries, 100);
824
+ ASSERT_EQ(files_info[i].smallest_key, Key(i * 100));
825
+ ASSERT_EQ(files_info[i].largest_key, Key((i + 1) * 100 - 1));
826
+ }
827
+ files.push_back(sst_files_dir_ + "file" + std::to_string(n) + ".sst");
828
+ ASSERT_NOK(DeprecatedAddFile(files));
829
+ for (int k = 0; k < n * 100; k++) {
830
+ ASSERT_EQ("NOT_FOUND", Get(Key(k)));
831
+ }
832
+ files.pop_back();
833
+ ASSERT_OK(DeprecatedAddFile(files));
834
+ for (int k = 0; k < n * 100; k++) {
835
+ std::string value = Key(k) + "_val";
836
+ ASSERT_EQ(Get(Key(k)), value);
837
+ }
838
+ DestroyAndRecreateExternalSSTFilesDir();
839
+ } while (ChangeOptions(kSkipPlainTable | kSkipFIFOCompaction));
840
+ }
841
+ // This test reporduce a bug that can happen in some cases if the DB started
842
+ // purging obsolete files when we are adding an external sst file.
843
+ // This situation may result in deleting the file while it's being added.
844
+ TEST_F(ExternalSSTFileTest, PurgeObsoleteFilesBug) {
845
+ Options options = CurrentOptions();
846
+ SstFileWriter sst_file_writer(EnvOptions(), options);
847
+
848
+ // file1.sst (0 => 500)
849
+ std::string sst_file_path = sst_files_dir_ + "file1.sst";
850
+ ASSERT_OK(sst_file_writer.Open(sst_file_path));
851
+ for (int i = 0; i < 500; i++) {
852
+ std::string k = Key(i);
853
+ ASSERT_OK(sst_file_writer.Put(k, k + "_val"));
854
+ }
855
+
856
+ ExternalSstFileInfo sst_file_info;
857
+ ASSERT_OK(sst_file_writer.Finish(&sst_file_info));
858
+
859
+ options.delete_obsolete_files_period_micros = 0;
860
+ options.disable_auto_compactions = true;
861
+ DestroyAndReopen(options);
862
+
863
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
864
+ "ExternalSstFileIngestionJob::Prepare:FileAdded", [&](void* /* arg */) {
865
+ ASSERT_OK(Put("aaa", "bbb"));
866
+ ASSERT_OK(Flush());
867
+ ASSERT_OK(Put("aaa", "xxx"));
868
+ ASSERT_OK(Flush());
869
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
870
+ });
871
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
872
+
873
+ ASSERT_OK(DeprecatedAddFile({sst_file_path}));
874
+
875
+ for (int i = 0; i < 500; i++) {
876
+ std::string k = Key(i);
877
+ std::string v = k + "_val";
878
+ ASSERT_EQ(Get(k), v);
879
+ }
880
+
881
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
882
+ }
883
+
884
+ TEST_F(ExternalSSTFileTest, SkipSnapshot) {
885
+ Options options = CurrentOptions();
886
+
887
+ SstFileWriter sst_file_writer(EnvOptions(), options);
888
+
889
+ // file1.sst (0 => 99)
890
+ std::string file1 = sst_files_dir_ + "file1.sst";
891
+ ASSERT_OK(sst_file_writer.Open(file1));
892
+ for (int k = 0; k < 100; k++) {
893
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
894
+ }
895
+ ExternalSstFileInfo file1_info;
896
+ ASSERT_OK(sst_file_writer.Finish(&file1_info));
897
+ ASSERT_EQ(file1_info.file_path, file1);
898
+ ASSERT_EQ(file1_info.num_entries, 100);
899
+ ASSERT_EQ(file1_info.smallest_key, Key(0));
900
+ ASSERT_EQ(file1_info.largest_key, Key(99));
901
+
902
+ // file2.sst (100 => 299)
903
+ std::string file2 = sst_files_dir_ + "file2.sst";
904
+ ASSERT_OK(sst_file_writer.Open(file2));
905
+ for (int k = 100; k < 300; k++) {
906
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
907
+ }
908
+ ExternalSstFileInfo file2_info;
909
+ ASSERT_OK(sst_file_writer.Finish(&file2_info));
910
+ ASSERT_EQ(file2_info.file_path, file2);
911
+ ASSERT_EQ(file2_info.num_entries, 200);
912
+ ASSERT_EQ(file2_info.smallest_key, Key(100));
913
+ ASSERT_EQ(file2_info.largest_key, Key(299));
914
+
915
+ ASSERT_OK(DeprecatedAddFile({file1}));
916
+
917
+ // Add file will fail when holding snapshot and use the default
918
+ // skip_snapshot_check to false
919
+ const Snapshot* s1 = db_->GetSnapshot();
920
+ if (s1 != nullptr) {
921
+ ASSERT_NOK(DeprecatedAddFile({file2}));
922
+ }
923
+
924
+ // Add file will success when set skip_snapshot_check to true even db holding
925
+ // snapshot
926
+ if (s1 != nullptr) {
927
+ ASSERT_OK(DeprecatedAddFile({file2}, false, true));
928
+ db_->ReleaseSnapshot(s1);
929
+ }
930
+
931
+ // file3.sst (300 => 399)
932
+ std::string file3 = sst_files_dir_ + "file3.sst";
933
+ ASSERT_OK(sst_file_writer.Open(file3));
934
+ for (int k = 300; k < 400; k++) {
935
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
936
+ }
937
+ ExternalSstFileInfo file3_info;
938
+ ASSERT_OK(sst_file_writer.Finish(&file3_info));
939
+ ASSERT_EQ(file3_info.file_path, file3);
940
+ ASSERT_EQ(file3_info.num_entries, 100);
941
+ ASSERT_EQ(file3_info.smallest_key, Key(300));
942
+ ASSERT_EQ(file3_info.largest_key, Key(399));
943
+
944
+ // check that we have change the old key
945
+ ASSERT_EQ(Get(Key(300)), "NOT_FOUND");
946
+ const Snapshot* s2 = db_->GetSnapshot();
947
+ ASSERT_OK(DeprecatedAddFile({file3}, false, true));
948
+ ASSERT_EQ(Get(Key(300)), Key(300) + ("_val"));
949
+ ASSERT_EQ(Get(Key(300), s2), Key(300) + ("_val"));
950
+
951
+ db_->ReleaseSnapshot(s2);
952
+ }
953
+
954
+ TEST_F(ExternalSSTFileTest, MultiThreaded) {
955
+ env_->skip_fsync_ = true;
956
+ // Bulk load 10 files every file contain 1000 keys
957
+ int num_files = 10;
958
+ int keys_per_file = 1000;
959
+
960
+ // Generate file names
961
+ std::vector<std::string> file_names;
962
+ for (int i = 0; i < num_files; i++) {
963
+ std::string file_name = "file_" + ToString(i) + ".sst";
964
+ file_names.push_back(sst_files_dir_ + file_name);
965
+ }
966
+
967
+ do {
968
+ Options options = CurrentOptions();
969
+
970
+ std::atomic<int> thread_num(0);
971
+ std::function<void()> write_file_func = [&]() {
972
+ int file_idx = thread_num.fetch_add(1);
973
+ int range_start = file_idx * keys_per_file;
974
+ int range_end = range_start + keys_per_file;
975
+
976
+ SstFileWriter sst_file_writer(EnvOptions(), options);
977
+
978
+ ASSERT_OK(sst_file_writer.Open(file_names[file_idx]));
979
+
980
+ for (int k = range_start; k < range_end; k++) {
981
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k)));
982
+ }
983
+
984
+ ASSERT_OK(sst_file_writer.Finish());
985
+ };
986
+ // Write num_files files in parallel
987
+ std::vector<port::Thread> sst_writer_threads;
988
+ for (int i = 0; i < num_files; ++i) {
989
+ sst_writer_threads.emplace_back(write_file_func);
990
+ }
991
+
992
+ for (auto& t : sst_writer_threads) {
993
+ t.join();
994
+ }
995
+
996
+ fprintf(stderr, "Wrote %d files (%d keys)\n", num_files,
997
+ num_files * keys_per_file);
998
+
999
+ thread_num.store(0);
1000
+ std::atomic<int> files_added(0);
1001
+ // Thread 0 -> Load {f0,f1}
1002
+ // Thread 1 -> Load {f0,f1}
1003
+ // Thread 2 -> Load {f2,f3}
1004
+ // Thread 3 -> Load {f2,f3}
1005
+ // Thread 4 -> Load {f4,f5}
1006
+ // Thread 5 -> Load {f4,f5}
1007
+ // ...
1008
+ std::function<void()> load_file_func = [&]() {
1009
+ // We intentionally add every file twice, and assert that it was added
1010
+ // only once and the other add failed
1011
+ int thread_id = thread_num.fetch_add(1);
1012
+ int file_idx = (thread_id / 2) * 2;
1013
+ // sometimes we use copy, sometimes link .. the result should be the same
1014
+ bool move_file = (thread_id % 3 == 0);
1015
+
1016
+ std::vector<std::string> files_to_add;
1017
+
1018
+ files_to_add = {file_names[file_idx]};
1019
+ if (static_cast<size_t>(file_idx + 1) < file_names.size()) {
1020
+ files_to_add.push_back(file_names[file_idx + 1]);
1021
+ }
1022
+
1023
+ Status s = DeprecatedAddFile(files_to_add, move_file);
1024
+ if (s.ok()) {
1025
+ files_added += static_cast<int>(files_to_add.size());
1026
+ }
1027
+ };
1028
+
1029
+ // Bulk load num_files files in parallel
1030
+ std::vector<port::Thread> add_file_threads;
1031
+ DestroyAndReopen(options);
1032
+ for (int i = 0; i < num_files; ++i) {
1033
+ add_file_threads.emplace_back(load_file_func);
1034
+ }
1035
+
1036
+ for (auto& t : add_file_threads) {
1037
+ t.join();
1038
+ }
1039
+ ASSERT_EQ(files_added.load(), num_files);
1040
+ fprintf(stderr, "Loaded %d files (%d keys)\n", num_files,
1041
+ num_files * keys_per_file);
1042
+
1043
+ // Overwrite values of keys divisible by 100
1044
+ for (int k = 0; k < num_files * keys_per_file; k += 100) {
1045
+ std::string key = Key(k);
1046
+ ASSERT_OK(Put(key, key + "_new"));
1047
+ }
1048
+
1049
+ for (int i = 0; i < 2; i++) {
1050
+ // Make sure the values are correct before and after flush/compaction
1051
+ for (int k = 0; k < num_files * keys_per_file; ++k) {
1052
+ std::string key = Key(k);
1053
+ std::string value = (k % 100 == 0) ? (key + "_new") : key;
1054
+ ASSERT_EQ(Get(key), value);
1055
+ }
1056
+ ASSERT_OK(Flush());
1057
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
1058
+ }
1059
+
1060
+ fprintf(stderr, "Verified %d values\n", num_files * keys_per_file);
1061
+ DestroyAndRecreateExternalSSTFilesDir();
1062
+ } while (ChangeOptions(kSkipPlainTable | kSkipFIFOCompaction));
1063
+ }
1064
+
1065
+ TEST_F(ExternalSSTFileTest, OverlappingRanges) {
1066
+ env_->skip_fsync_ = true;
1067
+ Random rnd(301);
1068
+ SequenceNumber assigned_seqno = 0;
1069
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1070
+ "ExternalSstFileIngestionJob::Run", [&assigned_seqno](void* arg) {
1071
+ ASSERT_TRUE(arg != nullptr);
1072
+ assigned_seqno = *(static_cast<SequenceNumber*>(arg));
1073
+ });
1074
+ bool need_flush = false;
1075
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1076
+ "DBImpl::IngestExternalFile:NeedFlush", [&need_flush](void* arg) {
1077
+ ASSERT_TRUE(arg != nullptr);
1078
+ need_flush = *(static_cast<bool*>(arg));
1079
+ });
1080
+ bool overlap_with_db = false;
1081
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1082
+ "ExternalSstFileIngestionJob::AssignLevelAndSeqnoForIngestedFile",
1083
+ [&overlap_with_db](void* arg) {
1084
+ ASSERT_TRUE(arg != nullptr);
1085
+ overlap_with_db = *(static_cast<bool*>(arg));
1086
+ });
1087
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1088
+ do {
1089
+ Options options = CurrentOptions();
1090
+ env_->skip_fsync_ = true;
1091
+ DestroyAndReopen(options);
1092
+
1093
+ SstFileWriter sst_file_writer(EnvOptions(), options);
1094
+
1095
+ printf("Option config = %d\n", option_config_);
1096
+ std::vector<std::pair<int, int>> key_ranges;
1097
+ for (int i = 0; i < 100; i++) {
1098
+ int range_start = rnd.Uniform(20000);
1099
+ int keys_per_range = 10 + rnd.Uniform(41);
1100
+
1101
+ key_ranges.emplace_back(range_start, range_start + keys_per_range);
1102
+ }
1103
+
1104
+ int memtable_add = 0;
1105
+ int success_add_file = 0;
1106
+ int failed_add_file = 0;
1107
+ std::map<std::string, std::string> true_data;
1108
+ for (size_t i = 0; i < key_ranges.size(); i++) {
1109
+ int range_start = key_ranges[i].first;
1110
+ int range_end = key_ranges[i].second;
1111
+
1112
+ Status s;
1113
+ std::string range_val = "range_" + ToString(i);
1114
+
1115
+ // For 20% of ranges we use DB::Put, for 80% we use DB::AddFile
1116
+ if (i && i % 5 == 0) {
1117
+ // Use DB::Put to insert range (insert into memtable)
1118
+ range_val += "_put";
1119
+ for (int k = range_start; k <= range_end; k++) {
1120
+ s = Put(Key(k), range_val);
1121
+ ASSERT_OK(s);
1122
+ }
1123
+ memtable_add++;
1124
+ } else {
1125
+ // Use DB::AddFile to insert range
1126
+ range_val += "_add_file";
1127
+
1128
+ // Generate the file containing the range
1129
+ std::string file_name = sst_files_dir_ + env_->GenerateUniqueId();
1130
+ s = sst_file_writer.Open(file_name);
1131
+ ASSERT_OK(s);
1132
+ for (int k = range_start; k <= range_end; k++) {
1133
+ s = sst_file_writer.Put(Key(k), range_val);
1134
+ ASSERT_OK(s);
1135
+ }
1136
+ ExternalSstFileInfo file_info;
1137
+ s = sst_file_writer.Finish(&file_info);
1138
+ ASSERT_OK(s);
1139
+
1140
+ // Insert the generated file
1141
+ s = DeprecatedAddFile({file_name});
1142
+ auto it = true_data.lower_bound(Key(range_start));
1143
+ if (option_config_ != kUniversalCompaction &&
1144
+ option_config_ != kUniversalCompactionMultiLevel &&
1145
+ option_config_ != kUniversalSubcompactions) {
1146
+ if (it != true_data.end() && it->first <= Key(range_end)) {
1147
+ // This range overlap with data already exist in DB
1148
+ ASSERT_NOK(s);
1149
+ failed_add_file++;
1150
+ } else {
1151
+ ASSERT_OK(s);
1152
+ success_add_file++;
1153
+ }
1154
+ } else {
1155
+ if ((it != true_data.end() && it->first <= Key(range_end)) ||
1156
+ need_flush || assigned_seqno > 0 || overlap_with_db) {
1157
+ // This range overlap with data already exist in DB
1158
+ ASSERT_NOK(s);
1159
+ failed_add_file++;
1160
+ } else {
1161
+ ASSERT_OK(s);
1162
+ success_add_file++;
1163
+ }
1164
+ }
1165
+ }
1166
+
1167
+ if (s.ok()) {
1168
+ // Update true_data map to include the new inserted data
1169
+ for (int k = range_start; k <= range_end; k++) {
1170
+ true_data[Key(k)] = range_val;
1171
+ }
1172
+ }
1173
+
1174
+ // Flush / Compact the DB
1175
+ if (i && i % 50 == 0) {
1176
+ ASSERT_OK(Flush());
1177
+ }
1178
+ if (i && i % 75 == 0) {
1179
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
1180
+ }
1181
+ }
1182
+
1183
+ printf("Total: %" ROCKSDB_PRIszt
1184
+ " ranges\n"
1185
+ "AddFile()|Success: %d ranges\n"
1186
+ "AddFile()|RangeConflict: %d ranges\n"
1187
+ "Put(): %d ranges\n",
1188
+ key_ranges.size(), success_add_file, failed_add_file, memtable_add);
1189
+
1190
+ // Verify the correctness of the data
1191
+ for (const auto& kv : true_data) {
1192
+ ASSERT_EQ(Get(kv.first), kv.second);
1193
+ }
1194
+ printf("keys/values verified\n");
1195
+ DestroyAndRecreateExternalSSTFilesDir();
1196
+ } while (ChangeOptions(kSkipPlainTable | kSkipFIFOCompaction));
1197
+ }
1198
+
1199
+ TEST_P(ExternalSSTFileTest, PickedLevel) {
1200
+ env_->skip_fsync_ = true;
1201
+ Options options = CurrentOptions();
1202
+ options.disable_auto_compactions = false;
1203
+ options.level0_file_num_compaction_trigger = 4;
1204
+ options.num_levels = 4;
1205
+ DestroyAndReopen(options);
1206
+
1207
+ std::map<std::string, std::string> true_data;
1208
+
1209
+ // File 0 will go to last level (L3)
1210
+ ASSERT_OK(GenerateAndAddExternalFile(options, {1, 10}, -1, false, false, true,
1211
+ false, false, &true_data));
1212
+ EXPECT_EQ(FilesPerLevel(), "0,0,0,1");
1213
+
1214
+ // File 1 will go to level L2 (since it overlap with file 0 in L3)
1215
+ ASSERT_OK(GenerateAndAddExternalFile(options, {2, 9}, -1, false, false, true,
1216
+ false, false, &true_data));
1217
+ EXPECT_EQ(FilesPerLevel(), "0,0,1,1");
1218
+
1219
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency({
1220
+ {"ExternalSSTFileTest::PickedLevel:0", "BackgroundCallCompaction:0"},
1221
+ {"DBImpl::BackgroundCompaction:Start",
1222
+ "ExternalSSTFileTest::PickedLevel:1"},
1223
+ {"ExternalSSTFileTest::PickedLevel:2",
1224
+ "DBImpl::BackgroundCompaction:NonTrivial:AfterRun"},
1225
+ });
1226
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1227
+
1228
+ // Flush 4 files containing the same keys
1229
+ for (int i = 0; i < 4; i++) {
1230
+ ASSERT_OK(Put(Key(3), Key(3) + "put"));
1231
+ ASSERT_OK(Put(Key(8), Key(8) + "put"));
1232
+ true_data[Key(3)] = Key(3) + "put";
1233
+ true_data[Key(8)] = Key(8) + "put";
1234
+ ASSERT_OK(Flush());
1235
+ }
1236
+
1237
+ // Wait for BackgroundCompaction() to be called
1238
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevel:0");
1239
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevel:1");
1240
+
1241
+ EXPECT_EQ(FilesPerLevel(), "4,0,1,1");
1242
+
1243
+ // This file overlaps with file 0 (L3), file 1 (L2) and the
1244
+ // output of compaction going to L1
1245
+ ASSERT_OK(GenerateAndAddExternalFile(options, {4, 7}, -1, false, false, true,
1246
+ false, false, &true_data));
1247
+ EXPECT_EQ(FilesPerLevel(), "5,0,1,1");
1248
+
1249
+ // This file does not overlap with any file or with the running compaction
1250
+ ASSERT_OK(GenerateAndAddExternalFile(options, {9000, 9001}, -1, false, false,
1251
+ false, false, false, &true_data));
1252
+ EXPECT_EQ(FilesPerLevel(), "5,0,1,2");
1253
+
1254
+ // Hold compaction from finishing
1255
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevel:2");
1256
+
1257
+ ASSERT_OK(dbfull()->TEST_WaitForCompact());
1258
+ EXPECT_EQ(FilesPerLevel(), "1,1,1,2");
1259
+
1260
+ size_t kcnt = 0;
1261
+ VerifyDBFromMap(true_data, &kcnt, false);
1262
+
1263
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
1264
+ }
1265
+
1266
+ TEST_F(ExternalSSTFileTest, PickedLevelBug) {
1267
+ env_->skip_fsync_ = true;
1268
+ Options options = CurrentOptions();
1269
+ options.disable_auto_compactions = false;
1270
+ options.level0_file_num_compaction_trigger = 3;
1271
+ options.num_levels = 2;
1272
+ DestroyAndReopen(options);
1273
+
1274
+ std::vector<int> file_keys;
1275
+
1276
+ // file #1 in L0
1277
+ file_keys = {0, 5, 7};
1278
+ for (int k : file_keys) {
1279
+ ASSERT_OK(Put(Key(k), Key(k)));
1280
+ }
1281
+ ASSERT_OK(Flush());
1282
+
1283
+ // file #2 in L0
1284
+ file_keys = {4, 6, 8, 9};
1285
+ for (int k : file_keys) {
1286
+ ASSERT_OK(Put(Key(k), Key(k)));
1287
+ }
1288
+ ASSERT_OK(Flush());
1289
+
1290
+ // We have 2 overlapping files in L0
1291
+ EXPECT_EQ(FilesPerLevel(), "2");
1292
+
1293
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
1294
+ {{"DBImpl::AddFile:MutexLock", "ExternalSSTFileTest::PickedLevelBug:0"},
1295
+ {"ExternalSSTFileTest::PickedLevelBug:1", "DBImpl::AddFile:MutexUnlock"},
1296
+ {"ExternalSSTFileTest::PickedLevelBug:2",
1297
+ "DBImpl::RunManualCompaction:0"},
1298
+ {"ExternalSSTFileTest::PickedLevelBug:3",
1299
+ "DBImpl::RunManualCompaction:1"}});
1300
+
1301
+ std::atomic<bool> bg_compact_started(false);
1302
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1303
+ "DBImpl::BackgroundCompaction:Start",
1304
+ [&](void* /*arg*/) { bg_compact_started.store(true); });
1305
+
1306
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1307
+
1308
+ // While writing the MANIFEST start a thread that will ask for compaction
1309
+ Status bg_compact_status;
1310
+ ROCKSDB_NAMESPACE::port::Thread bg_compact([&]() {
1311
+ bg_compact_status =
1312
+ db_->CompactRange(CompactRangeOptions(), nullptr, nullptr);
1313
+ });
1314
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelBug:2");
1315
+
1316
+ // Start a thread that will ingest a new file
1317
+ Status bg_addfile_status;
1318
+ ROCKSDB_NAMESPACE::port::Thread bg_addfile([&]() {
1319
+ file_keys = {1, 2, 3};
1320
+ bg_addfile_status = GenerateAndAddExternalFile(options, file_keys, 1);
1321
+ });
1322
+
1323
+ // Wait for AddFile to start picking levels and writing MANIFEST
1324
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelBug:0");
1325
+
1326
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelBug:3");
1327
+
1328
+ // We need to verify that no compactions can run while AddFile is
1329
+ // ingesting the files into the levels it find suitable. So we will
1330
+ // wait for 2 seconds to give a chance for compactions to run during
1331
+ // this period, and then make sure that no compactions where able to run
1332
+ env_->SleepForMicroseconds(1000000 * 2);
1333
+ ASSERT_FALSE(bg_compact_started.load());
1334
+
1335
+ // Hold AddFile from finishing writing the MANIFEST
1336
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelBug:1");
1337
+
1338
+ bg_addfile.join();
1339
+ bg_compact.join();
1340
+
1341
+ ASSERT_OK(bg_addfile_status);
1342
+ ASSERT_OK(bg_compact_status);
1343
+
1344
+ ASSERT_OK(dbfull()->TEST_WaitForCompact());
1345
+
1346
+ int total_keys = 0;
1347
+ Iterator* iter = db_->NewIterator(ReadOptions());
1348
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
1349
+ ASSERT_OK(iter->status());
1350
+ total_keys++;
1351
+ }
1352
+ ASSERT_EQ(total_keys, 10);
1353
+
1354
+ delete iter;
1355
+
1356
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
1357
+ }
1358
+
1359
+ TEST_F(ExternalSSTFileTest, IngestNonExistingFile) {
1360
+ Options options = CurrentOptions();
1361
+ DestroyAndReopen(options);
1362
+
1363
+ Status s = db_->IngestExternalFile({"non_existing_file"},
1364
+ IngestExternalFileOptions());
1365
+ ASSERT_NOK(s);
1366
+
1367
+ // Verify file deletion is not impacted (verify a bug fix)
1368
+ ASSERT_OK(Put(Key(1), Key(1)));
1369
+ ASSERT_OK(Put(Key(9), Key(9)));
1370
+ ASSERT_OK(Flush());
1371
+
1372
+ ASSERT_OK(Put(Key(1), Key(1)));
1373
+ ASSERT_OK(Put(Key(9), Key(9)));
1374
+ ASSERT_OK(Flush());
1375
+
1376
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
1377
+ ASSERT_OK(dbfull()->TEST_WaitForCompact(true));
1378
+
1379
+ // After full compaction, there should be only 1 file.
1380
+ std::vector<std::string> files;
1381
+ ASSERT_OK(env_->GetChildren(dbname_, &files));
1382
+ int num_sst_files = 0;
1383
+ for (auto& f : files) {
1384
+ uint64_t number;
1385
+ FileType type;
1386
+ if (ParseFileName(f, &number, &type) && type == kTableFile) {
1387
+ num_sst_files++;
1388
+ }
1389
+ }
1390
+ ASSERT_EQ(1, num_sst_files);
1391
+ }
1392
+
1393
+ TEST_F(ExternalSSTFileTest, CompactDuringAddFileRandom) {
1394
+ env_->skip_fsync_ = true;
1395
+ Options options = CurrentOptions();
1396
+ options.disable_auto_compactions = false;
1397
+ options.level0_file_num_compaction_trigger = 2;
1398
+ options.num_levels = 2;
1399
+ DestroyAndReopen(options);
1400
+
1401
+ std::function<void()> bg_compact = [&]() {
1402
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
1403
+ };
1404
+
1405
+ int range_id = 0;
1406
+ std::vector<int> file_keys;
1407
+ std::function<void()> bg_addfile = [&]() {
1408
+ ASSERT_OK(GenerateAndAddExternalFile(options, file_keys, range_id));
1409
+ };
1410
+
1411
+ const int num_of_ranges = 1000;
1412
+ std::vector<port::Thread> threads;
1413
+ while (range_id < num_of_ranges) {
1414
+ int range_start = range_id * 10;
1415
+ int range_end = range_start + 10;
1416
+
1417
+ file_keys.clear();
1418
+ for (int k = range_start + 1; k < range_end; k++) {
1419
+ file_keys.push_back(k);
1420
+ }
1421
+ ASSERT_OK(Put(Key(range_start), Key(range_start)));
1422
+ ASSERT_OK(Put(Key(range_end), Key(range_end)));
1423
+ ASSERT_OK(Flush());
1424
+
1425
+ if (range_id % 10 == 0) {
1426
+ threads.emplace_back(bg_compact);
1427
+ }
1428
+ threads.emplace_back(bg_addfile);
1429
+
1430
+ for (auto& t : threads) {
1431
+ t.join();
1432
+ }
1433
+ threads.clear();
1434
+
1435
+ range_id++;
1436
+ }
1437
+
1438
+ for (int rid = 0; rid < num_of_ranges; rid++) {
1439
+ int range_start = rid * 10;
1440
+ int range_end = range_start + 10;
1441
+
1442
+ ASSERT_EQ(Get(Key(range_start)), Key(range_start)) << rid;
1443
+ ASSERT_EQ(Get(Key(range_end)), Key(range_end)) << rid;
1444
+ for (int k = range_start + 1; k < range_end; k++) {
1445
+ std::string v = Key(k) + ToString(rid);
1446
+ ASSERT_EQ(Get(Key(k)), v) << rid;
1447
+ }
1448
+ }
1449
+ }
1450
+
1451
+ TEST_F(ExternalSSTFileTest, PickedLevelDynamic) {
1452
+ env_->skip_fsync_ = true;
1453
+ Options options = CurrentOptions();
1454
+ options.disable_auto_compactions = false;
1455
+ options.level0_file_num_compaction_trigger = 4;
1456
+ options.level_compaction_dynamic_level_bytes = true;
1457
+ options.num_levels = 4;
1458
+ DestroyAndReopen(options);
1459
+ std::map<std::string, std::string> true_data;
1460
+
1461
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency({
1462
+ {"ExternalSSTFileTest::PickedLevelDynamic:0",
1463
+ "BackgroundCallCompaction:0"},
1464
+ {"DBImpl::BackgroundCompaction:Start",
1465
+ "ExternalSSTFileTest::PickedLevelDynamic:1"},
1466
+ {"ExternalSSTFileTest::PickedLevelDynamic:2",
1467
+ "DBImpl::BackgroundCompaction:NonTrivial:AfterRun"},
1468
+ });
1469
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1470
+
1471
+ // Flush 4 files containing the same keys
1472
+ for (int i = 0; i < 4; i++) {
1473
+ for (int k = 20; k <= 30; k++) {
1474
+ ASSERT_OK(Put(Key(k), Key(k) + "put"));
1475
+ true_data[Key(k)] = Key(k) + "put";
1476
+ }
1477
+ for (int k = 50; k <= 60; k++) {
1478
+ ASSERT_OK(Put(Key(k), Key(k) + "put"));
1479
+ true_data[Key(k)] = Key(k) + "put";
1480
+ }
1481
+ ASSERT_OK(Flush());
1482
+ }
1483
+
1484
+ // Wait for BackgroundCompaction() to be called
1485
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelDynamic:0");
1486
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelDynamic:1");
1487
+
1488
+ // This file overlaps with the output of the compaction (going to L3)
1489
+ // so the file will be added to L0 since L3 is the base level
1490
+ ASSERT_OK(GenerateAndAddExternalFile(options, {31, 32, 33, 34}, -1, false,
1491
+ false, true, false, false, &true_data));
1492
+ EXPECT_EQ(FilesPerLevel(), "5");
1493
+
1494
+ // This file does not overlap with the current running compactiong
1495
+ ASSERT_OK(GenerateAndAddExternalFile(options, {9000, 9001}, -1, false, false,
1496
+ true, false, false, &true_data));
1497
+ EXPECT_EQ(FilesPerLevel(), "5,0,0,1");
1498
+
1499
+ // Hold compaction from finishing
1500
+ TEST_SYNC_POINT("ExternalSSTFileTest::PickedLevelDynamic:2");
1501
+
1502
+ // Output of the compaction will go to L3
1503
+ ASSERT_OK(dbfull()->TEST_WaitForCompact());
1504
+ EXPECT_EQ(FilesPerLevel(), "1,0,0,2");
1505
+
1506
+ Close();
1507
+ options.disable_auto_compactions = true;
1508
+ Reopen(options);
1509
+
1510
+ ASSERT_OK(GenerateAndAddExternalFile(options, {1, 15, 19}, -1, false, false,
1511
+ true, false, false, &true_data));
1512
+ ASSERT_EQ(FilesPerLevel(), "1,0,0,3");
1513
+
1514
+ ASSERT_OK(GenerateAndAddExternalFile(options, {1000, 1001, 1002}, -1, false,
1515
+ false, true, false, false, &true_data));
1516
+ ASSERT_EQ(FilesPerLevel(), "1,0,0,4");
1517
+
1518
+ ASSERT_OK(GenerateAndAddExternalFile(options, {500, 600, 700}, -1, false,
1519
+ false, true, false, false, &true_data));
1520
+ ASSERT_EQ(FilesPerLevel(), "1,0,0,5");
1521
+
1522
+ // File 5 overlaps with file 2 (L3 / base level)
1523
+ ASSERT_OK(GenerateAndAddExternalFile(options, {2, 10}, -1, false, false, true,
1524
+ false, false, &true_data));
1525
+ ASSERT_EQ(FilesPerLevel(), "2,0,0,5");
1526
+
1527
+ // File 6 overlaps with file 2 (L3 / base level) and file 5 (L0)
1528
+ ASSERT_OK(GenerateAndAddExternalFile(options, {3, 9}, -1, false, false, true,
1529
+ false, false, &true_data));
1530
+ ASSERT_EQ(FilesPerLevel(), "3,0,0,5");
1531
+
1532
+ // Verify data in files
1533
+ size_t kcnt = 0;
1534
+ VerifyDBFromMap(true_data, &kcnt, false);
1535
+
1536
+ // Write range [5 => 10] to L0
1537
+ for (int i = 5; i <= 10; i++) {
1538
+ std::string k = Key(i);
1539
+ std::string v = k + "put";
1540
+ ASSERT_OK(Put(k, v));
1541
+ true_data[k] = v;
1542
+ }
1543
+ ASSERT_OK(Flush());
1544
+ ASSERT_EQ(FilesPerLevel(), "4,0,0,5");
1545
+
1546
+ // File 7 overlaps with file 4 (L3)
1547
+ ASSERT_OK(GenerateAndAddExternalFile(options, {650, 651, 652}, -1, false,
1548
+ false, true, false, false, &true_data));
1549
+ ASSERT_EQ(FilesPerLevel(), "5,0,0,5");
1550
+
1551
+ VerifyDBFromMap(true_data, &kcnt, false);
1552
+
1553
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
1554
+ }
1555
+
1556
+ TEST_F(ExternalSSTFileTest, AddExternalSstFileWithCustomCompartor) {
1557
+ Options options = CurrentOptions();
1558
+ options.comparator = ReverseBytewiseComparator();
1559
+ DestroyAndReopen(options);
1560
+
1561
+ SstFileWriter sst_file_writer(EnvOptions(), options);
1562
+
1563
+ // Generate files with these key ranges
1564
+ // {14 -> 0}
1565
+ // {24 -> 10}
1566
+ // {34 -> 20}
1567
+ // {44 -> 30}
1568
+ // ..
1569
+ std::vector<std::string> generated_files;
1570
+ for (int i = 0; i < 10; i++) {
1571
+ std::string file_name = sst_files_dir_ + env_->GenerateUniqueId();
1572
+ ASSERT_OK(sst_file_writer.Open(file_name));
1573
+
1574
+ int range_end = i * 10;
1575
+ int range_start = range_end + 15;
1576
+ for (int k = (range_start - 1); k >= range_end; k--) {
1577
+ ASSERT_OK(sst_file_writer.Put(Key(k), Key(k)));
1578
+ }
1579
+ ExternalSstFileInfo file_info;
1580
+ ASSERT_OK(sst_file_writer.Finish(&file_info));
1581
+ generated_files.push_back(file_name);
1582
+ }
1583
+
1584
+ std::vector<std::string> in_files;
1585
+
1586
+ // These 2nd and 3rd files overlap with each other
1587
+ in_files = {generated_files[0], generated_files[4], generated_files[5],
1588
+ generated_files[7]};
1589
+ ASSERT_NOK(DeprecatedAddFile(in_files));
1590
+
1591
+ // These 2 files don't overlap with each other
1592
+ in_files = {generated_files[0], generated_files[2]};
1593
+ ASSERT_OK(DeprecatedAddFile(in_files));
1594
+
1595
+ // These 2 files don't overlap with each other but overlap with keys in DB
1596
+ in_files = {generated_files[3], generated_files[7]};
1597
+ ASSERT_NOK(DeprecatedAddFile(in_files));
1598
+
1599
+ // Files don't overlap and don't overlap with DB key range
1600
+ in_files = {generated_files[4], generated_files[6], generated_files[8]};
1601
+ ASSERT_OK(DeprecatedAddFile(in_files));
1602
+
1603
+ for (int i = 0; i < 100; i++) {
1604
+ if (i % 20 <= 14) {
1605
+ ASSERT_EQ(Get(Key(i)), Key(i));
1606
+ } else {
1607
+ ASSERT_EQ(Get(Key(i)), "NOT_FOUND");
1608
+ }
1609
+ }
1610
+ }
1611
+
1612
+ TEST_F(ExternalSSTFileTest, AddFileTrivialMoveBug) {
1613
+ Options options = CurrentOptions();
1614
+ options.num_levels = 3;
1615
+ options.IncreaseParallelism(20);
1616
+ DestroyAndReopen(options);
1617
+
1618
+ ASSERT_OK(GenerateAndAddExternalFile(options, {1, 4}, 1)); // L3
1619
+ ASSERT_OK(GenerateAndAddExternalFile(options, {2, 3}, 2)); // L2
1620
+
1621
+ ASSERT_OK(GenerateAndAddExternalFile(options, {10, 14}, 3)); // L3
1622
+ ASSERT_OK(GenerateAndAddExternalFile(options, {12, 13}, 4)); // L2
1623
+
1624
+ ASSERT_OK(GenerateAndAddExternalFile(options, {20, 24}, 5)); // L3
1625
+ ASSERT_OK(GenerateAndAddExternalFile(options, {22, 23}, 6)); // L2
1626
+
1627
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1628
+ "CompactionJob::Run():Start", [&](void* /*arg*/) {
1629
+ // fit in L3 but will overlap with compaction so will be added
1630
+ // to L2 but a compaction will trivially move it to L3
1631
+ // and break LSM consistency
1632
+ static std::atomic<bool> called = {false};
1633
+ if (!called) {
1634
+ called = true;
1635
+ ASSERT_OK(dbfull()->SetOptions({{"max_bytes_for_level_base", "1"}}));
1636
+ ASSERT_OK(GenerateAndAddExternalFile(options, {15, 16}, 7));
1637
+ }
1638
+ });
1639
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1640
+
1641
+ CompactRangeOptions cro;
1642
+ cro.exclusive_manual_compaction = false;
1643
+ ASSERT_OK(db_->CompactRange(cro, nullptr, nullptr));
1644
+
1645
+ ASSERT_OK(dbfull()->TEST_WaitForCompact());
1646
+
1647
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
1648
+ }
1649
+
1650
+ TEST_F(ExternalSSTFileTest, CompactAddedFiles) {
1651
+ Options options = CurrentOptions();
1652
+ options.num_levels = 3;
1653
+ DestroyAndReopen(options);
1654
+
1655
+ ASSERT_OK(GenerateAndAddExternalFile(options, {1, 10}, 1)); // L3
1656
+ ASSERT_OK(GenerateAndAddExternalFile(options, {2, 9}, 2)); // L2
1657
+ ASSERT_OK(GenerateAndAddExternalFile(options, {3, 8}, 3)); // L1
1658
+ ASSERT_OK(GenerateAndAddExternalFile(options, {4, 7}, 4)); // L0
1659
+
1660
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
1661
+ }
1662
+
1663
+ TEST_F(ExternalSSTFileTest, SstFileWriterNonSharedKeys) {
1664
+ Options options = CurrentOptions();
1665
+ DestroyAndReopen(options);
1666
+ std::string file_path = sst_files_dir_ + "/not_shared";
1667
+ SstFileWriter sst_file_writer(EnvOptions(), options);
1668
+
1669
+ std::string suffix(100, 'X');
1670
+ ASSERT_OK(sst_file_writer.Open(file_path));
1671
+ ASSERT_OK(sst_file_writer.Put("A" + suffix, "VAL"));
1672
+ ASSERT_OK(sst_file_writer.Put("BB" + suffix, "VAL"));
1673
+ ASSERT_OK(sst_file_writer.Put("CC" + suffix, "VAL"));
1674
+ ASSERT_OK(sst_file_writer.Put("CXD" + suffix, "VAL"));
1675
+ ASSERT_OK(sst_file_writer.Put("CZZZ" + suffix, "VAL"));
1676
+ ASSERT_OK(sst_file_writer.Put("ZAAAX" + suffix, "VAL"));
1677
+
1678
+ ASSERT_OK(sst_file_writer.Finish());
1679
+ ASSERT_OK(DeprecatedAddFile({file_path}));
1680
+ }
1681
+
1682
+ TEST_F(ExternalSSTFileTest, WithUnorderedWrite) {
1683
+ SyncPoint::GetInstance()->DisableProcessing();
1684
+ SyncPoint::GetInstance()->LoadDependency(
1685
+ {{"DBImpl::WriteImpl:UnorderedWriteAfterWriteWAL",
1686
+ "ExternalSSTFileTest::WithUnorderedWrite:WaitWriteWAL"},
1687
+ {"DBImpl::WaitForPendingWrites:BeforeBlock",
1688
+ "DBImpl::WriteImpl:BeforeUnorderedWriteMemtable"}});
1689
+ SyncPoint::GetInstance()->SetCallBack(
1690
+ "DBImpl::IngestExternalFile:NeedFlush", [&](void* need_flush) {
1691
+ ASSERT_TRUE(*reinterpret_cast<bool*>(need_flush));
1692
+ });
1693
+
1694
+ Options options = CurrentOptions();
1695
+ options.unordered_write = true;
1696
+ DestroyAndReopen(options);
1697
+ ASSERT_OK(Put("foo", "v1"));
1698
+ SyncPoint::GetInstance()->EnableProcessing();
1699
+ port::Thread writer([&]() { ASSERT_OK(Put("bar", "v2")); });
1700
+
1701
+ TEST_SYNC_POINT("ExternalSSTFileTest::WithUnorderedWrite:WaitWriteWAL");
1702
+ ASSERT_OK(GenerateAndAddExternalFile(options, {{"bar", "v3"}}, -1,
1703
+ true /* allow_global_seqno */));
1704
+ ASSERT_EQ(Get("bar"), "v3");
1705
+
1706
+ writer.join();
1707
+ SyncPoint::GetInstance()->DisableProcessing();
1708
+ SyncPoint::GetInstance()->ClearAllCallBacks();
1709
+ }
1710
+
1711
+ TEST_P(ExternalSSTFileTest, IngestFileWithGlobalSeqnoRandomized) {
1712
+ env_->skip_fsync_ = true;
1713
+ Options options = CurrentOptions();
1714
+ options.IncreaseParallelism(20);
1715
+ options.level0_slowdown_writes_trigger = 256;
1716
+ options.level0_stop_writes_trigger = 256;
1717
+
1718
+ bool write_global_seqno = std::get<0>(GetParam());
1719
+ bool verify_checksums_before_ingest = std::get<1>(GetParam());
1720
+ for (int iter = 0; iter < 2; iter++) {
1721
+ bool write_to_memtable = (iter == 0);
1722
+ DestroyAndReopen(options);
1723
+
1724
+ Random rnd(301);
1725
+ std::map<std::string, std::string> true_data;
1726
+ for (int i = 0; i < 500; i++) {
1727
+ std::vector<std::pair<std::string, std::string>> random_data;
1728
+ for (int j = 0; j < 100; j++) {
1729
+ std::string k = rnd.RandomString(rnd.Next() % 20);
1730
+ std::string v = rnd.RandomString(rnd.Next() % 50);
1731
+ random_data.emplace_back(k, v);
1732
+ }
1733
+
1734
+ if (write_to_memtable && rnd.OneIn(4)) {
1735
+ // 25% of writes go through memtable
1736
+ for (auto& entry : random_data) {
1737
+ ASSERT_OK(Put(entry.first, entry.second));
1738
+ true_data[entry.first] = entry.second;
1739
+ }
1740
+ } else {
1741
+ ASSERT_OK(GenerateAndAddExternalFile(
1742
+ options, random_data, -1, true, write_global_seqno,
1743
+ verify_checksums_before_ingest, false, true, &true_data));
1744
+ }
1745
+ }
1746
+ size_t kcnt = 0;
1747
+ VerifyDBFromMap(true_data, &kcnt, false);
1748
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
1749
+ VerifyDBFromMap(true_data, &kcnt, false);
1750
+ }
1751
+ }
1752
+
1753
+ TEST_P(ExternalSSTFileTest, IngestFileWithGlobalSeqnoAssignedLevel) {
1754
+ Options options = CurrentOptions();
1755
+ options.num_levels = 5;
1756
+ options.disable_auto_compactions = true;
1757
+ DestroyAndReopen(options);
1758
+ std::vector<std::pair<std::string, std::string>> file_data;
1759
+ std::map<std::string, std::string> true_data;
1760
+
1761
+ // Insert 100 -> 200 into the memtable
1762
+ for (int i = 100; i <= 200; i++) {
1763
+ ASSERT_OK(Put(Key(i), "memtable"));
1764
+ true_data[Key(i)] = "memtable";
1765
+ }
1766
+
1767
+ // Insert 0 -> 20 using AddFile
1768
+ file_data.clear();
1769
+ for (int i = 0; i <= 20; i++) {
1770
+ file_data.emplace_back(Key(i), "L4");
1771
+ }
1772
+ bool write_global_seqno = std::get<0>(GetParam());
1773
+ bool verify_checksums_before_ingest = std::get<1>(GetParam());
1774
+ ASSERT_OK(GenerateAndAddExternalFile(
1775
+ options, file_data, -1, true, write_global_seqno,
1776
+ verify_checksums_before_ingest, false, false, &true_data));
1777
+
1778
+ // This file don't overlap with anything in the DB, will go to L4
1779
+ ASSERT_EQ("0,0,0,0,1", FilesPerLevel());
1780
+
1781
+ // Insert 80 -> 130 using AddFile
1782
+ file_data.clear();
1783
+ for (int i = 80; i <= 130; i++) {
1784
+ file_data.emplace_back(Key(i), "L0");
1785
+ }
1786
+ ASSERT_OK(GenerateAndAddExternalFile(
1787
+ options, file_data, -1, true, write_global_seqno,
1788
+ verify_checksums_before_ingest, false, false, &true_data));
1789
+
1790
+ // This file overlap with the memtable, so it will flush it and add
1791
+ // it self to L0
1792
+ ASSERT_EQ("2,0,0,0,1", FilesPerLevel());
1793
+
1794
+ // Insert 30 -> 50 using AddFile
1795
+ file_data.clear();
1796
+ for (int i = 30; i <= 50; i++) {
1797
+ file_data.emplace_back(Key(i), "L4");
1798
+ }
1799
+ ASSERT_OK(GenerateAndAddExternalFile(
1800
+ options, file_data, -1, true, write_global_seqno,
1801
+ verify_checksums_before_ingest, false, false, &true_data));
1802
+
1803
+ // This file don't overlap with anything in the DB and fit in L4 as well
1804
+ ASSERT_EQ("2,0,0,0,2", FilesPerLevel());
1805
+
1806
+ // Insert 10 -> 40 using AddFile
1807
+ file_data.clear();
1808
+ for (int i = 10; i <= 40; i++) {
1809
+ file_data.emplace_back(Key(i), "L3");
1810
+ }
1811
+ ASSERT_OK(GenerateAndAddExternalFile(
1812
+ options, file_data, -1, true, write_global_seqno,
1813
+ verify_checksums_before_ingest, false, false, &true_data));
1814
+
1815
+ // This file overlap with files in L4, we will ingest it in L3
1816
+ ASSERT_EQ("2,0,0,1,2", FilesPerLevel());
1817
+
1818
+ size_t kcnt = 0;
1819
+ VerifyDBFromMap(true_data, &kcnt, false);
1820
+ }
1821
+
1822
+ TEST_P(ExternalSSTFileTest, IngestFileWithGlobalSeqnoMemtableFlush) {
1823
+ Options options = CurrentOptions();
1824
+ DestroyAndReopen(options);
1825
+ uint64_t entries_in_memtable;
1826
+ std::map<std::string, std::string> true_data;
1827
+
1828
+ for (int k : {10, 20, 40, 80}) {
1829
+ ASSERT_OK(Put(Key(k), "memtable"));
1830
+ true_data[Key(k)] = "memtable";
1831
+ }
1832
+ ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable,
1833
+ &entries_in_memtable));
1834
+ ASSERT_GE(entries_in_memtable, 1);
1835
+
1836
+ bool write_global_seqno = std::get<0>(GetParam());
1837
+ bool verify_checksums_before_ingest = std::get<1>(GetParam());
1838
+ // No need for flush
1839
+ ASSERT_OK(GenerateAndAddExternalFile(
1840
+ options, {90, 100, 110}, -1, true, write_global_seqno,
1841
+ verify_checksums_before_ingest, false, false, &true_data));
1842
+ ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable,
1843
+ &entries_in_memtable));
1844
+ ASSERT_GE(entries_in_memtable, 1);
1845
+
1846
+ // This file will flush the memtable
1847
+ ASSERT_OK(GenerateAndAddExternalFile(
1848
+ options, {19, 20, 21}, -1, true, write_global_seqno,
1849
+ verify_checksums_before_ingest, false, false, &true_data));
1850
+ ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable,
1851
+ &entries_in_memtable));
1852
+ ASSERT_EQ(entries_in_memtable, 0);
1853
+
1854
+ for (int k : {200, 201, 205, 206}) {
1855
+ ASSERT_OK(Put(Key(k), "memtable"));
1856
+ true_data[Key(k)] = "memtable";
1857
+ }
1858
+ ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable,
1859
+ &entries_in_memtable));
1860
+ ASSERT_GE(entries_in_memtable, 1);
1861
+
1862
+ // No need for flush, this file keys fit between the memtable keys
1863
+ ASSERT_OK(GenerateAndAddExternalFile(
1864
+ options, {202, 203, 204}, -1, true, write_global_seqno,
1865
+ verify_checksums_before_ingest, false, false, &true_data));
1866
+ ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable,
1867
+ &entries_in_memtable));
1868
+ ASSERT_GE(entries_in_memtable, 1);
1869
+
1870
+ // This file will flush the memtable
1871
+ ASSERT_OK(GenerateAndAddExternalFile(
1872
+ options, {206, 207}, -1, true, write_global_seqno,
1873
+ verify_checksums_before_ingest, false, false, &true_data));
1874
+ ASSERT_TRUE(db_->GetIntProperty(DB::Properties::kNumEntriesActiveMemTable,
1875
+ &entries_in_memtable));
1876
+ ASSERT_EQ(entries_in_memtable, 0);
1877
+
1878
+ size_t kcnt = 0;
1879
+ VerifyDBFromMap(true_data, &kcnt, false);
1880
+ }
1881
+
1882
+ TEST_P(ExternalSSTFileTest, L0SortingIssue) {
1883
+ Options options = CurrentOptions();
1884
+ options.num_levels = 2;
1885
+ DestroyAndReopen(options);
1886
+ std::map<std::string, std::string> true_data;
1887
+
1888
+ ASSERT_OK(Put(Key(1), "memtable"));
1889
+ ASSERT_OK(Put(Key(10), "memtable"));
1890
+
1891
+ bool write_global_seqno = std::get<0>(GetParam());
1892
+ bool verify_checksums_before_ingest = std::get<1>(GetParam());
1893
+ // No Flush needed, No global seqno needed, Ingest in L1
1894
+ ASSERT_OK(
1895
+ GenerateAndAddExternalFile(options, {7, 8}, -1, true, write_global_seqno,
1896
+ verify_checksums_before_ingest, false, false));
1897
+ // No Flush needed, but need a global seqno, Ingest in L0
1898
+ ASSERT_OK(
1899
+ GenerateAndAddExternalFile(options, {7, 8}, -1, true, write_global_seqno,
1900
+ verify_checksums_before_ingest, false, false));
1901
+ printf("%s\n", FilesPerLevel().c_str());
1902
+
1903
+ // Overwrite what we added using external files
1904
+ ASSERT_OK(Put(Key(7), "memtable"));
1905
+ ASSERT_OK(Put(Key(8), "memtable"));
1906
+
1907
+ // Read values from memtable
1908
+ ASSERT_EQ(Get(Key(7)), "memtable");
1909
+ ASSERT_EQ(Get(Key(8)), "memtable");
1910
+
1911
+ // Flush and read from L0
1912
+ ASSERT_OK(Flush());
1913
+ printf("%s\n", FilesPerLevel().c_str());
1914
+ ASSERT_EQ(Get(Key(7)), "memtable");
1915
+ ASSERT_EQ(Get(Key(8)), "memtable");
1916
+ }
1917
+
1918
+ TEST_F(ExternalSSTFileTest, CompactionDeadlock) {
1919
+ Options options = CurrentOptions();
1920
+ options.num_levels = 2;
1921
+ options.level0_file_num_compaction_trigger = 4;
1922
+ options.level0_slowdown_writes_trigger = 4;
1923
+ options.level0_stop_writes_trigger = 4;
1924
+ DestroyAndReopen(options);
1925
+
1926
+ // atomic conter of currently running bg threads
1927
+ std::atomic<int> running_threads(0);
1928
+
1929
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency({
1930
+ {"DBImpl::DelayWrite:Wait", "ExternalSSTFileTest::DeadLock:0"},
1931
+ {"ExternalSSTFileTest::DeadLock:1", "DBImpl::AddFile:Start"},
1932
+ {"DBImpl::AddFile:MutexLock", "ExternalSSTFileTest::DeadLock:2"},
1933
+ {"ExternalSSTFileTest::DeadLock:3", "BackgroundCallCompaction:0"},
1934
+ });
1935
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1936
+
1937
+ // Start ingesting and extrnal file in the background
1938
+ ROCKSDB_NAMESPACE::port::Thread bg_ingest_file([&]() {
1939
+ running_threads += 1;
1940
+ ASSERT_OK(GenerateAndAddExternalFile(options, {5, 6}));
1941
+ running_threads -= 1;
1942
+ });
1943
+
1944
+ ASSERT_OK(Put(Key(1), "memtable"));
1945
+ ASSERT_OK(Flush());
1946
+
1947
+ ASSERT_OK(Put(Key(2), "memtable"));
1948
+ ASSERT_OK(Flush());
1949
+
1950
+ ASSERT_OK(Put(Key(3), "memtable"));
1951
+ ASSERT_OK(Flush());
1952
+
1953
+ ASSERT_OK(Put(Key(4), "memtable"));
1954
+ ASSERT_OK(Flush());
1955
+
1956
+ // This thread will try to insert into the memtable but since we have 4 L0
1957
+ // files this thread will be blocked and hold the writer thread
1958
+ ROCKSDB_NAMESPACE::port::Thread bg_block_put([&]() {
1959
+ running_threads += 1;
1960
+ ASSERT_OK(Put(Key(10), "memtable"));
1961
+ running_threads -= 1;
1962
+ });
1963
+
1964
+ // Make sure DelayWrite is called first
1965
+ TEST_SYNC_POINT("ExternalSSTFileTest::DeadLock:0");
1966
+
1967
+ // `DBImpl::AddFile:Start` will wait until we be here
1968
+ TEST_SYNC_POINT("ExternalSSTFileTest::DeadLock:1");
1969
+
1970
+ // Wait for IngestExternalFile() to start and aquire mutex
1971
+ TEST_SYNC_POINT("ExternalSSTFileTest::DeadLock:2");
1972
+
1973
+ // Now let compaction start
1974
+ TEST_SYNC_POINT("ExternalSSTFileTest::DeadLock:3");
1975
+
1976
+ // Wait for max 5 seconds, if we did not finish all bg threads
1977
+ // then we hit the deadlock bug
1978
+ for (int i = 0; i < 10; i++) {
1979
+ if (running_threads.load() == 0) {
1980
+ break;
1981
+ }
1982
+ env_->SleepForMicroseconds(500000);
1983
+ }
1984
+
1985
+ ASSERT_EQ(running_threads.load(), 0);
1986
+
1987
+ bg_ingest_file.join();
1988
+ bg_block_put.join();
1989
+ }
1990
+
1991
+ TEST_F(ExternalSSTFileTest, DirtyExit) {
1992
+ Options options = CurrentOptions();
1993
+ DestroyAndReopen(options);
1994
+ std::string file_path = sst_files_dir_ + "/dirty_exit";
1995
+ std::unique_ptr<SstFileWriter> sst_file_writer;
1996
+
1997
+ // Destruct SstFileWriter without calling Finish()
1998
+ sst_file_writer.reset(new SstFileWriter(EnvOptions(), options));
1999
+ ASSERT_OK(sst_file_writer->Open(file_path));
2000
+ sst_file_writer.reset();
2001
+
2002
+ // Destruct SstFileWriter with a failing Finish
2003
+ sst_file_writer.reset(new SstFileWriter(EnvOptions(), options));
2004
+ ASSERT_OK(sst_file_writer->Open(file_path));
2005
+ ASSERT_NOK(sst_file_writer->Finish());
2006
+ }
2007
+
2008
+ TEST_F(ExternalSSTFileTest, FileWithCFInfo) {
2009
+ Options options = CurrentOptions();
2010
+ CreateAndReopenWithCF({"koko", "toto"}, options);
2011
+
2012
+ SstFileWriter sfw_default(EnvOptions(), options, handles_[0]);
2013
+ SstFileWriter sfw_cf1(EnvOptions(), options, handles_[1]);
2014
+ SstFileWriter sfw_cf2(EnvOptions(), options, handles_[2]);
2015
+ SstFileWriter sfw_unknown(EnvOptions(), options);
2016
+
2017
+ // default_cf.sst
2018
+ const std::string cf_default_sst = sst_files_dir_ + "/default_cf.sst";
2019
+ ASSERT_OK(sfw_default.Open(cf_default_sst));
2020
+ ASSERT_OK(sfw_default.Put("K1", "V1"));
2021
+ ASSERT_OK(sfw_default.Put("K2", "V2"));
2022
+ ASSERT_OK(sfw_default.Finish());
2023
+
2024
+ // cf1.sst
2025
+ const std::string cf1_sst = sst_files_dir_ + "/cf1.sst";
2026
+ ASSERT_OK(sfw_cf1.Open(cf1_sst));
2027
+ ASSERT_OK(sfw_cf1.Put("K3", "V1"));
2028
+ ASSERT_OK(sfw_cf1.Put("K4", "V2"));
2029
+ ASSERT_OK(sfw_cf1.Finish());
2030
+
2031
+ // cf_unknown.sst
2032
+ const std::string unknown_sst = sst_files_dir_ + "/cf_unknown.sst";
2033
+ ASSERT_OK(sfw_unknown.Open(unknown_sst));
2034
+ ASSERT_OK(sfw_unknown.Put("K5", "V1"));
2035
+ ASSERT_OK(sfw_unknown.Put("K6", "V2"));
2036
+ ASSERT_OK(sfw_unknown.Finish());
2037
+
2038
+ IngestExternalFileOptions ifo;
2039
+
2040
+ // SST CF don't match
2041
+ ASSERT_NOK(db_->IngestExternalFile(handles_[0], {cf1_sst}, ifo));
2042
+ // SST CF don't match
2043
+ ASSERT_NOK(db_->IngestExternalFile(handles_[2], {cf1_sst}, ifo));
2044
+ // SST CF match
2045
+ ASSERT_OK(db_->IngestExternalFile(handles_[1], {cf1_sst}, ifo));
2046
+
2047
+ // SST CF don't match
2048
+ ASSERT_NOK(db_->IngestExternalFile(handles_[1], {cf_default_sst}, ifo));
2049
+ // SST CF don't match
2050
+ ASSERT_NOK(db_->IngestExternalFile(handles_[2], {cf_default_sst}, ifo));
2051
+ // SST CF match
2052
+ ASSERT_OK(db_->IngestExternalFile(handles_[0], {cf_default_sst}, ifo));
2053
+
2054
+ // SST CF unknown
2055
+ ASSERT_OK(db_->IngestExternalFile(handles_[1], {unknown_sst}, ifo));
2056
+ // SST CF unknown
2057
+ ASSERT_OK(db_->IngestExternalFile(handles_[2], {unknown_sst}, ifo));
2058
+ // SST CF unknown
2059
+ ASSERT_OK(db_->IngestExternalFile(handles_[0], {unknown_sst}, ifo));
2060
+
2061
+ // Cannot ingest a file into a dropped CF
2062
+ ASSERT_OK(db_->DropColumnFamily(handles_[1]));
2063
+ ASSERT_NOK(db_->IngestExternalFile(handles_[1], {unknown_sst}, ifo));
2064
+
2065
+ // CF was not dropped, ok to Ingest
2066
+ ASSERT_OK(db_->IngestExternalFile(handles_[2], {unknown_sst}, ifo));
2067
+ }
2068
+
2069
+ /*
2070
+ * Test and verify the functionality of ingestion_options.move_files and
2071
+ * ingestion_options.failed_move_fall_back_to_copy
2072
+ */
2073
+ TEST_P(ExternSSTFileLinkFailFallbackTest, LinkFailFallBackExternalSst) {
2074
+ const bool fail_link = std::get<0>(GetParam());
2075
+ const bool failed_move_fall_back_to_copy = std::get<1>(GetParam());
2076
+ test_env_->set_fail_link(fail_link);
2077
+ const EnvOptions env_options;
2078
+ DestroyAndReopen(options_);
2079
+ const int kNumKeys = 10000;
2080
+ IngestExternalFileOptions ifo;
2081
+ ifo.move_files = true;
2082
+ ifo.failed_move_fall_back_to_copy = failed_move_fall_back_to_copy;
2083
+
2084
+ std::string file_path = sst_files_dir_ + "file1.sst";
2085
+ // Create SstFileWriter for default column family
2086
+ SstFileWriter sst_file_writer(env_options, options_);
2087
+ ASSERT_OK(sst_file_writer.Open(file_path));
2088
+ for (int i = 0; i < kNumKeys; i++) {
2089
+ ASSERT_OK(sst_file_writer.Put(Key(i), Key(i) + "_value"));
2090
+ }
2091
+ ASSERT_OK(sst_file_writer.Finish());
2092
+ uint64_t file_size = 0;
2093
+ ASSERT_OK(env_->GetFileSize(file_path, &file_size));
2094
+
2095
+ bool copyfile = false;
2096
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
2097
+ "ExternalSstFileIngestionJob::Prepare:CopyFile",
2098
+ [&](void* /* arg */) { copyfile = true; });
2099
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
2100
+
2101
+ const Status s = db_->IngestExternalFile({file_path}, ifo);
2102
+
2103
+ ColumnFamilyHandleImpl* cfh =
2104
+ static_cast<ColumnFamilyHandleImpl*>(dbfull()->DefaultColumnFamily());
2105
+ ColumnFamilyData* cfd = cfh->cfd();
2106
+ const InternalStats* internal_stats_ptr = cfd->internal_stats();
2107
+ const std::vector<InternalStats::CompactionStats>& comp_stats =
2108
+ internal_stats_ptr->TEST_GetCompactionStats();
2109
+ uint64_t bytes_copied = 0;
2110
+ uint64_t bytes_moved = 0;
2111
+ for (const auto& stats : comp_stats) {
2112
+ bytes_copied += stats.bytes_written;
2113
+ bytes_moved += stats.bytes_moved;
2114
+ }
2115
+
2116
+ if (!fail_link) {
2117
+ // Link operation succeeds. External SST should be moved.
2118
+ ASSERT_OK(s);
2119
+ ASSERT_EQ(0, bytes_copied);
2120
+ ASSERT_EQ(file_size, bytes_moved);
2121
+ ASSERT_FALSE(copyfile);
2122
+ } else {
2123
+ // Link operation fails.
2124
+ ASSERT_EQ(0, bytes_moved);
2125
+ if (failed_move_fall_back_to_copy) {
2126
+ ASSERT_OK(s);
2127
+ // Copy file is true since a failed link falls back to copy file.
2128
+ ASSERT_TRUE(copyfile);
2129
+ ASSERT_EQ(file_size, bytes_copied);
2130
+ } else {
2131
+ ASSERT_TRUE(s.IsNotSupported());
2132
+ // Copy file is false since a failed link does not fall back to copy file.
2133
+ ASSERT_FALSE(copyfile);
2134
+ ASSERT_EQ(0, bytes_copied);
2135
+ }
2136
+ }
2137
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
2138
+ }
2139
+
2140
+ class TestIngestExternalFileListener : public EventListener {
2141
+ public:
2142
+ void OnExternalFileIngested(DB* /*db*/,
2143
+ const ExternalFileIngestionInfo& info) override {
2144
+ ingested_files.push_back(info);
2145
+ }
2146
+
2147
+ std::vector<ExternalFileIngestionInfo> ingested_files;
2148
+ };
2149
+
2150
+ TEST_P(ExternalSSTFileTest, IngestionListener) {
2151
+ Options options = CurrentOptions();
2152
+ TestIngestExternalFileListener* listener =
2153
+ new TestIngestExternalFileListener();
2154
+ options.listeners.emplace_back(listener);
2155
+ CreateAndReopenWithCF({"koko", "toto"}, options);
2156
+
2157
+ bool write_global_seqno = std::get<0>(GetParam());
2158
+ bool verify_checksums_before_ingest = std::get<1>(GetParam());
2159
+ // Ingest into default cf
2160
+ ASSERT_OK(GenerateAndAddExternalFile(
2161
+ options, {1, 2}, -1, true, write_global_seqno,
2162
+ verify_checksums_before_ingest, false, true, nullptr, handles_[0]));
2163
+ ASSERT_EQ(listener->ingested_files.size(), 1);
2164
+ ASSERT_EQ(listener->ingested_files.back().cf_name, "default");
2165
+ ASSERT_EQ(listener->ingested_files.back().global_seqno, 0);
2166
+ ASSERT_EQ(listener->ingested_files.back().table_properties.column_family_id,
2167
+ 0);
2168
+ ASSERT_EQ(listener->ingested_files.back().table_properties.column_family_name,
2169
+ "default");
2170
+
2171
+ // Ingest into cf1
2172
+ ASSERT_OK(GenerateAndAddExternalFile(
2173
+ options, {1, 2}, -1, true, write_global_seqno,
2174
+ verify_checksums_before_ingest, false, true, nullptr, handles_[1]));
2175
+ ASSERT_EQ(listener->ingested_files.size(), 2);
2176
+ ASSERT_EQ(listener->ingested_files.back().cf_name, "koko");
2177
+ ASSERT_EQ(listener->ingested_files.back().global_seqno, 0);
2178
+ ASSERT_EQ(listener->ingested_files.back().table_properties.column_family_id,
2179
+ 1);
2180
+ ASSERT_EQ(listener->ingested_files.back().table_properties.column_family_name,
2181
+ "koko");
2182
+
2183
+ // Ingest into cf2
2184
+ ASSERT_OK(GenerateAndAddExternalFile(
2185
+ options, {1, 2}, -1, true, write_global_seqno,
2186
+ verify_checksums_before_ingest, false, true, nullptr, handles_[2]));
2187
+ ASSERT_EQ(listener->ingested_files.size(), 3);
2188
+ ASSERT_EQ(listener->ingested_files.back().cf_name, "toto");
2189
+ ASSERT_EQ(listener->ingested_files.back().global_seqno, 0);
2190
+ ASSERT_EQ(listener->ingested_files.back().table_properties.column_family_id,
2191
+ 2);
2192
+ ASSERT_EQ(listener->ingested_files.back().table_properties.column_family_name,
2193
+ "toto");
2194
+ }
2195
+
2196
+ TEST_F(ExternalSSTFileTest, SnapshotInconsistencyBug) {
2197
+ Options options = CurrentOptions();
2198
+ DestroyAndReopen(options);
2199
+ const int kNumKeys = 10000;
2200
+
2201
+ // Insert keys using normal path and take a snapshot
2202
+ for (int i = 0; i < kNumKeys; i++) {
2203
+ ASSERT_OK(Put(Key(i), Key(i) + "_V1"));
2204
+ }
2205
+ const Snapshot* snap = db_->GetSnapshot();
2206
+
2207
+ // Overwrite all keys using IngestExternalFile
2208
+ std::string sst_file_path = sst_files_dir_ + "file1.sst";
2209
+ SstFileWriter sst_file_writer(EnvOptions(), options);
2210
+ ASSERT_OK(sst_file_writer.Open(sst_file_path));
2211
+ for (int i = 0; i < kNumKeys; i++) {
2212
+ ASSERT_OK(sst_file_writer.Put(Key(i), Key(i) + "_V2"));
2213
+ }
2214
+ ASSERT_OK(sst_file_writer.Finish());
2215
+
2216
+ IngestExternalFileOptions ifo;
2217
+ ifo.move_files = true;
2218
+ ASSERT_OK(db_->IngestExternalFile({sst_file_path}, ifo));
2219
+
2220
+ for (int i = 0; i < kNumKeys; i++) {
2221
+ ASSERT_EQ(Get(Key(i), snap), Key(i) + "_V1");
2222
+ ASSERT_EQ(Get(Key(i)), Key(i) + "_V2");
2223
+ }
2224
+
2225
+ db_->ReleaseSnapshot(snap);
2226
+ }
2227
+
2228
+ TEST_P(ExternalSSTFileTest, IngestBehind) {
2229
+ Options options = CurrentOptions();
2230
+ options.compaction_style = kCompactionStyleUniversal;
2231
+ options.num_levels = 3;
2232
+ options.disable_auto_compactions = false;
2233
+ DestroyAndReopen(options);
2234
+ std::vector<std::pair<std::string, std::string>> file_data;
2235
+ std::map<std::string, std::string> true_data;
2236
+
2237
+ // Insert 100 -> 200 into the memtable
2238
+ for (int i = 100; i <= 200; i++) {
2239
+ ASSERT_OK(Put(Key(i), "memtable"));
2240
+ true_data[Key(i)] = "memtable";
2241
+ }
2242
+
2243
+ // Insert 100 -> 200 using IngestExternalFile
2244
+ file_data.clear();
2245
+ for (int i = 0; i <= 20; i++) {
2246
+ file_data.emplace_back(Key(i), "ingest_behind");
2247
+ }
2248
+
2249
+ bool allow_global_seqno = true;
2250
+ bool ingest_behind = true;
2251
+ bool write_global_seqno = std::get<0>(GetParam());
2252
+ bool verify_checksums_before_ingest = std::get<1>(GetParam());
2253
+
2254
+ // Can't ingest behind since allow_ingest_behind isn't set to true
2255
+ ASSERT_NOK(GenerateAndAddExternalFile(
2256
+ options, file_data, -1, allow_global_seqno, write_global_seqno,
2257
+ verify_checksums_before_ingest, ingest_behind, false /*sort_data*/,
2258
+ &true_data));
2259
+
2260
+ options.allow_ingest_behind = true;
2261
+ // check that we still can open the DB, as num_levels should be
2262
+ // sanitized to 3
2263
+ options.num_levels = 2;
2264
+ DestroyAndReopen(options);
2265
+
2266
+ options.num_levels = 3;
2267
+ DestroyAndReopen(options);
2268
+ // Insert 100 -> 200 into the memtable
2269
+ for (int i = 100; i <= 200; i++) {
2270
+ ASSERT_OK(Put(Key(i), "memtable"));
2271
+ true_data[Key(i)] = "memtable";
2272
+ }
2273
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
2274
+ // Universal picker should go at second from the bottom level
2275
+ ASSERT_EQ("0,1", FilesPerLevel());
2276
+ ASSERT_OK(GenerateAndAddExternalFile(
2277
+ options, file_data, -1, allow_global_seqno, write_global_seqno,
2278
+ verify_checksums_before_ingest, true /*ingest_behind*/,
2279
+ false /*sort_data*/, &true_data));
2280
+ ASSERT_EQ("0,1,1", FilesPerLevel());
2281
+ // this time ingest should fail as the file doesn't fit to the bottom level
2282
+ ASSERT_NOK(GenerateAndAddExternalFile(
2283
+ options, file_data, -1, allow_global_seqno, write_global_seqno,
2284
+ verify_checksums_before_ingest, true /*ingest_behind*/,
2285
+ false /*sort_data*/, &true_data));
2286
+ ASSERT_EQ("0,1,1", FilesPerLevel());
2287
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
2288
+ // bottom level should be empty
2289
+ ASSERT_EQ("0,1", FilesPerLevel());
2290
+
2291
+ size_t kcnt = 0;
2292
+ VerifyDBFromMap(true_data, &kcnt, false);
2293
+ }
2294
+
2295
+ TEST_F(ExternalSSTFileTest, SkipBloomFilter) {
2296
+ Options options = CurrentOptions();
2297
+
2298
+ BlockBasedTableOptions table_options;
2299
+ table_options.filter_policy.reset(NewBloomFilterPolicy(10));
2300
+ table_options.cache_index_and_filter_blocks = true;
2301
+ options.table_factory.reset(NewBlockBasedTableFactory(table_options));
2302
+
2303
+
2304
+ // Create external SST file and include bloom filters
2305
+ options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics();
2306
+ DestroyAndReopen(options);
2307
+ {
2308
+ std::string file_path = sst_files_dir_ + "sst_with_bloom.sst";
2309
+ SstFileWriter sst_file_writer(EnvOptions(), options);
2310
+ ASSERT_OK(sst_file_writer.Open(file_path));
2311
+ ASSERT_OK(sst_file_writer.Put("Key1", "Value1"));
2312
+ ASSERT_OK(sst_file_writer.Finish());
2313
+
2314
+ ASSERT_OK(
2315
+ db_->IngestExternalFile({file_path}, IngestExternalFileOptions()));
2316
+
2317
+ ASSERT_EQ(Get("Key1"), "Value1");
2318
+ ASSERT_GE(
2319
+ options.statistics->getTickerCount(Tickers::BLOCK_CACHE_FILTER_ADD), 1);
2320
+ }
2321
+
2322
+ // Create external SST file but skip bloom filters
2323
+ options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics();
2324
+ DestroyAndReopen(options);
2325
+ {
2326
+ std::string file_path = sst_files_dir_ + "sst_with_no_bloom.sst";
2327
+ SstFileWriter sst_file_writer(EnvOptions(), options, nullptr, true,
2328
+ Env::IOPriority::IO_TOTAL,
2329
+ true /* skip_filters */);
2330
+ ASSERT_OK(sst_file_writer.Open(file_path));
2331
+ ASSERT_OK(sst_file_writer.Put("Key1", "Value1"));
2332
+ ASSERT_OK(sst_file_writer.Finish());
2333
+
2334
+ ASSERT_OK(
2335
+ db_->IngestExternalFile({file_path}, IngestExternalFileOptions()));
2336
+
2337
+ ASSERT_EQ(Get("Key1"), "Value1");
2338
+ ASSERT_EQ(
2339
+ options.statistics->getTickerCount(Tickers::BLOCK_CACHE_FILTER_ADD), 0);
2340
+ }
2341
+ }
2342
+
2343
+ TEST_F(ExternalSSTFileTest, IngestFileWrittenWithCompressionDictionary) {
2344
+ if (!ZSTD_Supported()) {
2345
+ return;
2346
+ }
2347
+ const int kNumEntries = 1 << 10;
2348
+ const int kNumBytesPerEntry = 1 << 10;
2349
+ Options options = CurrentOptions();
2350
+ options.compression = kZSTD;
2351
+ options.compression_opts.max_dict_bytes = 1 << 14; // 16KB
2352
+ options.compression_opts.zstd_max_train_bytes = 1 << 18; // 256KB
2353
+ DestroyAndReopen(options);
2354
+
2355
+ std::atomic<int> num_compression_dicts(0);
2356
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
2357
+ "BlockBasedTableBuilder::WriteCompressionDictBlock:RawDict",
2358
+ [&](void* /* arg */) { ++num_compression_dicts; });
2359
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
2360
+
2361
+ Random rnd(301);
2362
+ std::vector<std::pair<std::string, std::string>> random_data;
2363
+ for (int i = 0; i < kNumEntries; i++) {
2364
+ std::string val = rnd.RandomString(kNumBytesPerEntry);
2365
+ random_data.emplace_back(Key(i), std::move(val));
2366
+ }
2367
+ ASSERT_OK(GenerateAndAddExternalFile(options, std::move(random_data)));
2368
+ ASSERT_EQ(1, num_compression_dicts);
2369
+ }
2370
+
2371
+ // Very slow, not worth the cost to run regularly
2372
+ TEST_F(ExternalSSTFileTest, DISABLED_HugeBlockChecksum) {
2373
+ int max_checksum = static_cast<int>(kxxHash64);
2374
+ for (int i = 0; i <= max_checksum; ++i) {
2375
+ BlockBasedTableOptions table_options;
2376
+ table_options.checksum = static_cast<ChecksumType>(i);
2377
+ Options options = CurrentOptions();
2378
+ options.table_factory.reset(NewBlockBasedTableFactory(table_options));
2379
+
2380
+ SstFileWriter sst_file_writer(EnvOptions(), options);
2381
+
2382
+ // 2^32 - 1, will lead to data block with more than 2^32 bytes
2383
+ size_t huge_size = port::kMaxUint32;
2384
+
2385
+ std::string f = sst_files_dir_ + "f.sst";
2386
+ ASSERT_OK(sst_file_writer.Open(f));
2387
+ {
2388
+ Random64 r(123);
2389
+ std::string huge(huge_size, 0);
2390
+ for (size_t j = 0; j + 7 < huge_size; j += 8) {
2391
+ EncodeFixed64(&huge[j], r.Next());
2392
+ }
2393
+ ASSERT_OK(sst_file_writer.Put("Huge", huge));
2394
+ }
2395
+
2396
+ ExternalSstFileInfo f_info;
2397
+ ASSERT_OK(sst_file_writer.Finish(&f_info));
2398
+ ASSERT_GT(f_info.file_size, uint64_t{huge_size} + 10);
2399
+
2400
+ SstFileReader sst_file_reader(options);
2401
+ ASSERT_OK(sst_file_reader.Open(f));
2402
+ ASSERT_OK(sst_file_reader.VerifyChecksum());
2403
+ }
2404
+ }
2405
+
2406
+ TEST_P(ExternalSSTFileTest, IngestFilesIntoMultipleColumnFamilies_Success) {
2407
+ std::unique_ptr<FaultInjectionTestEnv> fault_injection_env(
2408
+ new FaultInjectionTestEnv(env_));
2409
+ Options options = CurrentOptions();
2410
+ options.env = fault_injection_env.get();
2411
+ CreateAndReopenWithCF({"pikachu", "eevee"}, options);
2412
+ std::vector<ColumnFamilyHandle*> column_families;
2413
+ column_families.push_back(handles_[0]);
2414
+ column_families.push_back(handles_[1]);
2415
+ column_families.push_back(handles_[2]);
2416
+ std::vector<IngestExternalFileOptions> ifos(column_families.size());
2417
+ for (auto& ifo : ifos) {
2418
+ ifo.allow_global_seqno = true; // Always allow global_seqno
2419
+ // May or may not write global_seqno
2420
+ ifo.write_global_seqno = std::get<0>(GetParam());
2421
+ // Whether to verify checksums before ingestion
2422
+ ifo.verify_checksums_before_ingest = std::get<1>(GetParam());
2423
+ }
2424
+ std::vector<std::vector<std::pair<std::string, std::string>>> data;
2425
+ data.push_back(
2426
+ {std::make_pair("foo1", "fv1"), std::make_pair("foo2", "fv2")});
2427
+ data.push_back(
2428
+ {std::make_pair("bar1", "bv1"), std::make_pair("bar2", "bv2")});
2429
+ data.push_back(
2430
+ {std::make_pair("bar3", "bv3"), std::make_pair("bar4", "bv4")});
2431
+
2432
+ // Resize the true_data vector upon construction to avoid re-alloc
2433
+ std::vector<std::map<std::string, std::string>> true_data(
2434
+ column_families.size());
2435
+ ASSERT_OK(GenerateAndAddExternalFiles(options, column_families, ifos, data,
2436
+ -1, true, true_data));
2437
+ Close();
2438
+ ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"},
2439
+ options);
2440
+ ASSERT_EQ(3, handles_.size());
2441
+ int cf = 0;
2442
+ for (const auto& verify_map : true_data) {
2443
+ for (const auto& elem : verify_map) {
2444
+ const std::string& key = elem.first;
2445
+ const std::string& value = elem.second;
2446
+ ASSERT_EQ(value, Get(cf, key));
2447
+ }
2448
+ ++cf;
2449
+ }
2450
+ Close();
2451
+ Destroy(options, true /* delete_cf_paths */);
2452
+ }
2453
+
2454
+ TEST_P(ExternalSSTFileTest,
2455
+ IngestFilesIntoMultipleColumnFamilies_NoMixedStateWithSnapshot) {
2456
+ std::unique_ptr<FaultInjectionTestEnv> fault_injection_env(
2457
+ new FaultInjectionTestEnv(env_));
2458
+ SyncPoint::GetInstance()->DisableProcessing();
2459
+ SyncPoint::GetInstance()->ClearAllCallBacks();
2460
+ SyncPoint::GetInstance()->LoadDependency({
2461
+ {"DBImpl::IngestExternalFiles:InstallSVForFirstCF:0",
2462
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_MixedState:"
2463
+ "BeforeRead"},
2464
+ {"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_MixedState:"
2465
+ "AfterRead",
2466
+ "DBImpl::IngestExternalFiles:InstallSVForFirstCF:1"},
2467
+ });
2468
+ SyncPoint::GetInstance()->EnableProcessing();
2469
+
2470
+ Options options = CurrentOptions();
2471
+ options.env = fault_injection_env.get();
2472
+ CreateAndReopenWithCF({"pikachu", "eevee"}, options);
2473
+ const std::vector<std::map<std::string, std::string>> data_before_ingestion =
2474
+ {{{"foo1", "fv1_0"}, {"foo2", "fv2_0"}, {"foo3", "fv3_0"}},
2475
+ {{"bar1", "bv1_0"}, {"bar2", "bv2_0"}, {"bar3", "bv3_0"}},
2476
+ {{"bar4", "bv4_0"}, {"bar5", "bv5_0"}, {"bar6", "bv6_0"}}};
2477
+ for (size_t i = 0; i != handles_.size(); ++i) {
2478
+ int cf = static_cast<int>(i);
2479
+ const auto& orig_data = data_before_ingestion[i];
2480
+ for (const auto& kv : orig_data) {
2481
+ ASSERT_OK(Put(cf, kv.first, kv.second));
2482
+ }
2483
+ ASSERT_OK(Flush(cf));
2484
+ }
2485
+
2486
+ std::vector<ColumnFamilyHandle*> column_families;
2487
+ column_families.push_back(handles_[0]);
2488
+ column_families.push_back(handles_[1]);
2489
+ column_families.push_back(handles_[2]);
2490
+ std::vector<IngestExternalFileOptions> ifos(column_families.size());
2491
+ for (auto& ifo : ifos) {
2492
+ ifo.allow_global_seqno = true; // Always allow global_seqno
2493
+ // May or may not write global_seqno
2494
+ ifo.write_global_seqno = std::get<0>(GetParam());
2495
+ // Whether to verify checksums before ingestion
2496
+ ifo.verify_checksums_before_ingest = std::get<1>(GetParam());
2497
+ }
2498
+ std::vector<std::vector<std::pair<std::string, std::string>>> data;
2499
+ data.push_back(
2500
+ {std::make_pair("foo1", "fv1"), std::make_pair("foo2", "fv2")});
2501
+ data.push_back(
2502
+ {std::make_pair("bar1", "bv1"), std::make_pair("bar2", "bv2")});
2503
+ data.push_back(
2504
+ {std::make_pair("bar3", "bv3"), std::make_pair("bar4", "bv4")});
2505
+ // Resize the true_data vector upon construction to avoid re-alloc
2506
+ std::vector<std::map<std::string, std::string>> true_data(
2507
+ column_families.size());
2508
+ // Take snapshot before ingestion starts
2509
+ ReadOptions read_opts;
2510
+ read_opts.total_order_seek = true;
2511
+ read_opts.snapshot = dbfull()->GetSnapshot();
2512
+ std::vector<Iterator*> iters(handles_.size());
2513
+
2514
+ // Range scan checks first kv of each CF before ingestion starts.
2515
+ for (size_t i = 0; i != handles_.size(); ++i) {
2516
+ iters[i] = dbfull()->NewIterator(read_opts, handles_[i]);
2517
+ iters[i]->SeekToFirst();
2518
+ ASSERT_TRUE(iters[i]->Valid());
2519
+ const std::string& key = iters[i]->key().ToString();
2520
+ const std::string& value = iters[i]->value().ToString();
2521
+ const std::map<std::string, std::string>& orig_data =
2522
+ data_before_ingestion[i];
2523
+ std::map<std::string, std::string>::const_iterator it = orig_data.find(key);
2524
+ ASSERT_NE(orig_data.end(), it);
2525
+ ASSERT_EQ(it->second, value);
2526
+ iters[i]->Next();
2527
+ }
2528
+ port::Thread ingest_thread([&]() {
2529
+ ASSERT_OK(GenerateAndAddExternalFiles(options, column_families, ifos, data,
2530
+ -1, true, true_data));
2531
+ });
2532
+ TEST_SYNC_POINT(
2533
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_MixedState:"
2534
+ "BeforeRead");
2535
+ // Should see only data before ingestion
2536
+ for (size_t i = 0; i != handles_.size(); ++i) {
2537
+ const auto& orig_data = data_before_ingestion[i];
2538
+ for (; iters[i]->Valid(); iters[i]->Next()) {
2539
+ const std::string& key = iters[i]->key().ToString();
2540
+ const std::string& value = iters[i]->value().ToString();
2541
+ std::map<std::string, std::string>::const_iterator it =
2542
+ orig_data.find(key);
2543
+ ASSERT_NE(orig_data.end(), it);
2544
+ ASSERT_EQ(it->second, value);
2545
+ }
2546
+ }
2547
+ TEST_SYNC_POINT(
2548
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_MixedState:"
2549
+ "AfterRead");
2550
+ ingest_thread.join();
2551
+ for (auto* iter : iters) {
2552
+ delete iter;
2553
+ }
2554
+ iters.clear();
2555
+ dbfull()->ReleaseSnapshot(read_opts.snapshot);
2556
+
2557
+ Close();
2558
+ ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"},
2559
+ options);
2560
+ // Should see consistent state after ingestion for all column families even
2561
+ // without snapshot.
2562
+ ASSERT_EQ(3, handles_.size());
2563
+ int cf = 0;
2564
+ for (const auto& verify_map : true_data) {
2565
+ for (const auto& elem : verify_map) {
2566
+ const std::string& key = elem.first;
2567
+ const std::string& value = elem.second;
2568
+ ASSERT_EQ(value, Get(cf, key));
2569
+ }
2570
+ ++cf;
2571
+ }
2572
+ Close();
2573
+ Destroy(options, true /* delete_cf_paths */);
2574
+ }
2575
+
2576
+ TEST_P(ExternalSSTFileTest, IngestFilesIntoMultipleColumnFamilies_PrepareFail) {
2577
+ std::unique_ptr<FaultInjectionTestEnv> fault_injection_env(
2578
+ new FaultInjectionTestEnv(env_));
2579
+ Options options = CurrentOptions();
2580
+ options.env = fault_injection_env.get();
2581
+ SyncPoint::GetInstance()->DisableProcessing();
2582
+ SyncPoint::GetInstance()->ClearAllCallBacks();
2583
+ SyncPoint::GetInstance()->LoadDependency({
2584
+ {"DBImpl::IngestExternalFiles:BeforeLastJobPrepare:0",
2585
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_PrepareFail:"
2586
+ "0"},
2587
+ {"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies:PrepareFail:"
2588
+ "1",
2589
+ "DBImpl::IngestExternalFiles:BeforeLastJobPrepare:1"},
2590
+ });
2591
+ SyncPoint::GetInstance()->EnableProcessing();
2592
+ CreateAndReopenWithCF({"pikachu", "eevee"}, options);
2593
+ std::vector<ColumnFamilyHandle*> column_families;
2594
+ column_families.push_back(handles_[0]);
2595
+ column_families.push_back(handles_[1]);
2596
+ column_families.push_back(handles_[2]);
2597
+ std::vector<IngestExternalFileOptions> ifos(column_families.size());
2598
+ for (auto& ifo : ifos) {
2599
+ ifo.allow_global_seqno = true; // Always allow global_seqno
2600
+ // May or may not write global_seqno
2601
+ ifo.write_global_seqno = std::get<0>(GetParam());
2602
+ // Whether to verify block checksums before ingest
2603
+ ifo.verify_checksums_before_ingest = std::get<1>(GetParam());
2604
+ }
2605
+ std::vector<std::vector<std::pair<std::string, std::string>>> data;
2606
+ data.push_back(
2607
+ {std::make_pair("foo1", "fv1"), std::make_pair("foo2", "fv2")});
2608
+ data.push_back(
2609
+ {std::make_pair("bar1", "bv1"), std::make_pair("bar2", "bv2")});
2610
+ data.push_back(
2611
+ {std::make_pair("bar3", "bv3"), std::make_pair("bar4", "bv4")});
2612
+
2613
+ // Resize the true_data vector upon construction to avoid re-alloc
2614
+ std::vector<std::map<std::string, std::string>> true_data(
2615
+ column_families.size());
2616
+ port::Thread ingest_thread([&]() {
2617
+ ASSERT_NOK(GenerateAndAddExternalFiles(options, column_families, ifos, data,
2618
+ -1, true, true_data));
2619
+ });
2620
+ TEST_SYNC_POINT(
2621
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_PrepareFail:"
2622
+ "0");
2623
+ fault_injection_env->SetFilesystemActive(false);
2624
+ TEST_SYNC_POINT(
2625
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies:PrepareFail:"
2626
+ "1");
2627
+ ingest_thread.join();
2628
+
2629
+ fault_injection_env->SetFilesystemActive(true);
2630
+ Close();
2631
+ ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"},
2632
+ options);
2633
+ ASSERT_EQ(3, handles_.size());
2634
+ int cf = 0;
2635
+ for (const auto& verify_map : true_data) {
2636
+ for (const auto& elem : verify_map) {
2637
+ const std::string& key = elem.first;
2638
+ ASSERT_EQ("NOT_FOUND", Get(cf, key));
2639
+ }
2640
+ ++cf;
2641
+ }
2642
+ Close();
2643
+ Destroy(options, true /* delete_cf_paths */);
2644
+ }
2645
+
2646
+ TEST_P(ExternalSSTFileTest, IngestFilesIntoMultipleColumnFamilies_CommitFail) {
2647
+ std::unique_ptr<FaultInjectionTestEnv> fault_injection_env(
2648
+ new FaultInjectionTestEnv(env_));
2649
+ Options options = CurrentOptions();
2650
+ options.env = fault_injection_env.get();
2651
+ SyncPoint::GetInstance()->DisableProcessing();
2652
+ SyncPoint::GetInstance()->ClearAllCallBacks();
2653
+ SyncPoint::GetInstance()->LoadDependency({
2654
+ {"DBImpl::IngestExternalFiles:BeforeJobsRun:0",
2655
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_CommitFail:"
2656
+ "0"},
2657
+ {"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_CommitFail:"
2658
+ "1",
2659
+ "DBImpl::IngestExternalFiles:BeforeJobsRun:1"},
2660
+ });
2661
+ SyncPoint::GetInstance()->EnableProcessing();
2662
+ CreateAndReopenWithCF({"pikachu", "eevee"}, options);
2663
+ std::vector<ColumnFamilyHandle*> column_families;
2664
+ column_families.push_back(handles_[0]);
2665
+ column_families.push_back(handles_[1]);
2666
+ column_families.push_back(handles_[2]);
2667
+ std::vector<IngestExternalFileOptions> ifos(column_families.size());
2668
+ for (auto& ifo : ifos) {
2669
+ ifo.allow_global_seqno = true; // Always allow global_seqno
2670
+ // May or may not write global_seqno
2671
+ ifo.write_global_seqno = std::get<0>(GetParam());
2672
+ // Whether to verify block checksums before ingestion
2673
+ ifo.verify_checksums_before_ingest = std::get<1>(GetParam());
2674
+ }
2675
+ std::vector<std::vector<std::pair<std::string, std::string>>> data;
2676
+ data.push_back(
2677
+ {std::make_pair("foo1", "fv1"), std::make_pair("foo2", "fv2")});
2678
+ data.push_back(
2679
+ {std::make_pair("bar1", "bv1"), std::make_pair("bar2", "bv2")});
2680
+ data.push_back(
2681
+ {std::make_pair("bar3", "bv3"), std::make_pair("bar4", "bv4")});
2682
+ // Resize the true_data vector upon construction to avoid re-alloc
2683
+ std::vector<std::map<std::string, std::string>> true_data(
2684
+ column_families.size());
2685
+ port::Thread ingest_thread([&]() {
2686
+ ASSERT_NOK(GenerateAndAddExternalFiles(options, column_families, ifos, data,
2687
+ -1, true, true_data));
2688
+ });
2689
+ TEST_SYNC_POINT(
2690
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_CommitFail:"
2691
+ "0");
2692
+ fault_injection_env->SetFilesystemActive(false);
2693
+ TEST_SYNC_POINT(
2694
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_CommitFail:"
2695
+ "1");
2696
+ ingest_thread.join();
2697
+
2698
+ fault_injection_env->SetFilesystemActive(true);
2699
+ Close();
2700
+ ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"},
2701
+ options);
2702
+ ASSERT_EQ(3, handles_.size());
2703
+ int cf = 0;
2704
+ for (const auto& verify_map : true_data) {
2705
+ for (const auto& elem : verify_map) {
2706
+ const std::string& key = elem.first;
2707
+ ASSERT_EQ("NOT_FOUND", Get(cf, key));
2708
+ }
2709
+ ++cf;
2710
+ }
2711
+ Close();
2712
+ Destroy(options, true /* delete_cf_paths */);
2713
+ }
2714
+
2715
+ TEST_P(ExternalSSTFileTest,
2716
+ IngestFilesIntoMultipleColumnFamilies_PartialManifestWriteFail) {
2717
+ std::unique_ptr<FaultInjectionTestEnv> fault_injection_env(
2718
+ new FaultInjectionTestEnv(env_));
2719
+ Options options = CurrentOptions();
2720
+ options.env = fault_injection_env.get();
2721
+
2722
+ CreateAndReopenWithCF({"pikachu", "eevee"}, options);
2723
+
2724
+ SyncPoint::GetInstance()->ClearTrace();
2725
+ SyncPoint::GetInstance()->DisableProcessing();
2726
+ SyncPoint::GetInstance()->ClearAllCallBacks();
2727
+ SyncPoint::GetInstance()->LoadDependency({
2728
+ {"VersionSet::ProcessManifestWrites:BeforeWriteLastVersionEdit:0",
2729
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_"
2730
+ "PartialManifestWriteFail:0"},
2731
+ {"ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_"
2732
+ "PartialManifestWriteFail:1",
2733
+ "VersionSet::ProcessManifestWrites:BeforeWriteLastVersionEdit:1"},
2734
+ });
2735
+ SyncPoint::GetInstance()->EnableProcessing();
2736
+
2737
+ std::vector<ColumnFamilyHandle*> column_families;
2738
+ column_families.push_back(handles_[0]);
2739
+ column_families.push_back(handles_[1]);
2740
+ column_families.push_back(handles_[2]);
2741
+ std::vector<IngestExternalFileOptions> ifos(column_families.size());
2742
+ for (auto& ifo : ifos) {
2743
+ ifo.allow_global_seqno = true; // Always allow global_seqno
2744
+ // May or may not write global_seqno
2745
+ ifo.write_global_seqno = std::get<0>(GetParam());
2746
+ // Whether to verify block checksums before ingestion
2747
+ ifo.verify_checksums_before_ingest = std::get<1>(GetParam());
2748
+ }
2749
+ std::vector<std::vector<std::pair<std::string, std::string>>> data;
2750
+ data.push_back(
2751
+ {std::make_pair("foo1", "fv1"), std::make_pair("foo2", "fv2")});
2752
+ data.push_back(
2753
+ {std::make_pair("bar1", "bv1"), std::make_pair("bar2", "bv2")});
2754
+ data.push_back(
2755
+ {std::make_pair("bar3", "bv3"), std::make_pair("bar4", "bv4")});
2756
+ // Resize the true_data vector upon construction to avoid re-alloc
2757
+ std::vector<std::map<std::string, std::string>> true_data(
2758
+ column_families.size());
2759
+ port::Thread ingest_thread([&]() {
2760
+ ASSERT_NOK(GenerateAndAddExternalFiles(options, column_families, ifos, data,
2761
+ -1, true, true_data));
2762
+ });
2763
+ TEST_SYNC_POINT(
2764
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_"
2765
+ "PartialManifestWriteFail:0");
2766
+ fault_injection_env->SetFilesystemActive(false);
2767
+ TEST_SYNC_POINT(
2768
+ "ExternalSSTFileTest::IngestFilesIntoMultipleColumnFamilies_"
2769
+ "PartialManifestWriteFail:1");
2770
+ ingest_thread.join();
2771
+
2772
+ ASSERT_OK(fault_injection_env->DropUnsyncedFileData());
2773
+ fault_injection_env->SetFilesystemActive(true);
2774
+ Close();
2775
+ ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"},
2776
+ options);
2777
+ ASSERT_EQ(3, handles_.size());
2778
+ int cf = 0;
2779
+ for (const auto& verify_map : true_data) {
2780
+ for (const auto& elem : verify_map) {
2781
+ const std::string& key = elem.first;
2782
+ ASSERT_EQ("NOT_FOUND", Get(cf, key));
2783
+ }
2784
+ ++cf;
2785
+ }
2786
+ Close();
2787
+ Destroy(options, true /* delete_cf_paths */);
2788
+ }
2789
+
2790
+ TEST_P(ExternalSSTFileTest, IngestFilesTriggerFlushingWithTwoWriteQueue) {
2791
+ Options options = CurrentOptions();
2792
+ // Use large buffer to avoid memtable flush
2793
+ options.write_buffer_size = 1024 * 1024;
2794
+ options.two_write_queues = true;
2795
+ DestroyAndReopen(options);
2796
+
2797
+ ASSERT_OK(dbfull()->Put(WriteOptions(), "1000", "v1"));
2798
+ ASSERT_OK(dbfull()->Put(WriteOptions(), "1001", "v1"));
2799
+ ASSERT_OK(dbfull()->Put(WriteOptions(), "9999", "v1"));
2800
+
2801
+ // Put one key which is overlap with keys in memtable.
2802
+ // It will trigger flushing memtable and require this thread is
2803
+ // currently at the front of the 2nd writer queue. We must make
2804
+ // sure that it won't enter the 2nd writer queue for the second time.
2805
+ std::vector<std::pair<std::string, std::string>> data;
2806
+ data.push_back(std::make_pair("1001", "v2"));
2807
+ ASSERT_OK(GenerateAndAddExternalFile(options, data, -1, true));
2808
+ }
2809
+
2810
+ TEST_P(ExternalSSTFileTest, DeltaEncodingWhileGlobalSeqnoPresent) {
2811
+ Options options = CurrentOptions();
2812
+ DestroyAndReopen(options);
2813
+ constexpr size_t kValueSize = 8;
2814
+ Random rnd(301);
2815
+ std::string value = rnd.RandomString(kValueSize);
2816
+
2817
+ // Write some key to make global seqno larger than zero
2818
+ for (int i = 0; i < 10; i++) {
2819
+ ASSERT_OK(Put("ab" + Key(i), value));
2820
+ }
2821
+ // Get a Snapshot to make RocksDB assign global seqno to ingested sst files.
2822
+ auto snap = dbfull()->GetSnapshot();
2823
+
2824
+ std::string fname = sst_files_dir_ + "test_file";
2825
+ ROCKSDB_NAMESPACE::SstFileWriter writer(EnvOptions(), options);
2826
+ ASSERT_OK(writer.Open(fname));
2827
+ std::string key1 = "ab";
2828
+ std::string key2 = "ab";
2829
+
2830
+ // Make the prefix of key2 is same with key1 add zero seqno. The tail of every
2831
+ // key is composed as (seqno << 8 | value_type), and here `1` represents
2832
+ // ValueType::kTypeValue
2833
+
2834
+ PutFixed64(&key2, PackSequenceAndType(0, kTypeValue));
2835
+ key2 += "cdefghijkl";
2836
+
2837
+ ASSERT_OK(writer.Put(key1, value));
2838
+ ASSERT_OK(writer.Put(key2, value));
2839
+
2840
+ ExternalSstFileInfo info;
2841
+ ASSERT_OK(writer.Finish(&info));
2842
+
2843
+ ASSERT_OK(dbfull()->IngestExternalFile({info.file_path},
2844
+ IngestExternalFileOptions()));
2845
+ dbfull()->ReleaseSnapshot(snap);
2846
+ ASSERT_EQ(value, Get(key1));
2847
+ // You will get error here
2848
+ ASSERT_EQ(value, Get(key2));
2849
+ }
2850
+
2851
+ TEST_P(ExternalSSTFileTest,
2852
+ DeltaEncodingWhileGlobalSeqnoPresentIteratorSwitch) {
2853
+ // Regression test for bug where global seqno corrupted the shared bytes
2854
+ // buffer when switching from reverse iteration to forward iteration.
2855
+ constexpr size_t kValueSize = 8;
2856
+ Options options = CurrentOptions();
2857
+
2858
+ Random rnd(301);
2859
+ std::string value = rnd.RandomString(kValueSize);
2860
+
2861
+ std::string key0 = "aa";
2862
+ std::string key1 = "ab";
2863
+ // Make the prefix of key2 is same with key1 add zero seqno. The tail of every
2864
+ // key is composed as (seqno << 8 | value_type), and here `1` represents
2865
+ // ValueType::kTypeValue
2866
+ std::string key2 = "ab";
2867
+ PutFixed64(&key2, PackSequenceAndType(0, kTypeValue));
2868
+ key2 += "cdefghijkl";
2869
+ std::string key3 = key2 + "_";
2870
+
2871
+ // Write some key to make global seqno larger than zero
2872
+ ASSERT_OK(Put(key0, value));
2873
+
2874
+ std::string fname = sst_files_dir_ + "test_file";
2875
+ ROCKSDB_NAMESPACE::SstFileWriter writer(EnvOptions(), options);
2876
+ ASSERT_OK(writer.Open(fname));
2877
+
2878
+ // key0 is a dummy to ensure the turnaround point (key1) comes from Prev
2879
+ // cache rather than block (restart keys are pinned in block).
2880
+ ASSERT_OK(writer.Put(key0, value));
2881
+ ASSERT_OK(writer.Put(key1, value));
2882
+ ASSERT_OK(writer.Put(key2, value));
2883
+ ASSERT_OK(writer.Put(key3, value));
2884
+
2885
+ ExternalSstFileInfo info;
2886
+ ASSERT_OK(writer.Finish(&info));
2887
+
2888
+ ASSERT_OK(dbfull()->IngestExternalFile({info.file_path},
2889
+ IngestExternalFileOptions()));
2890
+ ReadOptions read_opts;
2891
+ // Prevents Seek() when switching directions, which circumvents the bug.
2892
+ read_opts.total_order_seek = true;
2893
+ Iterator* iter = db_->NewIterator(read_opts);
2894
+ // Scan backwards to key2. File iterator will then be positioned at key1.
2895
+ iter->Seek(key3);
2896
+ ASSERT_EQ(key3, iter->key());
2897
+ iter->Prev();
2898
+ ASSERT_EQ(key2, iter->key());
2899
+ // Scan forwards and make sure key3 is present. Previously key3 would be
2900
+ // corrupted by the global seqno from key1.
2901
+ iter->Next();
2902
+ ASSERT_EQ(key3, iter->key());
2903
+ delete iter;
2904
+ }
2905
+
2906
+ INSTANTIATE_TEST_CASE_P(ExternalSSTFileTest, ExternalSSTFileTest,
2907
+ testing::Values(std::make_tuple(false, false),
2908
+ std::make_tuple(false, true),
2909
+ std::make_tuple(true, false),
2910
+ std::make_tuple(true, true)));
2911
+
2912
+ INSTANTIATE_TEST_CASE_P(ExternSSTFileLinkFailFallbackTest,
2913
+ ExternSSTFileLinkFailFallbackTest,
2914
+ testing::Values(std::make_tuple(true, false),
2915
+ std::make_tuple(true, true),
2916
+ std::make_tuple(false, false)));
2917
+
2918
+ } // namespace ROCKSDB_NAMESPACE
2919
+
2920
+ int main(int argc, char** argv) {
2921
+ ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
2922
+ ::testing::InitGoogleTest(&argc, argv);
2923
+ return RUN_ALL_TESTS();
2924
+ }
2925
+
2926
+ #else
2927
+ #include <stdio.h>
2928
+
2929
+ int main(int /*argc*/, char** /*argv*/) {
2930
+ fprintf(stderr,
2931
+ "SKIPPED as External SST File Writer and Ingestion are not supported "
2932
+ "in ROCKSDB_LITE\n");
2933
+ return 0;
2934
+ }
2935
+
2936
+ #endif // !ROCKSDB_LITE