@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,3820 @@
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
+ // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7
+ // Use of this source code is governed by a BSD-style license that can be
8
+ // found in the LICENSE file. See the AUTHORS file for names of contributors.
9
+
10
+ #include <cstring>
11
+ #include <regex>
12
+
13
+ #include "db/db_test_util.h"
14
+ #include "port/stack_trace.h"
15
+ #include "rocksdb/flush_block_policy.h"
16
+ #include "rocksdb/merge_operator.h"
17
+ #include "rocksdb/perf_context.h"
18
+ #include "rocksdb/utilities/debug.h"
19
+ #include "table/block_based/block_based_table_reader.h"
20
+ #include "table/block_based/block_builder.h"
21
+ #if !defined(ROCKSDB_LITE)
22
+ #include "test_util/sync_point.h"
23
+ #endif
24
+ #include "util/file_checksum_helper.h"
25
+ #include "util/random.h"
26
+ #include "utilities/fault_injection_env.h"
27
+ #include "utilities/merge_operators.h"
28
+ #include "utilities/merge_operators/string_append/stringappend.h"
29
+
30
+ namespace ROCKSDB_NAMESPACE {
31
+
32
+ class DBBasicTest : public DBTestBase {
33
+ public:
34
+ DBBasicTest() : DBTestBase("/db_basic_test", /*env_do_fsync=*/false) {}
35
+ };
36
+
37
+ TEST_F(DBBasicTest, OpenWhenOpen) {
38
+ Options options = CurrentOptions();
39
+ options.env = env_;
40
+ DB* db2 = nullptr;
41
+ Status s = DB::Open(options, dbname_, &db2);
42
+ ASSERT_NOK(s) << [db2]() {
43
+ delete db2;
44
+ return "db2 open: ok";
45
+ }();
46
+ ASSERT_EQ(Status::Code::kIOError, s.code());
47
+ ASSERT_EQ(Status::SubCode::kNone, s.subcode());
48
+ ASSERT_TRUE(strstr(s.getState(), "lock ") != nullptr);
49
+
50
+ delete db2;
51
+ }
52
+
53
+ TEST_F(DBBasicTest, UniqueSession) {
54
+ Options options = CurrentOptions();
55
+ std::string sid1, sid2, sid3, sid4;
56
+
57
+ ASSERT_OK(db_->GetDbSessionId(sid1));
58
+ Reopen(options);
59
+ ASSERT_OK(db_->GetDbSessionId(sid2));
60
+ ASSERT_OK(Put("foo", "v1"));
61
+ ASSERT_OK(db_->GetDbSessionId(sid4));
62
+ Reopen(options);
63
+ ASSERT_OK(db_->GetDbSessionId(sid3));
64
+
65
+ ASSERT_NE(sid1, sid2);
66
+ ASSERT_NE(sid1, sid3);
67
+ ASSERT_NE(sid2, sid3);
68
+
69
+ ASSERT_EQ(sid2, sid4);
70
+
71
+ // Expected compact format for session ids (see notes in implementation)
72
+ std::regex expected("[0-9A-Z]{20}");
73
+ const std::string match("match");
74
+ EXPECT_EQ(match, std::regex_replace(sid1, expected, match));
75
+ EXPECT_EQ(match, std::regex_replace(sid2, expected, match));
76
+ EXPECT_EQ(match, std::regex_replace(sid3, expected, match));
77
+
78
+ #ifndef ROCKSDB_LITE
79
+ Close();
80
+ ASSERT_OK(ReadOnlyReopen(options));
81
+ ASSERT_OK(db_->GetDbSessionId(sid1));
82
+ // Test uniqueness between readonly open (sid1) and regular open (sid3)
83
+ ASSERT_NE(sid1, sid3);
84
+ Close();
85
+ ASSERT_OK(ReadOnlyReopen(options));
86
+ ASSERT_OK(db_->GetDbSessionId(sid2));
87
+ ASSERT_EQ("v1", Get("foo"));
88
+ ASSERT_OK(db_->GetDbSessionId(sid3));
89
+
90
+ ASSERT_NE(sid1, sid2);
91
+
92
+ ASSERT_EQ(sid2, sid3);
93
+ #endif // ROCKSDB_LITE
94
+
95
+ CreateAndReopenWithCF({"goku"}, options);
96
+ ASSERT_OK(db_->GetDbSessionId(sid1));
97
+ ASSERT_OK(Put("bar", "e1"));
98
+ ASSERT_OK(db_->GetDbSessionId(sid2));
99
+ ASSERT_EQ("e1", Get("bar"));
100
+ ASSERT_OK(db_->GetDbSessionId(sid3));
101
+ ReopenWithColumnFamilies({"default", "goku"}, options);
102
+ ASSERT_OK(db_->GetDbSessionId(sid4));
103
+
104
+ ASSERT_EQ(sid1, sid2);
105
+ ASSERT_EQ(sid2, sid3);
106
+
107
+ ASSERT_NE(sid1, sid4);
108
+ }
109
+
110
+ #ifndef ROCKSDB_LITE
111
+ TEST_F(DBBasicTest, ReadOnlyDB) {
112
+ ASSERT_OK(Put("foo", "v1"));
113
+ ASSERT_OK(Put("bar", "v2"));
114
+ ASSERT_OK(Put("foo", "v3"));
115
+ Close();
116
+
117
+ auto verify_one_iter = [&](Iterator* iter) {
118
+ int count = 0;
119
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
120
+ ASSERT_OK(iter->status());
121
+ ++count;
122
+ }
123
+ // Always expect two keys: "foo" and "bar"
124
+ ASSERT_EQ(count, 2);
125
+ };
126
+
127
+ auto verify_all_iters = [&]() {
128
+ Iterator* iter = db_->NewIterator(ReadOptions());
129
+ verify_one_iter(iter);
130
+ delete iter;
131
+
132
+ std::vector<Iterator*> iters;
133
+ ASSERT_OK(db_->NewIterators(ReadOptions(),
134
+ {dbfull()->DefaultColumnFamily()}, &iters));
135
+ ASSERT_EQ(static_cast<uint64_t>(1), iters.size());
136
+ verify_one_iter(iters[0]);
137
+ delete iters[0];
138
+ };
139
+
140
+ auto options = CurrentOptions();
141
+ assert(options.env == env_);
142
+ ASSERT_OK(ReadOnlyReopen(options));
143
+ ASSERT_EQ("v3", Get("foo"));
144
+ ASSERT_EQ("v2", Get("bar"));
145
+ verify_all_iters();
146
+ Close();
147
+
148
+ // Reopen and flush memtable.
149
+ Reopen(options);
150
+ ASSERT_OK(Flush());
151
+ Close();
152
+ // Now check keys in read only mode.
153
+ ASSERT_OK(ReadOnlyReopen(options));
154
+ ASSERT_EQ("v3", Get("foo"));
155
+ ASSERT_EQ("v2", Get("bar"));
156
+ verify_all_iters();
157
+ ASSERT_TRUE(db_->SyncWAL().IsNotSupported());
158
+ }
159
+
160
+ TEST_F(DBBasicTest, ReadOnlyDBWithWriteDBIdToManifestSet) {
161
+ ASSERT_OK(Put("foo", "v1"));
162
+ ASSERT_OK(Put("bar", "v2"));
163
+ ASSERT_OK(Put("foo", "v3"));
164
+ Close();
165
+
166
+ auto options = CurrentOptions();
167
+ options.write_dbid_to_manifest = true;
168
+ assert(options.env == env_);
169
+ ASSERT_OK(ReadOnlyReopen(options));
170
+ std::string db_id1;
171
+ ASSERT_OK(db_->GetDbIdentity(db_id1));
172
+ ASSERT_EQ("v3", Get("foo"));
173
+ ASSERT_EQ("v2", Get("bar"));
174
+ Iterator* iter = db_->NewIterator(ReadOptions());
175
+ int count = 0;
176
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
177
+ ASSERT_OK(iter->status());
178
+ ++count;
179
+ }
180
+ ASSERT_EQ(count, 2);
181
+ delete iter;
182
+ Close();
183
+
184
+ // Reopen and flush memtable.
185
+ Reopen(options);
186
+ ASSERT_OK(Flush());
187
+ Close();
188
+ // Now check keys in read only mode.
189
+ ASSERT_OK(ReadOnlyReopen(options));
190
+ ASSERT_EQ("v3", Get("foo"));
191
+ ASSERT_EQ("v2", Get("bar"));
192
+ ASSERT_TRUE(db_->SyncWAL().IsNotSupported());
193
+ std::string db_id2;
194
+ ASSERT_OK(db_->GetDbIdentity(db_id2));
195
+ ASSERT_EQ(db_id1, db_id2);
196
+ }
197
+
198
+ TEST_F(DBBasicTest, CompactedDB) {
199
+ const uint64_t kFileSize = 1 << 20;
200
+ Options options = CurrentOptions();
201
+ options.disable_auto_compactions = true;
202
+ options.write_buffer_size = kFileSize;
203
+ options.target_file_size_base = kFileSize;
204
+ options.max_bytes_for_level_base = 1 << 30;
205
+ options.compression = kNoCompression;
206
+ Reopen(options);
207
+ // 1 L0 file, use CompactedDB if max_open_files = -1
208
+ ASSERT_OK(Put("aaa", DummyString(kFileSize / 2, '1')));
209
+ ASSERT_OK(Flush());
210
+ Close();
211
+ ASSERT_OK(ReadOnlyReopen(options));
212
+ Status s = Put("new", "value");
213
+ ASSERT_EQ(s.ToString(),
214
+ "Not implemented: Not supported operation in read only mode.");
215
+ ASSERT_EQ(DummyString(kFileSize / 2, '1'), Get("aaa"));
216
+ Close();
217
+ options.max_open_files = -1;
218
+ ASSERT_OK(ReadOnlyReopen(options));
219
+ s = Put("new", "value");
220
+ ASSERT_EQ(s.ToString(),
221
+ "Not implemented: Not supported in compacted db mode.");
222
+ ASSERT_EQ(DummyString(kFileSize / 2, '1'), Get("aaa"));
223
+ Close();
224
+ Reopen(options);
225
+ // Add more L0 files
226
+ ASSERT_OK(Put("bbb", DummyString(kFileSize / 2, '2')));
227
+ ASSERT_OK(Flush());
228
+ ASSERT_OK(Put("aaa", DummyString(kFileSize / 2, 'a')));
229
+ ASSERT_OK(Flush());
230
+ ASSERT_OK(Put("bbb", DummyString(kFileSize / 2, 'b')));
231
+ ASSERT_OK(Put("eee", DummyString(kFileSize / 2, 'e')));
232
+ ASSERT_OK(Flush());
233
+ Close();
234
+
235
+ ASSERT_OK(ReadOnlyReopen(options));
236
+ // Fallback to read-only DB
237
+ s = Put("new", "value");
238
+ ASSERT_EQ(s.ToString(),
239
+ "Not implemented: Not supported operation in read only mode.");
240
+ Close();
241
+
242
+ // Full compaction
243
+ Reopen(options);
244
+ // Add more keys
245
+ ASSERT_OK(Put("fff", DummyString(kFileSize / 2, 'f')));
246
+ ASSERT_OK(Put("hhh", DummyString(kFileSize / 2, 'h')));
247
+ ASSERT_OK(Put("iii", DummyString(kFileSize / 2, 'i')));
248
+ ASSERT_OK(Put("jjj", DummyString(kFileSize / 2, 'j')));
249
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
250
+ ASSERT_EQ(3, NumTableFilesAtLevel(1));
251
+ Close();
252
+
253
+ // CompactedDB
254
+ ASSERT_OK(ReadOnlyReopen(options));
255
+ s = Put("new", "value");
256
+ ASSERT_EQ(s.ToString(),
257
+ "Not implemented: Not supported in compacted db mode.");
258
+ ASSERT_EQ("NOT_FOUND", Get("abc"));
259
+ ASSERT_EQ(DummyString(kFileSize / 2, 'a'), Get("aaa"));
260
+ ASSERT_EQ(DummyString(kFileSize / 2, 'b'), Get("bbb"));
261
+ ASSERT_EQ("NOT_FOUND", Get("ccc"));
262
+ ASSERT_EQ(DummyString(kFileSize / 2, 'e'), Get("eee"));
263
+ ASSERT_EQ(DummyString(kFileSize / 2, 'f'), Get("fff"));
264
+ ASSERT_EQ("NOT_FOUND", Get("ggg"));
265
+ ASSERT_EQ(DummyString(kFileSize / 2, 'h'), Get("hhh"));
266
+ ASSERT_EQ(DummyString(kFileSize / 2, 'i'), Get("iii"));
267
+ ASSERT_EQ(DummyString(kFileSize / 2, 'j'), Get("jjj"));
268
+ ASSERT_EQ("NOT_FOUND", Get("kkk"));
269
+
270
+ // MultiGet
271
+ std::vector<std::string> values;
272
+ std::vector<Status> status_list = dbfull()->MultiGet(
273
+ ReadOptions(),
274
+ std::vector<Slice>({Slice("aaa"), Slice("ccc"), Slice("eee"),
275
+ Slice("ggg"), Slice("iii"), Slice("kkk")}),
276
+ &values);
277
+ ASSERT_EQ(status_list.size(), static_cast<uint64_t>(6));
278
+ ASSERT_EQ(values.size(), static_cast<uint64_t>(6));
279
+ ASSERT_OK(status_list[0]);
280
+ ASSERT_EQ(DummyString(kFileSize / 2, 'a'), values[0]);
281
+ ASSERT_TRUE(status_list[1].IsNotFound());
282
+ ASSERT_OK(status_list[2]);
283
+ ASSERT_EQ(DummyString(kFileSize / 2, 'e'), values[2]);
284
+ ASSERT_TRUE(status_list[3].IsNotFound());
285
+ ASSERT_OK(status_list[4]);
286
+ ASSERT_EQ(DummyString(kFileSize / 2, 'i'), values[4]);
287
+ ASSERT_TRUE(status_list[5].IsNotFound());
288
+
289
+ Reopen(options);
290
+ // Add a key
291
+ ASSERT_OK(Put("fff", DummyString(kFileSize / 2, 'f')));
292
+ Close();
293
+ ASSERT_OK(ReadOnlyReopen(options));
294
+ s = Put("new", "value");
295
+ ASSERT_EQ(s.ToString(),
296
+ "Not implemented: Not supported operation in read only mode.");
297
+ }
298
+
299
+ TEST_F(DBBasicTest, LevelLimitReopen) {
300
+ Options options = CurrentOptions();
301
+ CreateAndReopenWithCF({"pikachu"}, options);
302
+
303
+ const std::string value(1024 * 1024, ' ');
304
+ int i = 0;
305
+ while (NumTableFilesAtLevel(2, 1) == 0) {
306
+ ASSERT_OK(Put(1, Key(i++), value));
307
+ ASSERT_OK(dbfull()->TEST_WaitForFlushMemTable());
308
+ ASSERT_OK(dbfull()->TEST_WaitForCompact());
309
+ }
310
+
311
+ options.num_levels = 1;
312
+ options.max_bytes_for_level_multiplier_additional.resize(1, 1);
313
+ Status s = TryReopenWithColumnFamilies({"default", "pikachu"}, options);
314
+ ASSERT_EQ(s.IsInvalidArgument(), true);
315
+ ASSERT_EQ(s.ToString(),
316
+ "Invalid argument: db has more levels than options.num_levels");
317
+
318
+ options.num_levels = 10;
319
+ options.max_bytes_for_level_multiplier_additional.resize(10, 1);
320
+ ASSERT_OK(TryReopenWithColumnFamilies({"default", "pikachu"}, options));
321
+ }
322
+ #endif // ROCKSDB_LITE
323
+
324
+ TEST_F(DBBasicTest, PutDeleteGet) {
325
+ do {
326
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
327
+ ASSERT_OK(Put(1, "foo", "v1"));
328
+ ASSERT_EQ("v1", Get(1, "foo"));
329
+ ASSERT_OK(Put(1, "foo", "v2"));
330
+ ASSERT_EQ("v2", Get(1, "foo"));
331
+ ASSERT_OK(Delete(1, "foo"));
332
+ ASSERT_EQ("NOT_FOUND", Get(1, "foo"));
333
+ } while (ChangeOptions());
334
+ }
335
+
336
+ TEST_F(DBBasicTest, PutSingleDeleteGet) {
337
+ do {
338
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
339
+ ASSERT_OK(Put(1, "foo", "v1"));
340
+ ASSERT_EQ("v1", Get(1, "foo"));
341
+ ASSERT_OK(Put(1, "foo2", "v2"));
342
+ ASSERT_EQ("v2", Get(1, "foo2"));
343
+ ASSERT_OK(SingleDelete(1, "foo"));
344
+ ASSERT_EQ("NOT_FOUND", Get(1, "foo"));
345
+ // Ski FIFO and universal compaction because they do not apply to the test
346
+ // case. Skip MergePut because single delete does not get removed when it
347
+ // encounters a merge.
348
+ } while (ChangeOptions(kSkipFIFOCompaction | kSkipUniversalCompaction |
349
+ kSkipMergePut));
350
+ }
351
+
352
+ TEST_F(DBBasicTest, EmptyFlush) {
353
+ // It is possible to produce empty flushes when using single deletes. Tests
354
+ // whether empty flushes cause issues.
355
+ do {
356
+ Random rnd(301);
357
+
358
+ Options options = CurrentOptions();
359
+ options.disable_auto_compactions = true;
360
+ CreateAndReopenWithCF({"pikachu"}, options);
361
+
362
+ ASSERT_OK(Put(1, "a", Slice()));
363
+ ASSERT_OK(SingleDelete(1, "a"));
364
+ ASSERT_OK(Flush(1));
365
+
366
+ ASSERT_EQ("[ ]", AllEntriesFor("a", 1));
367
+ // Skip FIFO and universal compaction as they do not apply to the test
368
+ // case. Skip MergePut because merges cannot be combined with single
369
+ // deletions.
370
+ } while (ChangeOptions(kSkipFIFOCompaction | kSkipUniversalCompaction |
371
+ kSkipMergePut));
372
+ }
373
+
374
+ TEST_F(DBBasicTest, GetFromVersions) {
375
+ do {
376
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
377
+ ASSERT_OK(Put(1, "foo", "v1"));
378
+ ASSERT_OK(Flush(1));
379
+ ASSERT_EQ("v1", Get(1, "foo"));
380
+ ASSERT_EQ("NOT_FOUND", Get(0, "foo"));
381
+ } while (ChangeOptions());
382
+ }
383
+
384
+ #ifndef ROCKSDB_LITE
385
+ TEST_F(DBBasicTest, GetSnapshot) {
386
+ anon::OptionsOverride options_override;
387
+ options_override.skip_policy = kSkipNoSnapshot;
388
+ do {
389
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions(options_override));
390
+ // Try with both a short key and a long key
391
+ for (int i = 0; i < 2; i++) {
392
+ std::string key = (i == 0) ? std::string("foo") : std::string(200, 'x');
393
+ ASSERT_OK(Put(1, key, "v1"));
394
+ const Snapshot* s1 = db_->GetSnapshot();
395
+ ASSERT_OK(Put(1, key, "v2"));
396
+ ASSERT_EQ("v2", Get(1, key));
397
+ ASSERT_EQ("v1", Get(1, key, s1));
398
+ ASSERT_OK(Flush(1));
399
+ ASSERT_EQ("v2", Get(1, key));
400
+ ASSERT_EQ("v1", Get(1, key, s1));
401
+ db_->ReleaseSnapshot(s1);
402
+ }
403
+ } while (ChangeOptions());
404
+ }
405
+ #endif // ROCKSDB_LITE
406
+
407
+ TEST_F(DBBasicTest, CheckLock) {
408
+ do {
409
+ DB* localdb = nullptr;
410
+ Options options = CurrentOptions();
411
+ ASSERT_OK(TryReopen(options));
412
+
413
+ // second open should fail
414
+ Status s = DB::Open(options, dbname_, &localdb);
415
+ ASSERT_NOK(s) << [localdb]() {
416
+ delete localdb;
417
+ return "localdb open: ok";
418
+ }();
419
+ #ifdef OS_LINUX
420
+ ASSERT_TRUE(s.ToString().find("lock ") != std::string::npos);
421
+ #endif // OS_LINUX
422
+ } while (ChangeCompactOptions());
423
+ }
424
+
425
+ TEST_F(DBBasicTest, FlushMultipleMemtable) {
426
+ do {
427
+ Options options = CurrentOptions();
428
+ WriteOptions writeOpt = WriteOptions();
429
+ writeOpt.disableWAL = true;
430
+ options.max_write_buffer_number = 4;
431
+ options.min_write_buffer_number_to_merge = 3;
432
+ options.max_write_buffer_size_to_maintain = -1;
433
+ CreateAndReopenWithCF({"pikachu"}, options);
434
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "foo", "v1"));
435
+ ASSERT_OK(Flush(1));
436
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v1"));
437
+
438
+ ASSERT_EQ("v1", Get(1, "foo"));
439
+ ASSERT_EQ("v1", Get(1, "bar"));
440
+ ASSERT_OK(Flush(1));
441
+ } while (ChangeCompactOptions());
442
+ }
443
+
444
+ TEST_F(DBBasicTest, FlushEmptyColumnFamily) {
445
+ // Block flush thread and disable compaction thread
446
+ env_->SetBackgroundThreads(1, Env::HIGH);
447
+ env_->SetBackgroundThreads(1, Env::LOW);
448
+ test::SleepingBackgroundTask sleeping_task_low;
449
+ env_->Schedule(&test::SleepingBackgroundTask::DoSleepTask, &sleeping_task_low,
450
+ Env::Priority::LOW);
451
+ test::SleepingBackgroundTask sleeping_task_high;
452
+ env_->Schedule(&test::SleepingBackgroundTask::DoSleepTask,
453
+ &sleeping_task_high, Env::Priority::HIGH);
454
+
455
+ Options options = CurrentOptions();
456
+ // disable compaction
457
+ options.disable_auto_compactions = true;
458
+ WriteOptions writeOpt = WriteOptions();
459
+ writeOpt.disableWAL = true;
460
+ options.max_write_buffer_number = 2;
461
+ options.min_write_buffer_number_to_merge = 1;
462
+ options.max_write_buffer_size_to_maintain =
463
+ static_cast<int64_t>(options.write_buffer_size);
464
+ CreateAndReopenWithCF({"pikachu"}, options);
465
+
466
+ // Compaction can still go through even if no thread can flush the
467
+ // mem table.
468
+ ASSERT_OK(Flush(0));
469
+ ASSERT_OK(Flush(1));
470
+
471
+ // Insert can go through
472
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[0], "foo", "v1"));
473
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v1"));
474
+
475
+ ASSERT_EQ("v1", Get(0, "foo"));
476
+ ASSERT_EQ("v1", Get(1, "bar"));
477
+
478
+ sleeping_task_high.WakeUp();
479
+ sleeping_task_high.WaitUntilDone();
480
+
481
+ // Flush can still go through.
482
+ ASSERT_OK(Flush(0));
483
+ ASSERT_OK(Flush(1));
484
+
485
+ sleeping_task_low.WakeUp();
486
+ sleeping_task_low.WaitUntilDone();
487
+ }
488
+
489
+ TEST_F(DBBasicTest, Flush) {
490
+ do {
491
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
492
+ WriteOptions writeOpt = WriteOptions();
493
+ writeOpt.disableWAL = true;
494
+ SetPerfLevel(kEnableTime);
495
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "foo", "v1"));
496
+ // this will now also flush the last 2 writes
497
+ ASSERT_OK(Flush(1));
498
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v1"));
499
+
500
+ get_perf_context()->Reset();
501
+ Get(1, "foo");
502
+ ASSERT_TRUE((int)get_perf_context()->get_from_output_files_time > 0);
503
+ ASSERT_EQ(2, (int)get_perf_context()->get_read_bytes);
504
+
505
+ ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions());
506
+ ASSERT_EQ("v1", Get(1, "foo"));
507
+ ASSERT_EQ("v1", Get(1, "bar"));
508
+
509
+ writeOpt.disableWAL = true;
510
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v2"));
511
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "foo", "v2"));
512
+ ASSERT_OK(Flush(1));
513
+
514
+ ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions());
515
+ ASSERT_EQ("v2", Get(1, "bar"));
516
+ get_perf_context()->Reset();
517
+ ASSERT_EQ("v2", Get(1, "foo"));
518
+ ASSERT_TRUE((int)get_perf_context()->get_from_output_files_time > 0);
519
+
520
+ writeOpt.disableWAL = false;
521
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v3"));
522
+ ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "foo", "v3"));
523
+ ASSERT_OK(Flush(1));
524
+
525
+ ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions());
526
+ // 'foo' should be there because its put
527
+ // has WAL enabled.
528
+ ASSERT_EQ("v3", Get(1, "foo"));
529
+ ASSERT_EQ("v3", Get(1, "bar"));
530
+
531
+ SetPerfLevel(kDisable);
532
+ } while (ChangeCompactOptions());
533
+ }
534
+
535
+ TEST_F(DBBasicTest, ManifestRollOver) {
536
+ do {
537
+ Options options;
538
+ options.max_manifest_file_size = 10; // 10 bytes
539
+ options = CurrentOptions(options);
540
+ CreateAndReopenWithCF({"pikachu"}, options);
541
+ {
542
+ ASSERT_OK(Put(1, "manifest_key1", std::string(1000, '1')));
543
+ ASSERT_OK(Put(1, "manifest_key2", std::string(1000, '2')));
544
+ ASSERT_OK(Put(1, "manifest_key3", std::string(1000, '3')));
545
+ uint64_t manifest_before_flush = dbfull()->TEST_Current_Manifest_FileNo();
546
+ ASSERT_OK(Flush(1)); // This should trigger LogAndApply.
547
+ uint64_t manifest_after_flush = dbfull()->TEST_Current_Manifest_FileNo();
548
+ ASSERT_GT(manifest_after_flush, manifest_before_flush);
549
+ ReopenWithColumnFamilies({"default", "pikachu"}, options);
550
+ ASSERT_GT(dbfull()->TEST_Current_Manifest_FileNo(), manifest_after_flush);
551
+ // check if a new manifest file got inserted or not.
552
+ ASSERT_EQ(std::string(1000, '1'), Get(1, "manifest_key1"));
553
+ ASSERT_EQ(std::string(1000, '2'), Get(1, "manifest_key2"));
554
+ ASSERT_EQ(std::string(1000, '3'), Get(1, "manifest_key3"));
555
+ }
556
+ } while (ChangeCompactOptions());
557
+ }
558
+
559
+ TEST_F(DBBasicTest, IdentityAcrossRestarts1) {
560
+ do {
561
+ std::string id1;
562
+ ASSERT_OK(db_->GetDbIdentity(id1));
563
+
564
+ Options options = CurrentOptions();
565
+ Reopen(options);
566
+ std::string id2;
567
+ ASSERT_OK(db_->GetDbIdentity(id2));
568
+ // id1 should match id2 because identity was not regenerated
569
+ ASSERT_EQ(id1.compare(id2), 0);
570
+
571
+ std::string idfilename = IdentityFileName(dbname_);
572
+ ASSERT_OK(env_->DeleteFile(idfilename));
573
+ Reopen(options);
574
+ std::string id3;
575
+ ASSERT_OK(db_->GetDbIdentity(id3));
576
+ if (options.write_dbid_to_manifest) {
577
+ ASSERT_EQ(id1.compare(id3), 0);
578
+ } else {
579
+ // id1 should NOT match id3 because identity was regenerated
580
+ ASSERT_NE(id1.compare(id3), 0);
581
+ }
582
+ } while (ChangeCompactOptions());
583
+ }
584
+
585
+ TEST_F(DBBasicTest, IdentityAcrossRestarts2) {
586
+ do {
587
+ std::string id1;
588
+ ASSERT_OK(db_->GetDbIdentity(id1));
589
+
590
+ Options options = CurrentOptions();
591
+ options.write_dbid_to_manifest = true;
592
+ Reopen(options);
593
+ std::string id2;
594
+ ASSERT_OK(db_->GetDbIdentity(id2));
595
+ // id1 should match id2 because identity was not regenerated
596
+ ASSERT_EQ(id1.compare(id2), 0);
597
+
598
+ std::string idfilename = IdentityFileName(dbname_);
599
+ ASSERT_OK(env_->DeleteFile(idfilename));
600
+ Reopen(options);
601
+ std::string id3;
602
+ ASSERT_OK(db_->GetDbIdentity(id3));
603
+ // id1 should NOT match id3 because identity was regenerated
604
+ ASSERT_EQ(id1, id3);
605
+ } while (ChangeCompactOptions());
606
+ }
607
+
608
+ #ifndef ROCKSDB_LITE
609
+ TEST_F(DBBasicTest, Snapshot) {
610
+ env_->SetMockSleep();
611
+ anon::OptionsOverride options_override;
612
+ options_override.skip_policy = kSkipNoSnapshot;
613
+ do {
614
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions(options_override));
615
+ ASSERT_OK(Put(0, "foo", "0v1"));
616
+ ASSERT_OK(Put(1, "foo", "1v1"));
617
+
618
+ const Snapshot* s1 = db_->GetSnapshot();
619
+ ASSERT_EQ(1U, GetNumSnapshots());
620
+ uint64_t time_snap1 = GetTimeOldestSnapshots();
621
+ ASSERT_GT(time_snap1, 0U);
622
+ ASSERT_EQ(GetSequenceOldestSnapshots(), s1->GetSequenceNumber());
623
+ ASSERT_OK(Put(0, "foo", "0v2"));
624
+ ASSERT_OK(Put(1, "foo", "1v2"));
625
+
626
+ env_->MockSleepForSeconds(1);
627
+
628
+ const Snapshot* s2 = db_->GetSnapshot();
629
+ ASSERT_EQ(2U, GetNumSnapshots());
630
+ ASSERT_EQ(time_snap1, GetTimeOldestSnapshots());
631
+ ASSERT_EQ(GetSequenceOldestSnapshots(), s1->GetSequenceNumber());
632
+ ASSERT_OK(Put(0, "foo", "0v3"));
633
+ ASSERT_OK(Put(1, "foo", "1v3"));
634
+
635
+ {
636
+ ManagedSnapshot s3(db_);
637
+ ASSERT_EQ(3U, GetNumSnapshots());
638
+ ASSERT_EQ(time_snap1, GetTimeOldestSnapshots());
639
+ ASSERT_EQ(GetSequenceOldestSnapshots(), s1->GetSequenceNumber());
640
+
641
+ ASSERT_OK(Put(0, "foo", "0v4"));
642
+ ASSERT_OK(Put(1, "foo", "1v4"));
643
+ ASSERT_EQ("0v1", Get(0, "foo", s1));
644
+ ASSERT_EQ("1v1", Get(1, "foo", s1));
645
+ ASSERT_EQ("0v2", Get(0, "foo", s2));
646
+ ASSERT_EQ("1v2", Get(1, "foo", s2));
647
+ ASSERT_EQ("0v3", Get(0, "foo", s3.snapshot()));
648
+ ASSERT_EQ("1v3", Get(1, "foo", s3.snapshot()));
649
+ ASSERT_EQ("0v4", Get(0, "foo"));
650
+ ASSERT_EQ("1v4", Get(1, "foo"));
651
+ }
652
+
653
+ ASSERT_EQ(2U, GetNumSnapshots());
654
+ ASSERT_EQ(time_snap1, GetTimeOldestSnapshots());
655
+ ASSERT_EQ(GetSequenceOldestSnapshots(), s1->GetSequenceNumber());
656
+ ASSERT_EQ("0v1", Get(0, "foo", s1));
657
+ ASSERT_EQ("1v1", Get(1, "foo", s1));
658
+ ASSERT_EQ("0v2", Get(0, "foo", s2));
659
+ ASSERT_EQ("1v2", Get(1, "foo", s2));
660
+ ASSERT_EQ("0v4", Get(0, "foo"));
661
+ ASSERT_EQ("1v4", Get(1, "foo"));
662
+
663
+ db_->ReleaseSnapshot(s1);
664
+ ASSERT_EQ("0v2", Get(0, "foo", s2));
665
+ ASSERT_EQ("1v2", Get(1, "foo", s2));
666
+ ASSERT_EQ("0v4", Get(0, "foo"));
667
+ ASSERT_EQ("1v4", Get(1, "foo"));
668
+ ASSERT_EQ(1U, GetNumSnapshots());
669
+ ASSERT_LT(time_snap1, GetTimeOldestSnapshots());
670
+ ASSERT_EQ(GetSequenceOldestSnapshots(), s2->GetSequenceNumber());
671
+
672
+ db_->ReleaseSnapshot(s2);
673
+ ASSERT_EQ(0U, GetNumSnapshots());
674
+ ASSERT_EQ(GetSequenceOldestSnapshots(), 0);
675
+ ASSERT_EQ("0v4", Get(0, "foo"));
676
+ ASSERT_EQ("1v4", Get(1, "foo"));
677
+ } while (ChangeOptions());
678
+ }
679
+
680
+ #endif // ROCKSDB_LITE
681
+
682
+ class DBBasicMultiConfigs : public DBBasicTest,
683
+ public ::testing::WithParamInterface<int> {
684
+ public:
685
+ DBBasicMultiConfigs() { option_config_ = GetParam(); }
686
+
687
+ static std::vector<int> GenerateOptionConfigs() {
688
+ std::vector<int> option_configs;
689
+ for (int option_config = kDefault; option_config < kEnd; ++option_config) {
690
+ if (!ShouldSkipOptions(option_config, kSkipFIFOCompaction)) {
691
+ option_configs.push_back(option_config);
692
+ }
693
+ }
694
+ return option_configs;
695
+ }
696
+ };
697
+
698
+ TEST_P(DBBasicMultiConfigs, CompactBetweenSnapshots) {
699
+ anon::OptionsOverride options_override;
700
+ options_override.skip_policy = kSkipNoSnapshot;
701
+ Options options = CurrentOptions(options_override);
702
+ options.disable_auto_compactions = true;
703
+ DestroyAndReopen(options);
704
+ CreateAndReopenWithCF({"pikachu"}, options);
705
+ Random rnd(301);
706
+ FillLevels("a", "z", 1);
707
+
708
+ ASSERT_OK(Put(1, "foo", "first"));
709
+ const Snapshot* snapshot1 = db_->GetSnapshot();
710
+ ASSERT_OK(Put(1, "foo", "second"));
711
+ ASSERT_OK(Put(1, "foo", "third"));
712
+ ASSERT_OK(Put(1, "foo", "fourth"));
713
+ const Snapshot* snapshot2 = db_->GetSnapshot();
714
+ ASSERT_OK(Put(1, "foo", "fifth"));
715
+ ASSERT_OK(Put(1, "foo", "sixth"));
716
+
717
+ // All entries (including duplicates) exist
718
+ // before any compaction or flush is triggered.
719
+ ASSERT_EQ(AllEntriesFor("foo", 1),
720
+ "[ sixth, fifth, fourth, third, second, first ]");
721
+ ASSERT_EQ("sixth", Get(1, "foo"));
722
+ ASSERT_EQ("fourth", Get(1, "foo", snapshot2));
723
+ ASSERT_EQ("first", Get(1, "foo", snapshot1));
724
+
725
+ // After a flush, "second", "third" and "fifth" should
726
+ // be removed
727
+ ASSERT_OK(Flush(1));
728
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ sixth, fourth, first ]");
729
+
730
+ // after we release the snapshot1, only two values left
731
+ db_->ReleaseSnapshot(snapshot1);
732
+ FillLevels("a", "z", 1);
733
+ ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), handles_[1], nullptr,
734
+ nullptr));
735
+
736
+ // We have only one valid snapshot snapshot2. Since snapshot1 is
737
+ // not valid anymore, "first" should be removed by a compaction.
738
+ ASSERT_EQ("sixth", Get(1, "foo"));
739
+ ASSERT_EQ("fourth", Get(1, "foo", snapshot2));
740
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ sixth, fourth ]");
741
+
742
+ // after we release the snapshot2, only one value should be left
743
+ db_->ReleaseSnapshot(snapshot2);
744
+ FillLevels("a", "z", 1);
745
+ ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), handles_[1], nullptr,
746
+ nullptr));
747
+ ASSERT_EQ("sixth", Get(1, "foo"));
748
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ sixth ]");
749
+ }
750
+
751
+ INSTANTIATE_TEST_CASE_P(
752
+ DBBasicMultiConfigs, DBBasicMultiConfigs,
753
+ ::testing::ValuesIn(DBBasicMultiConfigs::GenerateOptionConfigs()));
754
+
755
+ TEST_F(DBBasicTest, DBOpen_Options) {
756
+ Options options = CurrentOptions();
757
+ Close();
758
+ Destroy(options);
759
+
760
+ // Does not exist, and create_if_missing == false: error
761
+ DB* db = nullptr;
762
+ options.create_if_missing = false;
763
+ Status s = DB::Open(options, dbname_, &db);
764
+ ASSERT_TRUE(strstr(s.ToString().c_str(), "does not exist") != nullptr);
765
+ ASSERT_TRUE(db == nullptr);
766
+
767
+ // Does not exist, and create_if_missing == true: OK
768
+ options.create_if_missing = true;
769
+ s = DB::Open(options, dbname_, &db);
770
+ ASSERT_OK(s);
771
+ ASSERT_TRUE(db != nullptr);
772
+
773
+ delete db;
774
+ db = nullptr;
775
+
776
+ // Does exist, and error_if_exists == true: error
777
+ options.create_if_missing = false;
778
+ options.error_if_exists = true;
779
+ s = DB::Open(options, dbname_, &db);
780
+ ASSERT_TRUE(strstr(s.ToString().c_str(), "exists") != nullptr);
781
+ ASSERT_TRUE(db == nullptr);
782
+
783
+ // Does exist, and error_if_exists == false: OK
784
+ options.create_if_missing = true;
785
+ options.error_if_exists = false;
786
+ s = DB::Open(options, dbname_, &db);
787
+ ASSERT_OK(s);
788
+ ASSERT_TRUE(db != nullptr);
789
+
790
+ delete db;
791
+ db = nullptr;
792
+ }
793
+
794
+ TEST_F(DBBasicTest, CompactOnFlush) {
795
+ anon::OptionsOverride options_override;
796
+ options_override.skip_policy = kSkipNoSnapshot;
797
+ do {
798
+ Options options = CurrentOptions(options_override);
799
+ options.disable_auto_compactions = true;
800
+ CreateAndReopenWithCF({"pikachu"}, options);
801
+
802
+ ASSERT_OK(Put(1, "foo", "v1"));
803
+ ASSERT_OK(Flush(1));
804
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ v1 ]");
805
+
806
+ // Write two new keys
807
+ ASSERT_OK(Put(1, "a", "begin"));
808
+ ASSERT_OK(Put(1, "z", "end"));
809
+ ASSERT_OK(Flush(1));
810
+
811
+ // Case1: Delete followed by a put
812
+ ASSERT_OK(Delete(1, "foo"));
813
+ ASSERT_OK(Put(1, "foo", "v2"));
814
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ v2, DEL, v1 ]");
815
+
816
+ // After the current memtable is flushed, the DEL should
817
+ // have been removed
818
+ ASSERT_OK(Flush(1));
819
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ v2, v1 ]");
820
+
821
+ ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), handles_[1],
822
+ nullptr, nullptr));
823
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ v2 ]");
824
+
825
+ // Case 2: Delete followed by another delete
826
+ ASSERT_OK(Delete(1, "foo"));
827
+ ASSERT_OK(Delete(1, "foo"));
828
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ DEL, DEL, v2 ]");
829
+ ASSERT_OK(Flush(1));
830
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ DEL, v2 ]");
831
+ ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), handles_[1],
832
+ nullptr, nullptr));
833
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ ]");
834
+
835
+ // Case 3: Put followed by a delete
836
+ ASSERT_OK(Put(1, "foo", "v3"));
837
+ ASSERT_OK(Delete(1, "foo"));
838
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ DEL, v3 ]");
839
+ ASSERT_OK(Flush(1));
840
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ DEL ]");
841
+ ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), handles_[1],
842
+ nullptr, nullptr));
843
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ ]");
844
+
845
+ // Case 4: Put followed by another Put
846
+ ASSERT_OK(Put(1, "foo", "v4"));
847
+ ASSERT_OK(Put(1, "foo", "v5"));
848
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ v5, v4 ]");
849
+ ASSERT_OK(Flush(1));
850
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ v5 ]");
851
+ ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), handles_[1],
852
+ nullptr, nullptr));
853
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ v5 ]");
854
+
855
+ // clear database
856
+ ASSERT_OK(Delete(1, "foo"));
857
+ ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), handles_[1],
858
+ nullptr, nullptr));
859
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ ]");
860
+
861
+ // Case 5: Put followed by snapshot followed by another Put
862
+ // Both puts should remain.
863
+ ASSERT_OK(Put(1, "foo", "v6"));
864
+ const Snapshot* snapshot = db_->GetSnapshot();
865
+ ASSERT_OK(Put(1, "foo", "v7"));
866
+ ASSERT_OK(Flush(1));
867
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ v7, v6 ]");
868
+ db_->ReleaseSnapshot(snapshot);
869
+
870
+ // clear database
871
+ ASSERT_OK(Delete(1, "foo"));
872
+ ASSERT_OK(dbfull()->CompactRange(CompactRangeOptions(), handles_[1],
873
+ nullptr, nullptr));
874
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ ]");
875
+
876
+ // Case 5: snapshot followed by a put followed by another Put
877
+ // Only the last put should remain.
878
+ const Snapshot* snapshot1 = db_->GetSnapshot();
879
+ ASSERT_OK(Put(1, "foo", "v8"));
880
+ ASSERT_OK(Put(1, "foo", "v9"));
881
+ ASSERT_OK(Flush(1));
882
+ ASSERT_EQ(AllEntriesFor("foo", 1), "[ v9 ]");
883
+ db_->ReleaseSnapshot(snapshot1);
884
+ } while (ChangeCompactOptions());
885
+ }
886
+
887
+ TEST_F(DBBasicTest, FlushOneColumnFamily) {
888
+ Options options = CurrentOptions();
889
+ CreateAndReopenWithCF({"pikachu", "ilya", "muromec", "dobrynia", "nikitich",
890
+ "alyosha", "popovich"},
891
+ options);
892
+
893
+ ASSERT_OK(Put(0, "Default", "Default"));
894
+ ASSERT_OK(Put(1, "pikachu", "pikachu"));
895
+ ASSERT_OK(Put(2, "ilya", "ilya"));
896
+ ASSERT_OK(Put(3, "muromec", "muromec"));
897
+ ASSERT_OK(Put(4, "dobrynia", "dobrynia"));
898
+ ASSERT_OK(Put(5, "nikitich", "nikitich"));
899
+ ASSERT_OK(Put(6, "alyosha", "alyosha"));
900
+ ASSERT_OK(Put(7, "popovich", "popovich"));
901
+
902
+ for (int i = 0; i < 8; ++i) {
903
+ ASSERT_OK(Flush(i));
904
+ auto tables = ListTableFiles(env_, dbname_);
905
+ ASSERT_EQ(tables.size(), i + 1U);
906
+ }
907
+ }
908
+
909
+ TEST_F(DBBasicTest, MultiGetSimple) {
910
+ do {
911
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
912
+ SetPerfLevel(kEnableCount);
913
+ ASSERT_OK(Put(1, "k1", "v1"));
914
+ ASSERT_OK(Put(1, "k2", "v2"));
915
+ ASSERT_OK(Put(1, "k3", "v3"));
916
+ ASSERT_OK(Put(1, "k4", "v4"));
917
+ ASSERT_OK(Delete(1, "k4"));
918
+ ASSERT_OK(Put(1, "k5", "v5"));
919
+ ASSERT_OK(Delete(1, "no_key"));
920
+
921
+ std::vector<Slice> keys({"k1", "k2", "k3", "k4", "k5", "no_key"});
922
+
923
+ std::vector<std::string> values(20, "Temporary data to be overwritten");
924
+ std::vector<ColumnFamilyHandle*> cfs(keys.size(), handles_[1]);
925
+
926
+ get_perf_context()->Reset();
927
+ std::vector<Status> s = db_->MultiGet(ReadOptions(), cfs, keys, &values);
928
+ ASSERT_EQ(values.size(), keys.size());
929
+ ASSERT_EQ(values[0], "v1");
930
+ ASSERT_EQ(values[1], "v2");
931
+ ASSERT_EQ(values[2], "v3");
932
+ ASSERT_EQ(values[4], "v5");
933
+ // four kv pairs * two bytes per value
934
+ ASSERT_EQ(8, (int)get_perf_context()->multiget_read_bytes);
935
+
936
+ ASSERT_OK(s[0]);
937
+ ASSERT_OK(s[1]);
938
+ ASSERT_OK(s[2]);
939
+ ASSERT_TRUE(s[3].IsNotFound());
940
+ ASSERT_OK(s[4]);
941
+ ASSERT_TRUE(s[5].IsNotFound());
942
+ SetPerfLevel(kDisable);
943
+ } while (ChangeCompactOptions());
944
+ }
945
+
946
+ TEST_F(DBBasicTest, MultiGetEmpty) {
947
+ do {
948
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
949
+ // Empty Key Set
950
+ std::vector<Slice> keys;
951
+ std::vector<std::string> values;
952
+ std::vector<ColumnFamilyHandle*> cfs;
953
+ std::vector<Status> s = db_->MultiGet(ReadOptions(), cfs, keys, &values);
954
+ ASSERT_EQ(s.size(), 0U);
955
+
956
+ // Empty Database, Empty Key Set
957
+ Options options = CurrentOptions();
958
+ options.create_if_missing = true;
959
+ DestroyAndReopen(options);
960
+ CreateAndReopenWithCF({"pikachu"}, options);
961
+ s = db_->MultiGet(ReadOptions(), cfs, keys, &values);
962
+ ASSERT_EQ(s.size(), 0U);
963
+
964
+ // Empty Database, Search for Keys
965
+ keys.resize(2);
966
+ keys[0] = "a";
967
+ keys[1] = "b";
968
+ cfs.push_back(handles_[0]);
969
+ cfs.push_back(handles_[1]);
970
+ s = db_->MultiGet(ReadOptions(), cfs, keys, &values);
971
+ ASSERT_EQ(static_cast<int>(s.size()), 2);
972
+ ASSERT_TRUE(s[0].IsNotFound() && s[1].IsNotFound());
973
+ } while (ChangeCompactOptions());
974
+ }
975
+
976
+ TEST_F(DBBasicTest, ChecksumTest) {
977
+ BlockBasedTableOptions table_options;
978
+ Options options = CurrentOptions();
979
+ // change when new checksum type added
980
+ int max_checksum = static_cast<int>(kxxHash64);
981
+ const int kNumPerFile = 2;
982
+
983
+ // generate one table with each type of checksum
984
+ for (int i = 0; i <= max_checksum; ++i) {
985
+ table_options.checksum = static_cast<ChecksumType>(i);
986
+ options.table_factory.reset(NewBlockBasedTableFactory(table_options));
987
+ Reopen(options);
988
+ for (int j = 0; j < kNumPerFile; ++j) {
989
+ ASSERT_OK(Put(Key(i * kNumPerFile + j), Key(i * kNumPerFile + j)));
990
+ }
991
+ ASSERT_OK(Flush());
992
+ }
993
+
994
+ // with each valid checksum type setting...
995
+ for (int i = 0; i <= max_checksum; ++i) {
996
+ table_options.checksum = static_cast<ChecksumType>(i);
997
+ options.table_factory.reset(NewBlockBasedTableFactory(table_options));
998
+ Reopen(options);
999
+ // verify every type of checksum (should be regardless of that setting)
1000
+ for (int j = 0; j < (max_checksum + 1) * kNumPerFile; ++j) {
1001
+ ASSERT_EQ(Key(j), Get(Key(j)));
1002
+ }
1003
+ }
1004
+ }
1005
+
1006
+ // On Windows you can have either memory mapped file or a file
1007
+ // with unbuffered access. So this asserts and does not make
1008
+ // sense to run
1009
+ #ifndef OS_WIN
1010
+ TEST_F(DBBasicTest, MmapAndBufferOptions) {
1011
+ if (!IsMemoryMappedAccessSupported()) {
1012
+ return;
1013
+ }
1014
+ Options options = CurrentOptions();
1015
+
1016
+ options.use_direct_reads = true;
1017
+ options.allow_mmap_reads = true;
1018
+ ASSERT_NOK(TryReopen(options));
1019
+
1020
+ // All other combinations are acceptable
1021
+ options.use_direct_reads = false;
1022
+ ASSERT_OK(TryReopen(options));
1023
+
1024
+ if (IsDirectIOSupported()) {
1025
+ options.use_direct_reads = true;
1026
+ options.allow_mmap_reads = false;
1027
+ ASSERT_OK(TryReopen(options));
1028
+ }
1029
+
1030
+ options.use_direct_reads = false;
1031
+ ASSERT_OK(TryReopen(options));
1032
+ }
1033
+ #endif
1034
+
1035
+ class TestEnv : public EnvWrapper {
1036
+ public:
1037
+ explicit TestEnv(Env* base_env) : EnvWrapper(base_env), close_count(0) {}
1038
+
1039
+ class TestLogger : public Logger {
1040
+ public:
1041
+ using Logger::Logv;
1042
+ explicit TestLogger(TestEnv* env_ptr) : Logger() { env = env_ptr; }
1043
+ ~TestLogger() override {
1044
+ if (!closed_) {
1045
+ CloseHelper().PermitUncheckedError();
1046
+ }
1047
+ }
1048
+ void Logv(const char* /*format*/, va_list /*ap*/) override {}
1049
+
1050
+ protected:
1051
+ Status CloseImpl() override { return CloseHelper(); }
1052
+
1053
+ private:
1054
+ Status CloseHelper() {
1055
+ env->CloseCountInc();
1056
+ ;
1057
+ return Status::IOError();
1058
+ }
1059
+ TestEnv* env;
1060
+ };
1061
+
1062
+ void CloseCountInc() { close_count++; }
1063
+
1064
+ int GetCloseCount() { return close_count; }
1065
+
1066
+ Status NewLogger(const std::string& /*fname*/,
1067
+ std::shared_ptr<Logger>* result) override {
1068
+ result->reset(new TestLogger(this));
1069
+ return Status::OK();
1070
+ }
1071
+
1072
+ private:
1073
+ int close_count;
1074
+ };
1075
+
1076
+ TEST_F(DBBasicTest, DBClose) {
1077
+ Options options = GetDefaultOptions();
1078
+ std::string dbname = test::PerThreadDBPath("db_close_test");
1079
+ ASSERT_OK(DestroyDB(dbname, options));
1080
+
1081
+ DB* db = nullptr;
1082
+ TestEnv* env = new TestEnv(env_);
1083
+ std::unique_ptr<TestEnv> local_env_guard(env);
1084
+ options.create_if_missing = true;
1085
+ options.env = env;
1086
+ Status s = DB::Open(options, dbname, &db);
1087
+ ASSERT_OK(s);
1088
+ ASSERT_TRUE(db != nullptr);
1089
+
1090
+ s = db->Close();
1091
+ ASSERT_EQ(env->GetCloseCount(), 1);
1092
+ ASSERT_EQ(s, Status::IOError());
1093
+
1094
+ delete db;
1095
+ ASSERT_EQ(env->GetCloseCount(), 1);
1096
+
1097
+ // Do not call DB::Close() and ensure our logger Close() still gets called
1098
+ s = DB::Open(options, dbname, &db);
1099
+ ASSERT_OK(s);
1100
+ ASSERT_TRUE(db != nullptr);
1101
+ delete db;
1102
+ ASSERT_EQ(env->GetCloseCount(), 2);
1103
+
1104
+ // Provide our own logger and ensure DB::Close() does not close it
1105
+ options.info_log.reset(new TestEnv::TestLogger(env));
1106
+ options.create_if_missing = false;
1107
+ s = DB::Open(options, dbname, &db);
1108
+ ASSERT_OK(s);
1109
+ ASSERT_TRUE(db != nullptr);
1110
+
1111
+ s = db->Close();
1112
+ ASSERT_EQ(s, Status::OK());
1113
+ delete db;
1114
+ ASSERT_EQ(env->GetCloseCount(), 2);
1115
+ options.info_log.reset();
1116
+ ASSERT_EQ(env->GetCloseCount(), 3);
1117
+ }
1118
+
1119
+ TEST_F(DBBasicTest, DBCloseFlushError) {
1120
+ std::unique_ptr<FaultInjectionTestEnv> fault_injection_env(
1121
+ new FaultInjectionTestEnv(env_));
1122
+ Options options = GetDefaultOptions();
1123
+ options.create_if_missing = true;
1124
+ options.manual_wal_flush = true;
1125
+ options.write_buffer_size = 100;
1126
+ options.env = fault_injection_env.get();
1127
+
1128
+ Reopen(options);
1129
+ ASSERT_OK(Put("key1", "value1"));
1130
+ ASSERT_OK(Put("key2", "value2"));
1131
+ ASSERT_OK(dbfull()->TEST_SwitchMemtable());
1132
+ ASSERT_OK(Put("key3", "value3"));
1133
+ fault_injection_env->SetFilesystemActive(false);
1134
+ Status s = dbfull()->Close();
1135
+ fault_injection_env->SetFilesystemActive(true);
1136
+ ASSERT_NE(s, Status::OK());
1137
+
1138
+ Destroy(options);
1139
+ }
1140
+
1141
+ class DBMultiGetTestWithParam : public DBBasicTest,
1142
+ public testing::WithParamInterface<bool> {};
1143
+
1144
+ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCF) {
1145
+ Options options = CurrentOptions();
1146
+ CreateAndReopenWithCF({"pikachu", "ilya", "muromec", "dobrynia", "nikitich",
1147
+ "alyosha", "popovich"},
1148
+ options);
1149
+ // <CF, key, value> tuples
1150
+ std::vector<std::tuple<int, std::string, std::string>> cf_kv_vec;
1151
+ static const int num_keys = 24;
1152
+ cf_kv_vec.reserve(num_keys);
1153
+
1154
+ for (int i = 0; i < num_keys; ++i) {
1155
+ int cf = i / 3;
1156
+ int cf_key = 1 % 3;
1157
+ cf_kv_vec.emplace_back(std::make_tuple(
1158
+ cf, "cf" + std::to_string(cf) + "_key_" + std::to_string(cf_key),
1159
+ "cf" + std::to_string(cf) + "_val_" + std::to_string(cf_key)));
1160
+ ASSERT_OK(Put(std::get<0>(cf_kv_vec[i]), std::get<1>(cf_kv_vec[i]),
1161
+ std::get<2>(cf_kv_vec[i])));
1162
+ }
1163
+
1164
+ int get_sv_count = 0;
1165
+ ROCKSDB_NAMESPACE::DBImpl* db = static_cast_with_check<DBImpl>(db_);
1166
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1167
+ "DBImpl::MultiGet::AfterRefSV", [&](void* /*arg*/) {
1168
+ if (++get_sv_count == 2) {
1169
+ // After MultiGet refs a couple of CFs, flush all CFs so MultiGet
1170
+ // is forced to repeat the process
1171
+ for (int i = 0; i < num_keys; ++i) {
1172
+ int cf = i / 3;
1173
+ int cf_key = i % 8;
1174
+ if (cf_key == 0) {
1175
+ ASSERT_OK(Flush(cf));
1176
+ }
1177
+ ASSERT_OK(Put(std::get<0>(cf_kv_vec[i]), std::get<1>(cf_kv_vec[i]),
1178
+ std::get<2>(cf_kv_vec[i]) + "_2"));
1179
+ }
1180
+ }
1181
+ if (get_sv_count == 11) {
1182
+ for (int i = 0; i < 8; ++i) {
1183
+ auto* cfd = static_cast_with_check<ColumnFamilyHandleImpl>(
1184
+ db->GetColumnFamilyHandle(i))
1185
+ ->cfd();
1186
+ ASSERT_EQ(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
1187
+ }
1188
+ }
1189
+ });
1190
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1191
+
1192
+ std::vector<int> cfs;
1193
+ std::vector<std::string> keys;
1194
+ std::vector<std::string> values;
1195
+
1196
+ for (int i = 0; i < num_keys; ++i) {
1197
+ cfs.push_back(std::get<0>(cf_kv_vec[i]));
1198
+ keys.push_back(std::get<1>(cf_kv_vec[i]));
1199
+ }
1200
+
1201
+ values = MultiGet(cfs, keys, nullptr, GetParam());
1202
+ ASSERT_EQ(values.size(), num_keys);
1203
+ for (unsigned int j = 0; j < values.size(); ++j) {
1204
+ ASSERT_EQ(values[j], std::get<2>(cf_kv_vec[j]) + "_2");
1205
+ }
1206
+
1207
+ keys.clear();
1208
+ cfs.clear();
1209
+ cfs.push_back(std::get<0>(cf_kv_vec[0]));
1210
+ keys.push_back(std::get<1>(cf_kv_vec[0]));
1211
+ cfs.push_back(std::get<0>(cf_kv_vec[3]));
1212
+ keys.push_back(std::get<1>(cf_kv_vec[3]));
1213
+ cfs.push_back(std::get<0>(cf_kv_vec[4]));
1214
+ keys.push_back(std::get<1>(cf_kv_vec[4]));
1215
+ values = MultiGet(cfs, keys, nullptr, GetParam());
1216
+ ASSERT_EQ(values[0], std::get<2>(cf_kv_vec[0]) + "_2");
1217
+ ASSERT_EQ(values[1], std::get<2>(cf_kv_vec[3]) + "_2");
1218
+ ASSERT_EQ(values[2], std::get<2>(cf_kv_vec[4]) + "_2");
1219
+
1220
+ keys.clear();
1221
+ cfs.clear();
1222
+ cfs.push_back(std::get<0>(cf_kv_vec[7]));
1223
+ keys.push_back(std::get<1>(cf_kv_vec[7]));
1224
+ cfs.push_back(std::get<0>(cf_kv_vec[6]));
1225
+ keys.push_back(std::get<1>(cf_kv_vec[6]));
1226
+ cfs.push_back(std::get<0>(cf_kv_vec[1]));
1227
+ keys.push_back(std::get<1>(cf_kv_vec[1]));
1228
+ values = MultiGet(cfs, keys, nullptr, GetParam());
1229
+ ASSERT_EQ(values[0], std::get<2>(cf_kv_vec[7]) + "_2");
1230
+ ASSERT_EQ(values[1], std::get<2>(cf_kv_vec[6]) + "_2");
1231
+ ASSERT_EQ(values[2], std::get<2>(cf_kv_vec[1]) + "_2");
1232
+
1233
+ for (int cf = 0; cf < 8; ++cf) {
1234
+ auto* cfd =
1235
+ static_cast_with_check<ColumnFamilyHandleImpl>(
1236
+ static_cast_with_check<DBImpl>(db_)->GetColumnFamilyHandle(cf))
1237
+ ->cfd();
1238
+ ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
1239
+ ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVObsolete);
1240
+ }
1241
+ }
1242
+
1243
+ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCFMutex) {
1244
+ Options options = CurrentOptions();
1245
+ CreateAndReopenWithCF({"pikachu", "ilya", "muromec", "dobrynia", "nikitich",
1246
+ "alyosha", "popovich"},
1247
+ options);
1248
+
1249
+ for (int i = 0; i < 8; ++i) {
1250
+ ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
1251
+ "cf" + std::to_string(i) + "_val"));
1252
+ }
1253
+
1254
+ int get_sv_count = 0;
1255
+ int retries = 0;
1256
+ bool last_try = false;
1257
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1258
+ "DBImpl::MultiGet::LastTry", [&](void* /*arg*/) {
1259
+ last_try = true;
1260
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
1261
+ });
1262
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1263
+ "DBImpl::MultiGet::AfterRefSV", [&](void* /*arg*/) {
1264
+ if (last_try) {
1265
+ return;
1266
+ }
1267
+ if (++get_sv_count == 2) {
1268
+ ++retries;
1269
+ get_sv_count = 0;
1270
+ for (int i = 0; i < 8; ++i) {
1271
+ ASSERT_OK(Flush(i));
1272
+ ASSERT_OK(Put(
1273
+ i, "cf" + std::to_string(i) + "_key",
1274
+ "cf" + std::to_string(i) + "_val" + std::to_string(retries)));
1275
+ }
1276
+ }
1277
+ });
1278
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1279
+
1280
+ std::vector<int> cfs;
1281
+ std::vector<std::string> keys;
1282
+ std::vector<std::string> values;
1283
+
1284
+ for (int i = 0; i < 8; ++i) {
1285
+ cfs.push_back(i);
1286
+ keys.push_back("cf" + std::to_string(i) + "_key");
1287
+ }
1288
+
1289
+ values = MultiGet(cfs, keys, nullptr, GetParam());
1290
+ ASSERT_TRUE(last_try);
1291
+ ASSERT_EQ(values.size(), 8);
1292
+ for (unsigned int j = 0; j < values.size(); ++j) {
1293
+ ASSERT_EQ(values[j],
1294
+ "cf" + std::to_string(j) + "_val" + std::to_string(retries));
1295
+ }
1296
+ for (int i = 0; i < 8; ++i) {
1297
+ auto* cfd =
1298
+ static_cast_with_check<ColumnFamilyHandleImpl>(
1299
+ static_cast_with_check<DBImpl>(db_)->GetColumnFamilyHandle(i))
1300
+ ->cfd();
1301
+ ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
1302
+ }
1303
+ }
1304
+
1305
+ TEST_P(DBMultiGetTestWithParam, MultiGetMultiCFSnapshot) {
1306
+ Options options = CurrentOptions();
1307
+ CreateAndReopenWithCF({"pikachu", "ilya", "muromec", "dobrynia", "nikitich",
1308
+ "alyosha", "popovich"},
1309
+ options);
1310
+
1311
+ for (int i = 0; i < 8; ++i) {
1312
+ ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
1313
+ "cf" + std::to_string(i) + "_val"));
1314
+ }
1315
+
1316
+ int get_sv_count = 0;
1317
+ ROCKSDB_NAMESPACE::DBImpl* db = static_cast_with_check<DBImpl>(db_);
1318
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1319
+ "DBImpl::MultiGet::AfterRefSV", [&](void* /*arg*/) {
1320
+ if (++get_sv_count == 2) {
1321
+ for (int i = 0; i < 8; ++i) {
1322
+ ASSERT_OK(Flush(i));
1323
+ ASSERT_OK(Put(i, "cf" + std::to_string(i) + "_key",
1324
+ "cf" + std::to_string(i) + "_val2"));
1325
+ }
1326
+ }
1327
+ if (get_sv_count == 8) {
1328
+ for (int i = 0; i < 8; ++i) {
1329
+ auto* cfd = static_cast_with_check<ColumnFamilyHandleImpl>(
1330
+ db->GetColumnFamilyHandle(i))
1331
+ ->cfd();
1332
+ ASSERT_TRUE(
1333
+ (cfd->TEST_GetLocalSV()->Get() == SuperVersion::kSVInUse) ||
1334
+ (cfd->TEST_GetLocalSV()->Get() == SuperVersion::kSVObsolete));
1335
+ }
1336
+ }
1337
+ });
1338
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1339
+
1340
+ std::vector<int> cfs;
1341
+ std::vector<std::string> keys;
1342
+ std::vector<std::string> values;
1343
+
1344
+ for (int i = 0; i < 8; ++i) {
1345
+ cfs.push_back(i);
1346
+ keys.push_back("cf" + std::to_string(i) + "_key");
1347
+ }
1348
+
1349
+ const Snapshot* snapshot = db_->GetSnapshot();
1350
+ values = MultiGet(cfs, keys, snapshot, GetParam());
1351
+ db_->ReleaseSnapshot(snapshot);
1352
+ ASSERT_EQ(values.size(), 8);
1353
+ for (unsigned int j = 0; j < values.size(); ++j) {
1354
+ ASSERT_EQ(values[j], "cf" + std::to_string(j) + "_val");
1355
+ }
1356
+ for (int i = 0; i < 8; ++i) {
1357
+ auto* cfd =
1358
+ static_cast_with_check<ColumnFamilyHandleImpl>(
1359
+ static_cast_with_check<DBImpl>(db_)->GetColumnFamilyHandle(i))
1360
+ ->cfd();
1361
+ ASSERT_NE(cfd->TEST_GetLocalSV()->Get(), SuperVersion::kSVInUse);
1362
+ }
1363
+ }
1364
+
1365
+ INSTANTIATE_TEST_CASE_P(DBMultiGetTestWithParam, DBMultiGetTestWithParam,
1366
+ testing::Bool());
1367
+
1368
+ TEST_F(DBBasicTest, MultiGetBatchedSimpleUnsorted) {
1369
+ do {
1370
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
1371
+ SetPerfLevel(kEnableCount);
1372
+ ASSERT_OK(Put(1, "k1", "v1"));
1373
+ ASSERT_OK(Put(1, "k2", "v2"));
1374
+ ASSERT_OK(Put(1, "k3", "v3"));
1375
+ ASSERT_OK(Put(1, "k4", "v4"));
1376
+ ASSERT_OK(Delete(1, "k4"));
1377
+ ASSERT_OK(Put(1, "k5", "v5"));
1378
+ ASSERT_OK(Delete(1, "no_key"));
1379
+
1380
+ get_perf_context()->Reset();
1381
+
1382
+ std::vector<Slice> keys({"no_key", "k5", "k4", "k3", "k2", "k1"});
1383
+ std::vector<PinnableSlice> values(keys.size());
1384
+ std::vector<ColumnFamilyHandle*> cfs(keys.size(), handles_[1]);
1385
+ std::vector<Status> s(keys.size());
1386
+
1387
+ db_->MultiGet(ReadOptions(), handles_[1], keys.size(), keys.data(),
1388
+ values.data(), s.data(), false);
1389
+
1390
+ ASSERT_EQ(values.size(), keys.size());
1391
+ ASSERT_EQ(std::string(values[5].data(), values[5].size()), "v1");
1392
+ ASSERT_EQ(std::string(values[4].data(), values[4].size()), "v2");
1393
+ ASSERT_EQ(std::string(values[3].data(), values[3].size()), "v3");
1394
+ ASSERT_EQ(std::string(values[1].data(), values[1].size()), "v5");
1395
+ // four kv pairs * two bytes per value
1396
+ ASSERT_EQ(8, (int)get_perf_context()->multiget_read_bytes);
1397
+
1398
+ ASSERT_TRUE(s[0].IsNotFound());
1399
+ ASSERT_OK(s[1]);
1400
+ ASSERT_TRUE(s[2].IsNotFound());
1401
+ ASSERT_OK(s[3]);
1402
+ ASSERT_OK(s[4]);
1403
+ ASSERT_OK(s[5]);
1404
+
1405
+ SetPerfLevel(kDisable);
1406
+ } while (ChangeCompactOptions());
1407
+ }
1408
+
1409
+ TEST_F(DBBasicTest, MultiGetBatchedSortedMultiFile) {
1410
+ do {
1411
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
1412
+ SetPerfLevel(kEnableCount);
1413
+ // To expand the power of this test, generate > 1 table file and
1414
+ // mix with memtable
1415
+ ASSERT_OK(Put(1, "k1", "v1"));
1416
+ ASSERT_OK(Put(1, "k2", "v2"));
1417
+ ASSERT_OK(Flush(1));
1418
+ ASSERT_OK(Put(1, "k3", "v3"));
1419
+ ASSERT_OK(Put(1, "k4", "v4"));
1420
+ ASSERT_OK(Flush(1));
1421
+ ASSERT_OK(Delete(1, "k4"));
1422
+ ASSERT_OK(Put(1, "k5", "v5"));
1423
+ ASSERT_OK(Delete(1, "no_key"));
1424
+
1425
+ get_perf_context()->Reset();
1426
+
1427
+ std::vector<Slice> keys({"k1", "k2", "k3", "k4", "k5", "no_key"});
1428
+ std::vector<PinnableSlice> values(keys.size());
1429
+ std::vector<ColumnFamilyHandle*> cfs(keys.size(), handles_[1]);
1430
+ std::vector<Status> s(keys.size());
1431
+
1432
+ db_->MultiGet(ReadOptions(), handles_[1], keys.size(), keys.data(),
1433
+ values.data(), s.data(), true);
1434
+
1435
+ ASSERT_EQ(values.size(), keys.size());
1436
+ ASSERT_EQ(std::string(values[0].data(), values[0].size()), "v1");
1437
+ ASSERT_EQ(std::string(values[1].data(), values[1].size()), "v2");
1438
+ ASSERT_EQ(std::string(values[2].data(), values[2].size()), "v3");
1439
+ ASSERT_EQ(std::string(values[4].data(), values[4].size()), "v5");
1440
+ // four kv pairs * two bytes per value
1441
+ ASSERT_EQ(8, (int)get_perf_context()->multiget_read_bytes);
1442
+
1443
+ ASSERT_OK(s[0]);
1444
+ ASSERT_OK(s[1]);
1445
+ ASSERT_OK(s[2]);
1446
+ ASSERT_TRUE(s[3].IsNotFound());
1447
+ ASSERT_OK(s[4]);
1448
+ ASSERT_TRUE(s[5].IsNotFound());
1449
+
1450
+ SetPerfLevel(kDisable);
1451
+ } while (ChangeOptions());
1452
+ }
1453
+
1454
+ TEST_F(DBBasicTest, MultiGetBatchedDuplicateKeys) {
1455
+ Options opts = CurrentOptions();
1456
+ opts.merge_operator = MergeOperators::CreateStringAppendOperator();
1457
+ CreateAndReopenWithCF({"pikachu"}, opts);
1458
+ SetPerfLevel(kEnableCount);
1459
+ // To expand the power of this test, generate > 1 table file and
1460
+ // mix with memtable
1461
+ ASSERT_OK(Merge(1, "k1", "v1"));
1462
+ ASSERT_OK(Merge(1, "k2", "v2"));
1463
+ ASSERT_OK(Flush(1));
1464
+ MoveFilesToLevel(2, 1);
1465
+ ASSERT_OK(Merge(1, "k3", "v3"));
1466
+ ASSERT_OK(Merge(1, "k4", "v4"));
1467
+ ASSERT_OK(Flush(1));
1468
+ MoveFilesToLevel(2, 1);
1469
+ ASSERT_OK(Merge(1, "k4", "v4_2"));
1470
+ ASSERT_OK(Merge(1, "k6", "v6"));
1471
+ ASSERT_OK(Flush(1));
1472
+ MoveFilesToLevel(2, 1);
1473
+ ASSERT_OK(Merge(1, "k7", "v7"));
1474
+ ASSERT_OK(Merge(1, "k8", "v8"));
1475
+ ASSERT_OK(Flush(1));
1476
+ MoveFilesToLevel(2, 1);
1477
+
1478
+ get_perf_context()->Reset();
1479
+
1480
+ std::vector<Slice> keys({"k8", "k8", "k8", "k4", "k4", "k1", "k3"});
1481
+ std::vector<PinnableSlice> values(keys.size());
1482
+ std::vector<ColumnFamilyHandle*> cfs(keys.size(), handles_[1]);
1483
+ std::vector<Status> s(keys.size());
1484
+
1485
+ db_->MultiGet(ReadOptions(), handles_[1], keys.size(), keys.data(),
1486
+ values.data(), s.data(), false);
1487
+
1488
+ ASSERT_EQ(values.size(), keys.size());
1489
+ ASSERT_EQ(std::string(values[0].data(), values[0].size()), "v8");
1490
+ ASSERT_EQ(std::string(values[1].data(), values[1].size()), "v8");
1491
+ ASSERT_EQ(std::string(values[2].data(), values[2].size()), "v8");
1492
+ ASSERT_EQ(std::string(values[3].data(), values[3].size()), "v4,v4_2");
1493
+ ASSERT_EQ(std::string(values[4].data(), values[4].size()), "v4,v4_2");
1494
+ ASSERT_EQ(std::string(values[5].data(), values[5].size()), "v1");
1495
+ ASSERT_EQ(std::string(values[6].data(), values[6].size()), "v3");
1496
+ ASSERT_EQ(24, (int)get_perf_context()->multiget_read_bytes);
1497
+
1498
+ for (Status& status : s) {
1499
+ ASSERT_OK(status);
1500
+ }
1501
+
1502
+ SetPerfLevel(kDisable);
1503
+ }
1504
+
1505
+ TEST_F(DBBasicTest, MultiGetBatchedMultiLevel) {
1506
+ Options options = CurrentOptions();
1507
+ options.disable_auto_compactions = true;
1508
+ Reopen(options);
1509
+ int num_keys = 0;
1510
+
1511
+ for (int i = 0; i < 128; ++i) {
1512
+ ASSERT_OK(Put("key_" + std::to_string(i), "val_l2_" + std::to_string(i)));
1513
+ num_keys++;
1514
+ if (num_keys == 8) {
1515
+ ASSERT_OK(Flush());
1516
+ num_keys = 0;
1517
+ }
1518
+ }
1519
+ if (num_keys > 0) {
1520
+ ASSERT_OK(Flush());
1521
+ num_keys = 0;
1522
+ }
1523
+ MoveFilesToLevel(2);
1524
+
1525
+ for (int i = 0; i < 128; i += 3) {
1526
+ ASSERT_OK(Put("key_" + std::to_string(i), "val_l1_" + std::to_string(i)));
1527
+ num_keys++;
1528
+ if (num_keys == 8) {
1529
+ ASSERT_OK(Flush());
1530
+ num_keys = 0;
1531
+ }
1532
+ }
1533
+ if (num_keys > 0) {
1534
+ ASSERT_OK(Flush());
1535
+ num_keys = 0;
1536
+ }
1537
+ MoveFilesToLevel(1);
1538
+
1539
+ for (int i = 0; i < 128; i += 5) {
1540
+ ASSERT_OK(Put("key_" + std::to_string(i), "val_l0_" + std::to_string(i)));
1541
+ num_keys++;
1542
+ if (num_keys == 8) {
1543
+ ASSERT_OK(Flush());
1544
+ num_keys = 0;
1545
+ }
1546
+ }
1547
+ if (num_keys > 0) {
1548
+ ASSERT_OK(Flush());
1549
+ num_keys = 0;
1550
+ }
1551
+ ASSERT_EQ(0, num_keys);
1552
+
1553
+ for (int i = 0; i < 128; i += 9) {
1554
+ ASSERT_OK(Put("key_" + std::to_string(i), "val_mem_" + std::to_string(i)));
1555
+ }
1556
+
1557
+ std::vector<std::string> keys;
1558
+ std::vector<std::string> values;
1559
+
1560
+ for (int i = 64; i < 80; ++i) {
1561
+ keys.push_back("key_" + std::to_string(i));
1562
+ }
1563
+
1564
+ values = MultiGet(keys, nullptr);
1565
+ ASSERT_EQ(values.size(), 16);
1566
+ for (unsigned int j = 0; j < values.size(); ++j) {
1567
+ int key = j + 64;
1568
+ if (key % 9 == 0) {
1569
+ ASSERT_EQ(values[j], "val_mem_" + std::to_string(key));
1570
+ } else if (key % 5 == 0) {
1571
+ ASSERT_EQ(values[j], "val_l0_" + std::to_string(key));
1572
+ } else if (key % 3 == 0) {
1573
+ ASSERT_EQ(values[j], "val_l1_" + std::to_string(key));
1574
+ } else {
1575
+ ASSERT_EQ(values[j], "val_l2_" + std::to_string(key));
1576
+ }
1577
+ }
1578
+ }
1579
+
1580
+ TEST_F(DBBasicTest, MultiGetBatchedMultiLevelMerge) {
1581
+ Options options = CurrentOptions();
1582
+ options.disable_auto_compactions = true;
1583
+ options.merge_operator = MergeOperators::CreateStringAppendOperator();
1584
+ BlockBasedTableOptions bbto;
1585
+ bbto.filter_policy.reset(NewBloomFilterPolicy(10, false));
1586
+ options.table_factory.reset(NewBlockBasedTableFactory(bbto));
1587
+ Reopen(options);
1588
+ int num_keys = 0;
1589
+
1590
+ for (int i = 0; i < 128; ++i) {
1591
+ ASSERT_OK(Put("key_" + std::to_string(i), "val_l2_" + std::to_string(i)));
1592
+ num_keys++;
1593
+ if (num_keys == 8) {
1594
+ ASSERT_OK(Flush());
1595
+ num_keys = 0;
1596
+ }
1597
+ }
1598
+ if (num_keys > 0) {
1599
+ ASSERT_OK(Flush());
1600
+ num_keys = 0;
1601
+ }
1602
+ MoveFilesToLevel(2);
1603
+
1604
+ for (int i = 0; i < 128; i += 3) {
1605
+ ASSERT_OK(Merge("key_" + std::to_string(i), "val_l1_" + std::to_string(i)));
1606
+ num_keys++;
1607
+ if (num_keys == 8) {
1608
+ ASSERT_OK(Flush());
1609
+ num_keys = 0;
1610
+ }
1611
+ }
1612
+ if (num_keys > 0) {
1613
+ ASSERT_OK(Flush());
1614
+ num_keys = 0;
1615
+ }
1616
+ MoveFilesToLevel(1);
1617
+
1618
+ for (int i = 0; i < 128; i += 5) {
1619
+ ASSERT_OK(Merge("key_" + std::to_string(i), "val_l0_" + std::to_string(i)));
1620
+ num_keys++;
1621
+ if (num_keys == 8) {
1622
+ ASSERT_OK(Flush());
1623
+ num_keys = 0;
1624
+ }
1625
+ }
1626
+ if (num_keys > 0) {
1627
+ ASSERT_OK(Flush());
1628
+ num_keys = 0;
1629
+ }
1630
+ ASSERT_EQ(0, num_keys);
1631
+
1632
+ for (int i = 0; i < 128; i += 9) {
1633
+ ASSERT_OK(
1634
+ Merge("key_" + std::to_string(i), "val_mem_" + std::to_string(i)));
1635
+ }
1636
+
1637
+ std::vector<std::string> keys;
1638
+ std::vector<std::string> values;
1639
+
1640
+ for (int i = 32; i < 80; ++i) {
1641
+ keys.push_back("key_" + std::to_string(i));
1642
+ }
1643
+
1644
+ values = MultiGet(keys, nullptr);
1645
+ ASSERT_EQ(values.size(), keys.size());
1646
+ for (unsigned int j = 0; j < 48; ++j) {
1647
+ int key = j + 32;
1648
+ std::string value;
1649
+ value.append("val_l2_" + std::to_string(key));
1650
+ if (key % 3 == 0) {
1651
+ value.append(",");
1652
+ value.append("val_l1_" + std::to_string(key));
1653
+ }
1654
+ if (key % 5 == 0) {
1655
+ value.append(",");
1656
+ value.append("val_l0_" + std::to_string(key));
1657
+ }
1658
+ if (key % 9 == 0) {
1659
+ value.append(",");
1660
+ value.append("val_mem_" + std::to_string(key));
1661
+ }
1662
+ ASSERT_EQ(values[j], value);
1663
+ }
1664
+ }
1665
+
1666
+ TEST_F(DBBasicTest, MultiGetBatchedValueSizeInMemory) {
1667
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
1668
+ SetPerfLevel(kEnableCount);
1669
+ ASSERT_OK(Put(1, "k1", "v_1"));
1670
+ ASSERT_OK(Put(1, "k2", "v_2"));
1671
+ ASSERT_OK(Put(1, "k3", "v_3"));
1672
+ ASSERT_OK(Put(1, "k4", "v_4"));
1673
+ ASSERT_OK(Put(1, "k5", "v_5"));
1674
+ ASSERT_OK(Put(1, "k6", "v_6"));
1675
+ std::vector<Slice> keys = {"k1", "k2", "k3", "k4", "k5", "k6"};
1676
+ std::vector<PinnableSlice> values(keys.size());
1677
+ std::vector<Status> s(keys.size());
1678
+ std::vector<ColumnFamilyHandle*> cfs(keys.size(), handles_[1]);
1679
+
1680
+ get_perf_context()->Reset();
1681
+ ReadOptions ro;
1682
+ ro.value_size_soft_limit = 11;
1683
+ db_->MultiGet(ro, handles_[1], keys.size(), keys.data(), values.data(),
1684
+ s.data(), false);
1685
+
1686
+ ASSERT_EQ(values.size(), keys.size());
1687
+ for (unsigned int i = 0; i < 4; i++) {
1688
+ ASSERT_EQ(std::string(values[i].data(), values[i].size()),
1689
+ "v_" + std::to_string(i + 1));
1690
+ }
1691
+
1692
+ for (unsigned int i = 4; i < 6; i++) {
1693
+ ASSERT_TRUE(s[i].IsAborted());
1694
+ }
1695
+
1696
+ ASSERT_EQ(12, (int)get_perf_context()->multiget_read_bytes);
1697
+ SetPerfLevel(kDisable);
1698
+ }
1699
+
1700
+ TEST_F(DBBasicTest, MultiGetBatchedValueSize) {
1701
+ do {
1702
+ CreateAndReopenWithCF({"pikachu"}, CurrentOptions());
1703
+ SetPerfLevel(kEnableCount);
1704
+
1705
+ ASSERT_OK(Put(1, "k6", "v6"));
1706
+ ASSERT_OK(Put(1, "k7", "v7_"));
1707
+ ASSERT_OK(Put(1, "k3", "v3_"));
1708
+ ASSERT_OK(Put(1, "k4", "v4"));
1709
+ ASSERT_OK(Flush(1));
1710
+ ASSERT_OK(Delete(1, "k4"));
1711
+ ASSERT_OK(Put(1, "k11", "v11"));
1712
+ ASSERT_OK(Delete(1, "no_key"));
1713
+ ASSERT_OK(Put(1, "k8", "v8_"));
1714
+ ASSERT_OK(Put(1, "k13", "v13"));
1715
+ ASSERT_OK(Put(1, "k14", "v14"));
1716
+ ASSERT_OK(Put(1, "k15", "v15"));
1717
+ ASSERT_OK(Put(1, "k16", "v16"));
1718
+ ASSERT_OK(Put(1, "k17", "v17"));
1719
+ ASSERT_OK(Flush(1));
1720
+
1721
+ ASSERT_OK(Put(1, "k1", "v1_"));
1722
+ ASSERT_OK(Put(1, "k2", "v2_"));
1723
+ ASSERT_OK(Put(1, "k5", "v5_"));
1724
+ ASSERT_OK(Put(1, "k9", "v9_"));
1725
+ ASSERT_OK(Put(1, "k10", "v10"));
1726
+ ASSERT_OK(Delete(1, "k2"));
1727
+ ASSERT_OK(Delete(1, "k6"));
1728
+
1729
+ get_perf_context()->Reset();
1730
+
1731
+ std::vector<Slice> keys({"k1", "k10", "k11", "k12", "k13", "k14", "k15",
1732
+ "k16", "k17", "k2", "k3", "k4", "k5", "k6", "k7",
1733
+ "k8", "k9", "no_key"});
1734
+ std::vector<PinnableSlice> values(keys.size());
1735
+ std::vector<ColumnFamilyHandle*> cfs(keys.size(), handles_[1]);
1736
+ std::vector<Status> s(keys.size());
1737
+
1738
+ ReadOptions ro;
1739
+ ro.value_size_soft_limit = 20;
1740
+ db_->MultiGet(ro, handles_[1], keys.size(), keys.data(), values.data(),
1741
+ s.data(), false);
1742
+
1743
+ ASSERT_EQ(values.size(), keys.size());
1744
+
1745
+ // In memory keys
1746
+ ASSERT_EQ(std::string(values[0].data(), values[0].size()), "v1_");
1747
+ ASSERT_EQ(std::string(values[1].data(), values[1].size()), "v10");
1748
+ ASSERT_TRUE(s[9].IsNotFound()); // k2
1749
+ ASSERT_EQ(std::string(values[12].data(), values[12].size()), "v5_");
1750
+ ASSERT_TRUE(s[13].IsNotFound()); // k6
1751
+ ASSERT_EQ(std::string(values[16].data(), values[16].size()), "v9_");
1752
+
1753
+ // In sst files
1754
+ ASSERT_EQ(std::string(values[2].data(), values[1].size()), "v11");
1755
+ ASSERT_EQ(std::string(values[4].data(), values[4].size()), "v13");
1756
+ ASSERT_EQ(std::string(values[5].data(), values[5].size()), "v14");
1757
+
1758
+ // Remaining aborted after value_size exceeds.
1759
+ ASSERT_TRUE(s[3].IsAborted());
1760
+ ASSERT_TRUE(s[6].IsAborted());
1761
+ ASSERT_TRUE(s[7].IsAborted());
1762
+ ASSERT_TRUE(s[8].IsAborted());
1763
+ ASSERT_TRUE(s[10].IsAborted());
1764
+ ASSERT_TRUE(s[11].IsAborted());
1765
+ ASSERT_TRUE(s[14].IsAborted());
1766
+ ASSERT_TRUE(s[15].IsAborted());
1767
+ ASSERT_TRUE(s[17].IsAborted());
1768
+
1769
+ // 6 kv pairs * 3 bytes per value (i.e. 18)
1770
+ ASSERT_EQ(21, (int)get_perf_context()->multiget_read_bytes);
1771
+ SetPerfLevel(kDisable);
1772
+ } while (ChangeCompactOptions());
1773
+ }
1774
+
1775
+ TEST_F(DBBasicTest, MultiGetBatchedValueSizeMultiLevelMerge) {
1776
+ Options options = CurrentOptions();
1777
+ options.disable_auto_compactions = true;
1778
+ options.merge_operator = MergeOperators::CreateStringAppendOperator();
1779
+ BlockBasedTableOptions bbto;
1780
+ bbto.filter_policy.reset(NewBloomFilterPolicy(10, false));
1781
+ options.table_factory.reset(NewBlockBasedTableFactory(bbto));
1782
+ Reopen(options);
1783
+ int num_keys = 0;
1784
+
1785
+ for (int i = 0; i < 64; ++i) {
1786
+ ASSERT_OK(Put("key_" + std::to_string(i), "val_l2_" + std::to_string(i)));
1787
+ num_keys++;
1788
+ if (num_keys == 8) {
1789
+ ASSERT_OK(Flush());
1790
+ num_keys = 0;
1791
+ }
1792
+ }
1793
+ if (num_keys > 0) {
1794
+ ASSERT_OK(Flush());
1795
+ num_keys = 0;
1796
+ }
1797
+ MoveFilesToLevel(2);
1798
+
1799
+ for (int i = 0; i < 64; i += 3) {
1800
+ ASSERT_OK(Merge("key_" + std::to_string(i), "val_l1_" + std::to_string(i)));
1801
+ num_keys++;
1802
+ if (num_keys == 8) {
1803
+ ASSERT_OK(Flush());
1804
+ num_keys = 0;
1805
+ }
1806
+ }
1807
+ if (num_keys > 0) {
1808
+ ASSERT_OK(Flush());
1809
+ num_keys = 0;
1810
+ }
1811
+ MoveFilesToLevel(1);
1812
+
1813
+ for (int i = 0; i < 64; i += 5) {
1814
+ ASSERT_OK(Merge("key_" + std::to_string(i), "val_l0_" + std::to_string(i)));
1815
+ num_keys++;
1816
+ if (num_keys == 8) {
1817
+ ASSERT_OK(Flush());
1818
+ num_keys = 0;
1819
+ }
1820
+ }
1821
+ if (num_keys > 0) {
1822
+ ASSERT_OK(Flush());
1823
+ num_keys = 0;
1824
+ }
1825
+ ASSERT_EQ(0, num_keys);
1826
+
1827
+ for (int i = 0; i < 64; i += 9) {
1828
+ ASSERT_OK(
1829
+ Merge("key_" + std::to_string(i), "val_mem_" + std::to_string(i)));
1830
+ }
1831
+
1832
+ std::vector<std::string> keys_str;
1833
+ for (int i = 10; i < 50; ++i) {
1834
+ keys_str.push_back("key_" + std::to_string(i));
1835
+ }
1836
+
1837
+ std::vector<Slice> keys(keys_str.size());
1838
+ for (int i = 0; i < 40; i++) {
1839
+ keys[i] = Slice(keys_str[i]);
1840
+ }
1841
+
1842
+ std::vector<PinnableSlice> values(keys_str.size());
1843
+ std::vector<Status> statuses(keys_str.size());
1844
+ ReadOptions read_options;
1845
+ read_options.verify_checksums = true;
1846
+ read_options.value_size_soft_limit = 380;
1847
+ db_->MultiGet(read_options, dbfull()->DefaultColumnFamily(), keys.size(),
1848
+ keys.data(), values.data(), statuses.data());
1849
+
1850
+ ASSERT_EQ(values.size(), keys.size());
1851
+
1852
+ uint64_t curr_value_size = 0;
1853
+ for (unsigned int j = 0; j < 26; ++j) {
1854
+ int key = j + 10;
1855
+ std::string value;
1856
+ value.append("val_l2_" + std::to_string(key));
1857
+ if (key % 3 == 0) {
1858
+ value.append(",");
1859
+ value.append("val_l1_" + std::to_string(key));
1860
+ }
1861
+ if (key % 5 == 0) {
1862
+ value.append(",");
1863
+ value.append("val_l0_" + std::to_string(key));
1864
+ }
1865
+ if (key % 9 == 0) {
1866
+ value.append(",");
1867
+ value.append("val_mem_" + std::to_string(key));
1868
+ }
1869
+ curr_value_size += value.size();
1870
+ ASSERT_EQ(values[j], value);
1871
+ ASSERT_OK(statuses[j]);
1872
+ }
1873
+ // ASSERT_TRUE(curr_value_size <= read_options.value_size_hard_limit);
1874
+
1875
+ // All remaning keys status is set Status::Abort
1876
+ for (unsigned int j = 26; j < 40; j++) {
1877
+ ASSERT_TRUE(statuses[j].IsAborted());
1878
+ }
1879
+ }
1880
+
1881
+ TEST_F(DBBasicTest, MultiGetStats) {
1882
+ Options options;
1883
+ options.create_if_missing = true;
1884
+ options.disable_auto_compactions = true;
1885
+ options.env = env_;
1886
+ options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics();
1887
+ BlockBasedTableOptions table_options;
1888
+ table_options.block_size = 1;
1889
+ table_options.index_type =
1890
+ BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
1891
+ table_options.partition_filters = true;
1892
+ table_options.no_block_cache = true;
1893
+ table_options.cache_index_and_filter_blocks = false;
1894
+ table_options.filter_policy.reset(NewBloomFilterPolicy(10, false));
1895
+ options.table_factory.reset(NewBlockBasedTableFactory(table_options));
1896
+ CreateAndReopenWithCF({"pikachu"}, options);
1897
+
1898
+ int total_keys = 2000;
1899
+ std::vector<std::string> keys_str(total_keys);
1900
+ std::vector<Slice> keys(total_keys);
1901
+ std::vector<PinnableSlice> values(total_keys);
1902
+ std::vector<Status> s(total_keys);
1903
+ ReadOptions read_opts;
1904
+
1905
+ Random rnd(309);
1906
+ // Create Multiple SST files at multiple levels.
1907
+ for (int i = 0; i < 500; ++i) {
1908
+ keys_str[i] = "k" + std::to_string(i);
1909
+ keys[i] = Slice(keys_str[i]);
1910
+ ASSERT_OK(Put(1, "k" + std::to_string(i), rnd.RandomString(1000)));
1911
+ if (i % 100 == 0) {
1912
+ ASSERT_OK(Flush(1));
1913
+ }
1914
+ }
1915
+ ASSERT_OK(Flush(1));
1916
+ MoveFilesToLevel(2, 1);
1917
+
1918
+ for (int i = 501; i < 1000; ++i) {
1919
+ keys_str[i] = "k" + std::to_string(i);
1920
+ keys[i] = Slice(keys_str[i]);
1921
+ ASSERT_OK(Put(1, "k" + std::to_string(i), rnd.RandomString(1000)));
1922
+ if (i % 100 == 0) {
1923
+ ASSERT_OK(Flush(1));
1924
+ }
1925
+ }
1926
+
1927
+ ASSERT_OK(Flush(1));
1928
+ MoveFilesToLevel(2, 1);
1929
+
1930
+ for (int i = 1001; i < total_keys; ++i) {
1931
+ keys_str[i] = "k" + std::to_string(i);
1932
+ keys[i] = Slice(keys_str[i]);
1933
+ ASSERT_OK(Put(1, "k" + std::to_string(i), rnd.RandomString(1000)));
1934
+ if (i % 100 == 0) {
1935
+ ASSERT_OK(Flush(1));
1936
+ }
1937
+ }
1938
+ ASSERT_OK(Flush(1));
1939
+ Close();
1940
+
1941
+ ReopenWithColumnFamilies({"default", "pikachu"}, options);
1942
+ ASSERT_OK(options.statistics->Reset());
1943
+
1944
+ db_->MultiGet(read_opts, handles_[1], total_keys, keys.data(), values.data(),
1945
+ s.data(), false);
1946
+
1947
+ ASSERT_EQ(values.size(), total_keys);
1948
+ HistogramData hist_data_blocks;
1949
+ HistogramData hist_index_and_filter_blocks;
1950
+ HistogramData hist_sst;
1951
+
1952
+ options.statistics->histogramData(NUM_DATA_BLOCKS_READ_PER_LEVEL,
1953
+ &hist_data_blocks);
1954
+ options.statistics->histogramData(NUM_INDEX_AND_FILTER_BLOCKS_READ_PER_LEVEL,
1955
+ &hist_index_and_filter_blocks);
1956
+ options.statistics->histogramData(NUM_SST_READ_PER_LEVEL, &hist_sst);
1957
+
1958
+ // Maximum number of blocks read from a file system in a level.
1959
+ ASSERT_GT(hist_data_blocks.max, 0);
1960
+ ASSERT_GT(hist_index_and_filter_blocks.max, 0);
1961
+ // Maximum number of sst files read from file system in a level.
1962
+ ASSERT_GT(hist_sst.max, 0);
1963
+
1964
+ // Minimun number of blocks read in a level.
1965
+ ASSERT_EQ(hist_data_blocks.min, 3);
1966
+ ASSERT_GT(hist_index_and_filter_blocks.min, 0);
1967
+ // Minimun number of sst files read in a level.
1968
+ ASSERT_GT(hist_sst.max, 0);
1969
+ }
1970
+
1971
+ // Test class for batched MultiGet with prefix extractor
1972
+ // Param bool - If true, use partitioned filters
1973
+ // If false, use full filter block
1974
+ class MultiGetPrefixExtractorTest : public DBBasicTest,
1975
+ public ::testing::WithParamInterface<bool> {
1976
+ };
1977
+
1978
+ TEST_P(MultiGetPrefixExtractorTest, Batched) {
1979
+ Options options = CurrentOptions();
1980
+ options.prefix_extractor.reset(NewFixedPrefixTransform(2));
1981
+ options.memtable_prefix_bloom_size_ratio = 10;
1982
+ BlockBasedTableOptions bbto;
1983
+ if (GetParam()) {
1984
+ bbto.index_type = BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
1985
+ bbto.partition_filters = true;
1986
+ }
1987
+ bbto.filter_policy.reset(NewBloomFilterPolicy(10, false));
1988
+ bbto.whole_key_filtering = false;
1989
+ bbto.cache_index_and_filter_blocks = false;
1990
+ options.table_factory.reset(NewBlockBasedTableFactory(bbto));
1991
+ Reopen(options);
1992
+
1993
+ SetPerfLevel(kEnableCount);
1994
+ get_perf_context()->Reset();
1995
+
1996
+ // First key is not in the prefix_extractor domain
1997
+ ASSERT_OK(Put("k", "v0"));
1998
+ ASSERT_OK(Put("kk1", "v1"));
1999
+ ASSERT_OK(Put("kk2", "v2"));
2000
+ ASSERT_OK(Put("kk3", "v3"));
2001
+ ASSERT_OK(Put("kk4", "v4"));
2002
+ std::vector<std::string> mem_keys(
2003
+ {"k", "kk1", "kk2", "kk3", "kk4", "rofl", "lmho"});
2004
+ std::vector<std::string> inmem_values;
2005
+ inmem_values = MultiGet(mem_keys, nullptr);
2006
+ ASSERT_EQ(inmem_values[0], "v0");
2007
+ ASSERT_EQ(inmem_values[1], "v1");
2008
+ ASSERT_EQ(inmem_values[2], "v2");
2009
+ ASSERT_EQ(inmem_values[3], "v3");
2010
+ ASSERT_EQ(inmem_values[4], "v4");
2011
+ ASSERT_EQ(get_perf_context()->bloom_memtable_miss_count, 2);
2012
+ ASSERT_EQ(get_perf_context()->bloom_memtable_hit_count, 5);
2013
+ ASSERT_OK(Flush());
2014
+
2015
+ std::vector<std::string> keys({"k", "kk1", "kk2", "kk3", "kk4"});
2016
+ std::vector<std::string> values;
2017
+ get_perf_context()->Reset();
2018
+ values = MultiGet(keys, nullptr);
2019
+ ASSERT_EQ(values[0], "v0");
2020
+ ASSERT_EQ(values[1], "v1");
2021
+ ASSERT_EQ(values[2], "v2");
2022
+ ASSERT_EQ(values[3], "v3");
2023
+ ASSERT_EQ(values[4], "v4");
2024
+ // Filter hits for 4 in-domain keys
2025
+ ASSERT_EQ(get_perf_context()->bloom_sst_hit_count, 4);
2026
+ }
2027
+
2028
+ INSTANTIATE_TEST_CASE_P(MultiGetPrefix, MultiGetPrefixExtractorTest,
2029
+ ::testing::Bool());
2030
+
2031
+ #ifndef ROCKSDB_LITE
2032
+ class DBMultiGetRowCacheTest : public DBBasicTest,
2033
+ public ::testing::WithParamInterface<bool> {};
2034
+
2035
+ TEST_P(DBMultiGetRowCacheTest, MultiGetBatched) {
2036
+ do {
2037
+ option_config_ = kRowCache;
2038
+ Options options = CurrentOptions();
2039
+ options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics();
2040
+ CreateAndReopenWithCF({"pikachu"}, options);
2041
+ SetPerfLevel(kEnableCount);
2042
+ ASSERT_OK(Put(1, "k1", "v1"));
2043
+ ASSERT_OK(Put(1, "k2", "v2"));
2044
+ ASSERT_OK(Put(1, "k3", "v3"));
2045
+ ASSERT_OK(Put(1, "k4", "v4"));
2046
+ ASSERT_OK(Flush(1));
2047
+ ASSERT_OK(Put(1, "k5", "v5"));
2048
+ const Snapshot* snap1 = dbfull()->GetSnapshot();
2049
+ ASSERT_OK(Delete(1, "k4"));
2050
+ ASSERT_OK(Flush(1));
2051
+ const Snapshot* snap2 = dbfull()->GetSnapshot();
2052
+
2053
+ get_perf_context()->Reset();
2054
+
2055
+ std::vector<Slice> keys({"no_key", "k5", "k4", "k3", "k1"});
2056
+ std::vector<PinnableSlice> values(keys.size());
2057
+ std::vector<ColumnFamilyHandle*> cfs(keys.size(), handles_[1]);
2058
+ std::vector<Status> s(keys.size());
2059
+
2060
+ ReadOptions ro;
2061
+ bool use_snapshots = GetParam();
2062
+ if (use_snapshots) {
2063
+ ro.snapshot = snap2;
2064
+ }
2065
+ db_->MultiGet(ro, handles_[1], keys.size(), keys.data(), values.data(),
2066
+ s.data(), false);
2067
+
2068
+ ASSERT_EQ(values.size(), keys.size());
2069
+ ASSERT_EQ(std::string(values[4].data(), values[4].size()), "v1");
2070
+ ASSERT_EQ(std::string(values[3].data(), values[3].size()), "v3");
2071
+ ASSERT_EQ(std::string(values[1].data(), values[1].size()), "v5");
2072
+ // four kv pairs * two bytes per value
2073
+ ASSERT_EQ(6, (int)get_perf_context()->multiget_read_bytes);
2074
+
2075
+ ASSERT_TRUE(s[0].IsNotFound());
2076
+ ASSERT_OK(s[1]);
2077
+ ASSERT_TRUE(s[2].IsNotFound());
2078
+ ASSERT_OK(s[3]);
2079
+ ASSERT_OK(s[4]);
2080
+
2081
+ // Call MultiGet() again with some intersection with the previous set of
2082
+ // keys. Those should already be in the row cache.
2083
+ keys.assign({"no_key", "k5", "k3", "k2"});
2084
+ for (size_t i = 0; i < keys.size(); ++i) {
2085
+ values[i].Reset();
2086
+ s[i] = Status::OK();
2087
+ }
2088
+ get_perf_context()->Reset();
2089
+
2090
+ if (use_snapshots) {
2091
+ ro.snapshot = snap1;
2092
+ }
2093
+ db_->MultiGet(ReadOptions(), handles_[1], keys.size(), keys.data(),
2094
+ values.data(), s.data(), false);
2095
+
2096
+ ASSERT_EQ(std::string(values[3].data(), values[3].size()), "v2");
2097
+ ASSERT_EQ(std::string(values[2].data(), values[2].size()), "v3");
2098
+ ASSERT_EQ(std::string(values[1].data(), values[1].size()), "v5");
2099
+ // four kv pairs * two bytes per value
2100
+ ASSERT_EQ(6, (int)get_perf_context()->multiget_read_bytes);
2101
+
2102
+ ASSERT_TRUE(s[0].IsNotFound());
2103
+ ASSERT_OK(s[1]);
2104
+ ASSERT_OK(s[2]);
2105
+ ASSERT_OK(s[3]);
2106
+ if (use_snapshots) {
2107
+ // Only reads from the first SST file would have been cached, since
2108
+ // snapshot seq no is > fd.largest_seqno
2109
+ ASSERT_EQ(1, TestGetTickerCount(options, ROW_CACHE_HIT));
2110
+ } else {
2111
+ ASSERT_EQ(2, TestGetTickerCount(options, ROW_CACHE_HIT));
2112
+ }
2113
+
2114
+ SetPerfLevel(kDisable);
2115
+ dbfull()->ReleaseSnapshot(snap1);
2116
+ dbfull()->ReleaseSnapshot(snap2);
2117
+ } while (ChangeCompactOptions());
2118
+ }
2119
+
2120
+ INSTANTIATE_TEST_CASE_P(DBMultiGetRowCacheTest, DBMultiGetRowCacheTest,
2121
+ testing::Values(true, false));
2122
+
2123
+ TEST_F(DBBasicTest, GetAllKeyVersions) {
2124
+ Options options = CurrentOptions();
2125
+ options.env = env_;
2126
+ options.create_if_missing = true;
2127
+ options.disable_auto_compactions = true;
2128
+ CreateAndReopenWithCF({"pikachu"}, options);
2129
+ ASSERT_EQ(2, handles_.size());
2130
+ const size_t kNumInserts = 4;
2131
+ const size_t kNumDeletes = 4;
2132
+ const size_t kNumUpdates = 4;
2133
+
2134
+ // Check default column family
2135
+ for (size_t i = 0; i != kNumInserts; ++i) {
2136
+ ASSERT_OK(Put(std::to_string(i), "value"));
2137
+ }
2138
+ for (size_t i = 0; i != kNumUpdates; ++i) {
2139
+ ASSERT_OK(Put(std::to_string(i), "value1"));
2140
+ }
2141
+ for (size_t i = 0; i != kNumDeletes; ++i) {
2142
+ ASSERT_OK(Delete(std::to_string(i)));
2143
+ }
2144
+ std::vector<KeyVersion> key_versions;
2145
+ ASSERT_OK(ROCKSDB_NAMESPACE::GetAllKeyVersions(
2146
+ db_, Slice(), Slice(), std::numeric_limits<size_t>::max(),
2147
+ &key_versions));
2148
+ ASSERT_EQ(kNumInserts + kNumDeletes + kNumUpdates, key_versions.size());
2149
+ ASSERT_OK(ROCKSDB_NAMESPACE::GetAllKeyVersions(
2150
+ db_, handles_[0], Slice(), Slice(), std::numeric_limits<size_t>::max(),
2151
+ &key_versions));
2152
+ ASSERT_EQ(kNumInserts + kNumDeletes + kNumUpdates, key_versions.size());
2153
+
2154
+ // Check non-default column family
2155
+ for (size_t i = 0; i + 1 != kNumInserts; ++i) {
2156
+ ASSERT_OK(Put(1, std::to_string(i), "value"));
2157
+ }
2158
+ for (size_t i = 0; i + 1 != kNumUpdates; ++i) {
2159
+ ASSERT_OK(Put(1, std::to_string(i), "value1"));
2160
+ }
2161
+ for (size_t i = 0; i + 1 != kNumDeletes; ++i) {
2162
+ ASSERT_OK(Delete(1, std::to_string(i)));
2163
+ }
2164
+ ASSERT_OK(ROCKSDB_NAMESPACE::GetAllKeyVersions(
2165
+ db_, handles_[1], Slice(), Slice(), std::numeric_limits<size_t>::max(),
2166
+ &key_versions));
2167
+ ASSERT_EQ(kNumInserts + kNumDeletes + kNumUpdates - 3, key_versions.size());
2168
+ }
2169
+ #endif // !ROCKSDB_LITE
2170
+
2171
+ TEST_F(DBBasicTest, MultiGetIOBufferOverrun) {
2172
+ Options options = CurrentOptions();
2173
+ Random rnd(301);
2174
+ BlockBasedTableOptions table_options;
2175
+ table_options.pin_l0_filter_and_index_blocks_in_cache = true;
2176
+ table_options.block_size = 16 * 1024;
2177
+ ASSERT_TRUE(table_options.block_size >
2178
+ BlockBasedTable::kMultiGetReadStackBufSize);
2179
+ options.table_factory.reset(NewBlockBasedTableFactory(table_options));
2180
+ Reopen(options);
2181
+
2182
+ std::string zero_str(128, '\0');
2183
+ for (int i = 0; i < 100; ++i) {
2184
+ // Make the value compressible. A purely random string doesn't compress
2185
+ // and the resultant data block will not be compressed
2186
+ std::string value(rnd.RandomString(128) + zero_str);
2187
+ assert(Put(Key(i), value) == Status::OK());
2188
+ }
2189
+ ASSERT_OK(Flush());
2190
+
2191
+ std::vector<std::string> key_data(10);
2192
+ std::vector<Slice> keys;
2193
+ // We cannot resize a PinnableSlice vector, so just set initial size to
2194
+ // largest we think we will need
2195
+ std::vector<PinnableSlice> values(10);
2196
+ std::vector<Status> statuses;
2197
+ ReadOptions ro;
2198
+
2199
+ // Warm up the cache first
2200
+ key_data.emplace_back(Key(0));
2201
+ keys.emplace_back(Slice(key_data.back()));
2202
+ key_data.emplace_back(Key(50));
2203
+ keys.emplace_back(Slice(key_data.back()));
2204
+ statuses.resize(keys.size());
2205
+
2206
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
2207
+ keys.data(), values.data(), statuses.data(), true);
2208
+ }
2209
+
2210
+ TEST_F(DBBasicTest, IncrementalRecoveryNoCorrupt) {
2211
+ Options options = CurrentOptions();
2212
+ DestroyAndReopen(options);
2213
+ CreateAndReopenWithCF({"pikachu", "eevee"}, options);
2214
+ size_t num_cfs = handles_.size();
2215
+ ASSERT_EQ(3, num_cfs);
2216
+ WriteOptions write_opts;
2217
+ write_opts.disableWAL = true;
2218
+ for (size_t cf = 0; cf != num_cfs; ++cf) {
2219
+ for (size_t i = 0; i != 10000; ++i) {
2220
+ std::string key_str = Key(static_cast<int>(i));
2221
+ std::string value_str = std::to_string(cf) + "_" + std::to_string(i);
2222
+
2223
+ ASSERT_OK(Put(static_cast<int>(cf), key_str, value_str));
2224
+ if (0 == (i % 1000)) {
2225
+ ASSERT_OK(Flush(static_cast<int>(cf)));
2226
+ }
2227
+ }
2228
+ }
2229
+ for (size_t cf = 0; cf != num_cfs; ++cf) {
2230
+ ASSERT_OK(Flush(static_cast<int>(cf)));
2231
+ }
2232
+ Close();
2233
+ options.best_efforts_recovery = true;
2234
+ ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu", "eevee"},
2235
+ options);
2236
+ num_cfs = handles_.size();
2237
+ ASSERT_EQ(3, num_cfs);
2238
+ for (size_t cf = 0; cf != num_cfs; ++cf) {
2239
+ for (int i = 0; i != 10000; ++i) {
2240
+ std::string key_str = Key(static_cast<int>(i));
2241
+ std::string expected_value_str =
2242
+ std::to_string(cf) + "_" + std::to_string(i);
2243
+ ASSERT_EQ(expected_value_str, Get(static_cast<int>(cf), key_str));
2244
+ }
2245
+ }
2246
+ }
2247
+
2248
+ TEST_F(DBBasicTest, BestEffortsRecoveryWithVersionBuildingFailure) {
2249
+ Options options = CurrentOptions();
2250
+ DestroyAndReopen(options);
2251
+ ASSERT_OK(Put("foo", "value"));
2252
+ ASSERT_OK(Flush());
2253
+ SyncPoint::GetInstance()->DisableProcessing();
2254
+ SyncPoint::GetInstance()->ClearAllCallBacks();
2255
+ SyncPoint::GetInstance()->SetCallBack(
2256
+ "VersionBuilder::CheckConsistencyBeforeReturn", [&](void* arg) {
2257
+ ASSERT_NE(nullptr, arg);
2258
+ *(reinterpret_cast<Status*>(arg)) =
2259
+ Status::Corruption("Inject corruption");
2260
+ });
2261
+ SyncPoint::GetInstance()->EnableProcessing();
2262
+
2263
+ options.best_efforts_recovery = true;
2264
+ Status s = TryReopen(options);
2265
+ ASSERT_TRUE(s.IsCorruption());
2266
+ SyncPoint::GetInstance()->DisableProcessing();
2267
+ SyncPoint::GetInstance()->ClearAllCallBacks();
2268
+ }
2269
+
2270
+ #ifndef ROCKSDB_LITE
2271
+ namespace {
2272
+ class TableFileListener : public EventListener {
2273
+ public:
2274
+ void OnTableFileCreated(const TableFileCreationInfo& info) override {
2275
+ InstrumentedMutexLock lock(&mutex_);
2276
+ cf_to_paths_[info.cf_name].push_back(info.file_path);
2277
+ }
2278
+ std::vector<std::string>& GetFiles(const std::string& cf_name) {
2279
+ InstrumentedMutexLock lock(&mutex_);
2280
+ return cf_to_paths_[cf_name];
2281
+ }
2282
+
2283
+ private:
2284
+ InstrumentedMutex mutex_;
2285
+ std::unordered_map<std::string, std::vector<std::string>> cf_to_paths_;
2286
+ };
2287
+ } // namespace
2288
+
2289
+ TEST_F(DBBasicTest, LastSstFileNotInManifest) {
2290
+ // If the last sst file is not tracked in MANIFEST,
2291
+ // or the VersionEdit for the last sst file is not synced,
2292
+ // on recovery, the last sst file should be deleted,
2293
+ // and new sst files shouldn't reuse its file number.
2294
+ Options options = CurrentOptions();
2295
+ DestroyAndReopen(options);
2296
+ Close();
2297
+
2298
+ // Manually add a sst file.
2299
+ constexpr uint64_t kSstFileNumber = 100;
2300
+ const std::string kSstFile = MakeTableFileName(dbname_, kSstFileNumber);
2301
+ ASSERT_OK(WriteStringToFile(env_, /* data = */ "bad sst file content",
2302
+ /* fname = */ kSstFile,
2303
+ /* should_sync = */ true));
2304
+ ASSERT_OK(env_->FileExists(kSstFile));
2305
+
2306
+ TableFileListener* listener = new TableFileListener();
2307
+ options.listeners.emplace_back(listener);
2308
+ Reopen(options);
2309
+ // kSstFile should already be deleted.
2310
+ ASSERT_TRUE(env_->FileExists(kSstFile).IsNotFound());
2311
+
2312
+ ASSERT_OK(Put("k", "v"));
2313
+ ASSERT_OK(Flush());
2314
+ // New sst file should have file number > kSstFileNumber.
2315
+ std::vector<std::string>& files =
2316
+ listener->GetFiles(kDefaultColumnFamilyName);
2317
+ ASSERT_EQ(files.size(), 1);
2318
+ const std::string fname = files[0].erase(0, (dbname_ + "/").size());
2319
+ uint64_t number = 0;
2320
+ FileType type = kTableFile;
2321
+ ASSERT_TRUE(ParseFileName(fname, &number, &type));
2322
+ ASSERT_EQ(type, kTableFile);
2323
+ ASSERT_GT(number, kSstFileNumber);
2324
+ }
2325
+
2326
+ TEST_F(DBBasicTest, RecoverWithMissingFiles) {
2327
+ Options options = CurrentOptions();
2328
+ DestroyAndReopen(options);
2329
+ TableFileListener* listener = new TableFileListener();
2330
+ // Disable auto compaction to simplify SST file name tracking.
2331
+ options.disable_auto_compactions = true;
2332
+ options.listeners.emplace_back(listener);
2333
+ CreateAndReopenWithCF({"pikachu", "eevee"}, options);
2334
+ std::vector<std::string> all_cf_names = {kDefaultColumnFamilyName, "pikachu",
2335
+ "eevee"};
2336
+ size_t num_cfs = handles_.size();
2337
+ ASSERT_EQ(3, num_cfs);
2338
+ for (size_t cf = 0; cf != num_cfs; ++cf) {
2339
+ ASSERT_OK(Put(static_cast<int>(cf), "a", "0_value"));
2340
+ ASSERT_OK(Flush(static_cast<int>(cf)));
2341
+ ASSERT_OK(Put(static_cast<int>(cf), "b", "0_value"));
2342
+ ASSERT_OK(Flush(static_cast<int>(cf)));
2343
+ ASSERT_OK(Put(static_cast<int>(cf), "c", "0_value"));
2344
+ ASSERT_OK(Flush(static_cast<int>(cf)));
2345
+ }
2346
+
2347
+ // Delete and corrupt files
2348
+ for (size_t i = 0; i < all_cf_names.size(); ++i) {
2349
+ std::vector<std::string>& files = listener->GetFiles(all_cf_names[i]);
2350
+ ASSERT_EQ(3, files.size());
2351
+ std::string corrupted_data;
2352
+ ASSERT_OK(ReadFileToString(env_, files[files.size() - 1], &corrupted_data));
2353
+ ASSERT_OK(WriteStringToFile(
2354
+ env_, corrupted_data.substr(0, corrupted_data.size() - 2),
2355
+ files[files.size() - 1], /*should_sync=*/true));
2356
+ for (int j = static_cast<int>(files.size() - 2); j >= static_cast<int>(i);
2357
+ --j) {
2358
+ ASSERT_OK(env_->DeleteFile(files[j]));
2359
+ }
2360
+ }
2361
+ options.best_efforts_recovery = true;
2362
+ ReopenWithColumnFamilies(all_cf_names, options);
2363
+ // Verify data
2364
+ ReadOptions read_opts;
2365
+ read_opts.total_order_seek = true;
2366
+ {
2367
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_opts, handles_[0]));
2368
+ iter->SeekToFirst();
2369
+ ASSERT_FALSE(iter->Valid());
2370
+ ASSERT_OK(iter->status());
2371
+ iter.reset(db_->NewIterator(read_opts, handles_[1]));
2372
+ iter->SeekToFirst();
2373
+ ASSERT_TRUE(iter->Valid());
2374
+ ASSERT_EQ("a", iter->key());
2375
+ iter->Next();
2376
+ ASSERT_FALSE(iter->Valid());
2377
+ ASSERT_OK(iter->status());
2378
+ iter.reset(db_->NewIterator(read_opts, handles_[2]));
2379
+ iter->SeekToFirst();
2380
+ ASSERT_TRUE(iter->Valid());
2381
+ ASSERT_EQ("a", iter->key());
2382
+ iter->Next();
2383
+ ASSERT_TRUE(iter->Valid());
2384
+ ASSERT_EQ("b", iter->key());
2385
+ iter->Next();
2386
+ ASSERT_FALSE(iter->Valid());
2387
+ ASSERT_OK(iter->status());
2388
+ }
2389
+ }
2390
+
2391
+ TEST_F(DBBasicTest, BestEffortsRecoveryTryMultipleManifests) {
2392
+ Options options = CurrentOptions();
2393
+ options.env = env_;
2394
+ DestroyAndReopen(options);
2395
+ ASSERT_OK(Put("foo", "value0"));
2396
+ ASSERT_OK(Flush());
2397
+ Close();
2398
+ {
2399
+ // Hack by adding a new MANIFEST with high file number
2400
+ std::string garbage(10, '\0');
2401
+ ASSERT_OK(WriteStringToFile(env_, garbage, dbname_ + "/MANIFEST-001000",
2402
+ /*should_sync=*/true));
2403
+ }
2404
+ {
2405
+ // Hack by adding a corrupted SST not referenced by any MANIFEST
2406
+ std::string garbage(10, '\0');
2407
+ ASSERT_OK(WriteStringToFile(env_, garbage, dbname_ + "/001001.sst",
2408
+ /*should_sync=*/true));
2409
+ }
2410
+
2411
+ options.best_efforts_recovery = true;
2412
+
2413
+ Reopen(options);
2414
+ ASSERT_OK(Put("bar", "value"));
2415
+ }
2416
+
2417
+ TEST_F(DBBasicTest, RecoverWithNoCurrentFile) {
2418
+ Options options = CurrentOptions();
2419
+ options.env = env_;
2420
+ DestroyAndReopen(options);
2421
+ CreateAndReopenWithCF({"pikachu"}, options);
2422
+ options.best_efforts_recovery = true;
2423
+ ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu"}, options);
2424
+ ASSERT_EQ(2, handles_.size());
2425
+ ASSERT_OK(Put("foo", "value"));
2426
+ ASSERT_OK(Put(1, "bar", "value"));
2427
+ ASSERT_OK(Flush());
2428
+ ASSERT_OK(Flush(1));
2429
+ Close();
2430
+ ASSERT_OK(env_->DeleteFile(CurrentFileName(dbname_)));
2431
+ ReopenWithColumnFamilies({kDefaultColumnFamilyName, "pikachu"}, options);
2432
+ std::vector<std::string> cf_names;
2433
+ ASSERT_OK(DB::ListColumnFamilies(DBOptions(options), dbname_, &cf_names));
2434
+ ASSERT_EQ(2, cf_names.size());
2435
+ for (const auto& name : cf_names) {
2436
+ ASSERT_TRUE(name == kDefaultColumnFamilyName || name == "pikachu");
2437
+ }
2438
+ }
2439
+
2440
+ TEST_F(DBBasicTest, RecoverWithNoManifest) {
2441
+ Options options = CurrentOptions();
2442
+ options.env = env_;
2443
+ DestroyAndReopen(options);
2444
+ ASSERT_OK(Put("foo", "value"));
2445
+ ASSERT_OK(Flush());
2446
+ Close();
2447
+ {
2448
+ // Delete all MANIFEST.
2449
+ std::vector<std::string> files;
2450
+ ASSERT_OK(env_->GetChildren(dbname_, &files));
2451
+ for (const auto& file : files) {
2452
+ uint64_t number = 0;
2453
+ FileType type = kWalFile;
2454
+ if (ParseFileName(file, &number, &type) && type == kDescriptorFile) {
2455
+ ASSERT_OK(env_->DeleteFile(dbname_ + "/" + file));
2456
+ }
2457
+ }
2458
+ }
2459
+ options.best_efforts_recovery = true;
2460
+ options.create_if_missing = false;
2461
+ Status s = TryReopen(options);
2462
+ ASSERT_TRUE(s.IsInvalidArgument());
2463
+ options.create_if_missing = true;
2464
+ Reopen(options);
2465
+ // Since no MANIFEST exists, best-efforts recovery creates a new, empty db.
2466
+ ASSERT_EQ("NOT_FOUND", Get("foo"));
2467
+ }
2468
+
2469
+ TEST_F(DBBasicTest, SkipWALIfMissingTableFiles) {
2470
+ Options options = CurrentOptions();
2471
+ DestroyAndReopen(options);
2472
+ TableFileListener* listener = new TableFileListener();
2473
+ options.listeners.emplace_back(listener);
2474
+ CreateAndReopenWithCF({"pikachu"}, options);
2475
+ std::vector<std::string> kAllCfNames = {kDefaultColumnFamilyName, "pikachu"};
2476
+ size_t num_cfs = handles_.size();
2477
+ ASSERT_EQ(2, num_cfs);
2478
+ for (int cf = 0; cf < static_cast<int>(kAllCfNames.size()); ++cf) {
2479
+ ASSERT_OK(Put(cf, "a", "0_value"));
2480
+ ASSERT_OK(Flush(cf));
2481
+ ASSERT_OK(Put(cf, "b", "0_value"));
2482
+ }
2483
+ // Delete files
2484
+ for (size_t i = 0; i < kAllCfNames.size(); ++i) {
2485
+ std::vector<std::string>& files = listener->GetFiles(kAllCfNames[i]);
2486
+ ASSERT_EQ(1, files.size());
2487
+ for (int j = static_cast<int>(files.size() - 1); j >= static_cast<int>(i);
2488
+ --j) {
2489
+ ASSERT_OK(env_->DeleteFile(files[j]));
2490
+ }
2491
+ }
2492
+ options.best_efforts_recovery = true;
2493
+ ReopenWithColumnFamilies(kAllCfNames, options);
2494
+ // Verify WAL is not applied
2495
+ ReadOptions read_opts;
2496
+ read_opts.total_order_seek = true;
2497
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_opts, handles_[0]));
2498
+ iter->SeekToFirst();
2499
+ ASSERT_FALSE(iter->Valid());
2500
+ ASSERT_OK(iter->status());
2501
+ iter.reset(db_->NewIterator(read_opts, handles_[1]));
2502
+ iter->SeekToFirst();
2503
+ ASSERT_TRUE(iter->Valid());
2504
+ ASSERT_EQ("a", iter->key());
2505
+ iter->Next();
2506
+ ASSERT_FALSE(iter->Valid());
2507
+ ASSERT_OK(iter->status());
2508
+ }
2509
+
2510
+ TEST_F(DBBasicTest, DisableTrackWal) {
2511
+ // If WAL tracking was enabled, and then disabled during reopen,
2512
+ // the previously tracked WALs should be removed from MANIFEST.
2513
+
2514
+ Options options = CurrentOptions();
2515
+ options.track_and_verify_wals_in_manifest = true;
2516
+ // extremely small write buffer size,
2517
+ // so that new WALs are created more frequently.
2518
+ options.write_buffer_size = 100;
2519
+ options.env = env_;
2520
+ DestroyAndReopen(options);
2521
+ for (int i = 0; i < 100; i++) {
2522
+ ASSERT_OK(Put("foo" + std::to_string(i), "value" + std::to_string(i)));
2523
+ }
2524
+ ASSERT_OK(dbfull()->TEST_SwitchMemtable());
2525
+ ASSERT_OK(db_->SyncWAL());
2526
+ // Some WALs are tracked.
2527
+ ASSERT_FALSE(dbfull()->TEST_GetVersionSet()->GetWalSet().GetWals().empty());
2528
+ Close();
2529
+
2530
+ // Disable WAL tracking.
2531
+ options.track_and_verify_wals_in_manifest = false;
2532
+ options.create_if_missing = false;
2533
+ ASSERT_OK(TryReopen(options));
2534
+ // Previously tracked WALs are cleared.
2535
+ ASSERT_TRUE(dbfull()->TEST_GetVersionSet()->GetWalSet().GetWals().empty());
2536
+ Close();
2537
+
2538
+ // Re-enable WAL tracking again.
2539
+ options.track_and_verify_wals_in_manifest = true;
2540
+ options.create_if_missing = false;
2541
+ ASSERT_OK(TryReopen(options));
2542
+ ASSERT_TRUE(dbfull()->TEST_GetVersionSet()->GetWalSet().GetWals().empty());
2543
+ Close();
2544
+ }
2545
+ #endif // !ROCKSDB_LITE
2546
+
2547
+ TEST_F(DBBasicTest, ManifestChecksumMismatch) {
2548
+ Options options = CurrentOptions();
2549
+ DestroyAndReopen(options);
2550
+ ASSERT_OK(Put("bar", "value"));
2551
+ ASSERT_OK(Flush());
2552
+ SyncPoint::GetInstance()->DisableProcessing();
2553
+ SyncPoint::GetInstance()->ClearAllCallBacks();
2554
+ SyncPoint::GetInstance()->SetCallBack(
2555
+ "LogWriter::EmitPhysicalRecord:BeforeEncodeChecksum", [&](void* arg) {
2556
+ auto* crc = reinterpret_cast<uint32_t*>(arg);
2557
+ *crc = *crc + 1;
2558
+ });
2559
+ SyncPoint::GetInstance()->EnableProcessing();
2560
+
2561
+ WriteOptions write_opts;
2562
+ write_opts.disableWAL = true;
2563
+ Status s = db_->Put(write_opts, "foo", "value");
2564
+ ASSERT_OK(s);
2565
+ ASSERT_OK(Flush());
2566
+ SyncPoint::GetInstance()->DisableProcessing();
2567
+ SyncPoint::GetInstance()->ClearAllCallBacks();
2568
+ ASSERT_OK(Put("foo", "value1"));
2569
+ ASSERT_OK(Flush());
2570
+ s = TryReopen(options);
2571
+ ASSERT_TRUE(s.IsCorruption());
2572
+ }
2573
+
2574
+ #ifndef ROCKSDB_LITE
2575
+ class DBBasicTestTrackWal : public DBTestBase,
2576
+ public testing::WithParamInterface<bool> {
2577
+ public:
2578
+ DBBasicTestTrackWal()
2579
+ : DBTestBase("/db_basic_test_track_wal", /*env_do_fsync=*/false) {}
2580
+
2581
+ int CountWalFiles() {
2582
+ VectorLogPtr log_files;
2583
+ EXPECT_OK(dbfull()->GetSortedWalFiles(log_files));
2584
+ return static_cast<int>(log_files.size());
2585
+ };
2586
+ };
2587
+
2588
+ TEST_P(DBBasicTestTrackWal, DoNotTrackObsoleteWal) {
2589
+ // If a WAL becomes obsolete after flushing, but is not deleted from disk yet,
2590
+ // then if SyncWAL is called afterwards, the obsolete WAL should not be
2591
+ // tracked in MANIFEST.
2592
+
2593
+ Options options = CurrentOptions();
2594
+ options.create_if_missing = true;
2595
+ options.track_and_verify_wals_in_manifest = true;
2596
+ options.atomic_flush = GetParam();
2597
+
2598
+ DestroyAndReopen(options);
2599
+ CreateAndReopenWithCF({"cf"}, options);
2600
+ ASSERT_EQ(handles_.size(), 2); // default, cf
2601
+ // Do not delete WALs.
2602
+ ASSERT_OK(db_->DisableFileDeletions());
2603
+ constexpr int n = 10;
2604
+ std::vector<std::unique_ptr<LogFile>> wals(n);
2605
+ for (size_t i = 0; i < n; i++) {
2606
+ // Generate a new WAL for each key-value.
2607
+ const int cf = i % 2;
2608
+ ASSERT_OK(db_->GetCurrentWalFile(&wals[i]));
2609
+ ASSERT_OK(Put(cf, "k" + std::to_string(i), "v" + std::to_string(i)));
2610
+ ASSERT_OK(Flush({0, 1}));
2611
+ }
2612
+ ASSERT_EQ(CountWalFiles(), n);
2613
+ // Since all WALs are obsolete, no WAL should be tracked in MANIFEST.
2614
+ ASSERT_OK(db_->SyncWAL());
2615
+
2616
+ // Manually delete all WALs.
2617
+ Close();
2618
+ for (const auto& wal : wals) {
2619
+ ASSERT_OK(env_->DeleteFile(LogFileName(dbname_, wal->LogNumber())));
2620
+ }
2621
+
2622
+ // If SyncWAL tracks the obsolete WALs in MANIFEST,
2623
+ // reopen will fail because the WALs are missing from disk.
2624
+ ASSERT_OK(TryReopenWithColumnFamilies({"default", "cf"}, options));
2625
+ Destroy(options);
2626
+ }
2627
+
2628
+ INSTANTIATE_TEST_CASE_P(DBBasicTestTrackWal, DBBasicTestTrackWal,
2629
+ testing::Bool());
2630
+ #endif // ROCKSDB_LITE
2631
+
2632
+ class DBBasicTestMultiGet : public DBTestBase {
2633
+ public:
2634
+ DBBasicTestMultiGet(std::string test_dir, int num_cfs, bool compressed_cache,
2635
+ bool uncompressed_cache, bool _compression_enabled,
2636
+ bool _fill_cache, uint32_t compression_parallel_threads)
2637
+ : DBTestBase(test_dir, /*env_do_fsync=*/false) {
2638
+ compression_enabled_ = _compression_enabled;
2639
+ fill_cache_ = _fill_cache;
2640
+
2641
+ if (compressed_cache) {
2642
+ std::shared_ptr<Cache> cache = NewLRUCache(1048576);
2643
+ compressed_cache_ = std::make_shared<MyBlockCache>(cache);
2644
+ }
2645
+ if (uncompressed_cache) {
2646
+ std::shared_ptr<Cache> cache = NewLRUCache(1048576);
2647
+ uncompressed_cache_ = std::make_shared<MyBlockCache>(cache);
2648
+ }
2649
+
2650
+ env_->count_random_reads_ = true;
2651
+
2652
+ Options options = CurrentOptions();
2653
+ Random rnd(301);
2654
+ BlockBasedTableOptions table_options;
2655
+
2656
+ #ifndef ROCKSDB_LITE
2657
+ if (compression_enabled_) {
2658
+ std::vector<CompressionType> compression_types;
2659
+ compression_types = GetSupportedCompressions();
2660
+ // Not every platform may have compression libraries available, so
2661
+ // dynamically pick based on what's available
2662
+ CompressionType tmp_type = kNoCompression;
2663
+ for (auto c_type : compression_types) {
2664
+ if (c_type != kNoCompression) {
2665
+ tmp_type = c_type;
2666
+ break;
2667
+ }
2668
+ }
2669
+ if (tmp_type != kNoCompression) {
2670
+ options.compression = tmp_type;
2671
+ } else {
2672
+ compression_enabled_ = false;
2673
+ }
2674
+ }
2675
+ #else
2676
+ // GetSupportedCompressions() is not available in LITE build
2677
+ if (!Snappy_Supported()) {
2678
+ compression_enabled_ = false;
2679
+ }
2680
+ #endif // ROCKSDB_LITE
2681
+
2682
+ table_options.block_cache = uncompressed_cache_;
2683
+ if (table_options.block_cache == nullptr) {
2684
+ table_options.no_block_cache = true;
2685
+ } else {
2686
+ table_options.pin_l0_filter_and_index_blocks_in_cache = true;
2687
+ }
2688
+ table_options.block_cache_compressed = compressed_cache_;
2689
+ table_options.flush_block_policy_factory.reset(
2690
+ new MyFlushBlockPolicyFactory());
2691
+ options.table_factory.reset(NewBlockBasedTableFactory(table_options));
2692
+ if (!compression_enabled_) {
2693
+ options.compression = kNoCompression;
2694
+ } else {
2695
+ options.compression_opts.parallel_threads = compression_parallel_threads;
2696
+ }
2697
+ options_ = options;
2698
+ Reopen(options);
2699
+
2700
+ if (num_cfs > 1) {
2701
+ for (int cf = 0; cf < num_cfs; ++cf) {
2702
+ cf_names_.emplace_back("cf" + std::to_string(cf));
2703
+ }
2704
+ CreateColumnFamilies(cf_names_, options);
2705
+ cf_names_.emplace_back("default");
2706
+ }
2707
+
2708
+ std::string zero_str(128, '\0');
2709
+ for (int cf = 0; cf < num_cfs; ++cf) {
2710
+ for (int i = 0; i < 100; ++i) {
2711
+ // Make the value compressible. A purely random string doesn't compress
2712
+ // and the resultant data block will not be compressed
2713
+ values_.emplace_back(rnd.RandomString(128) + zero_str);
2714
+ assert(((num_cfs == 1) ? Put(Key(i), values_[i])
2715
+ : Put(cf, Key(i), values_[i])) == Status::OK());
2716
+ }
2717
+ if (num_cfs == 1) {
2718
+ EXPECT_OK(Flush());
2719
+ } else {
2720
+ EXPECT_OK(dbfull()->Flush(FlushOptions(), handles_[cf]));
2721
+ }
2722
+
2723
+ for (int i = 0; i < 100; ++i) {
2724
+ // block cannot gain space by compression
2725
+ uncompressable_values_.emplace_back(rnd.RandomString(256) + '\0');
2726
+ std::string tmp_key = "a" + Key(i);
2727
+ assert(((num_cfs == 1) ? Put(tmp_key, uncompressable_values_[i])
2728
+ : Put(cf, tmp_key, uncompressable_values_[i])) ==
2729
+ Status::OK());
2730
+ }
2731
+ if (num_cfs == 1) {
2732
+ EXPECT_OK(Flush());
2733
+ } else {
2734
+ EXPECT_OK(dbfull()->Flush(FlushOptions(), handles_[cf]));
2735
+ }
2736
+ }
2737
+ }
2738
+
2739
+ bool CheckValue(int i, const std::string& value) {
2740
+ if (values_[i].compare(value) == 0) {
2741
+ return true;
2742
+ }
2743
+ return false;
2744
+ }
2745
+
2746
+ bool CheckUncompressableValue(int i, const std::string& value) {
2747
+ if (uncompressable_values_[i].compare(value) == 0) {
2748
+ return true;
2749
+ }
2750
+ return false;
2751
+ }
2752
+
2753
+ const std::vector<std::string>& GetCFNames() const { return cf_names_; }
2754
+
2755
+ int num_lookups() { return uncompressed_cache_->num_lookups(); }
2756
+ int num_found() { return uncompressed_cache_->num_found(); }
2757
+ int num_inserts() { return uncompressed_cache_->num_inserts(); }
2758
+
2759
+ int num_lookups_compressed() { return compressed_cache_->num_lookups(); }
2760
+ int num_found_compressed() { return compressed_cache_->num_found(); }
2761
+ int num_inserts_compressed() { return compressed_cache_->num_inserts(); }
2762
+
2763
+ bool fill_cache() { return fill_cache_; }
2764
+ bool compression_enabled() { return compression_enabled_; }
2765
+ bool has_compressed_cache() { return compressed_cache_ != nullptr; }
2766
+ bool has_uncompressed_cache() { return uncompressed_cache_ != nullptr; }
2767
+ Options get_options() { return options_; }
2768
+
2769
+ static void SetUpTestCase() {}
2770
+ static void TearDownTestCase() {}
2771
+
2772
+ protected:
2773
+ class MyFlushBlockPolicyFactory : public FlushBlockPolicyFactory {
2774
+ public:
2775
+ MyFlushBlockPolicyFactory() {}
2776
+
2777
+ virtual const char* Name() const override {
2778
+ return "MyFlushBlockPolicyFactory";
2779
+ }
2780
+
2781
+ virtual FlushBlockPolicy* NewFlushBlockPolicy(
2782
+ const BlockBasedTableOptions& /*table_options*/,
2783
+ const BlockBuilder& data_block_builder) const override {
2784
+ return new MyFlushBlockPolicy(data_block_builder);
2785
+ }
2786
+ };
2787
+
2788
+ class MyFlushBlockPolicy : public FlushBlockPolicy {
2789
+ public:
2790
+ explicit MyFlushBlockPolicy(const BlockBuilder& data_block_builder)
2791
+ : num_keys_(0), data_block_builder_(data_block_builder) {}
2792
+
2793
+ bool Update(const Slice& /*key*/, const Slice& /*value*/) override {
2794
+ if (data_block_builder_.empty()) {
2795
+ // First key in this block
2796
+ num_keys_ = 1;
2797
+ return false;
2798
+ }
2799
+ // Flush every 10 keys
2800
+ if (num_keys_ == 10) {
2801
+ num_keys_ = 1;
2802
+ return true;
2803
+ }
2804
+ num_keys_++;
2805
+ return false;
2806
+ }
2807
+
2808
+ private:
2809
+ int num_keys_;
2810
+ const BlockBuilder& data_block_builder_;
2811
+ };
2812
+
2813
+ class MyBlockCache : public CacheWrapper {
2814
+ public:
2815
+ explicit MyBlockCache(std::shared_ptr<Cache> target)
2816
+ : CacheWrapper(target),
2817
+ num_lookups_(0),
2818
+ num_found_(0),
2819
+ num_inserts_(0) {}
2820
+
2821
+ const char* Name() const override { return "MyBlockCache"; }
2822
+
2823
+ Status Insert(const Slice& key, void* value, size_t charge,
2824
+ void (*deleter)(const Slice& key, void* value),
2825
+ Handle** handle = nullptr,
2826
+ Priority priority = Priority::LOW) override {
2827
+ num_inserts_++;
2828
+ return target_->Insert(key, value, charge, deleter, handle, priority);
2829
+ }
2830
+
2831
+ Handle* Lookup(const Slice& key, Statistics* stats = nullptr) override {
2832
+ num_lookups_++;
2833
+ Handle* handle = target_->Lookup(key, stats);
2834
+ if (handle != nullptr) {
2835
+ num_found_++;
2836
+ }
2837
+ return handle;
2838
+ }
2839
+ int num_lookups() { return num_lookups_; }
2840
+
2841
+ int num_found() { return num_found_; }
2842
+
2843
+ int num_inserts() { return num_inserts_; }
2844
+
2845
+ private:
2846
+ int num_lookups_;
2847
+ int num_found_;
2848
+ int num_inserts_;
2849
+ };
2850
+
2851
+ std::shared_ptr<MyBlockCache> compressed_cache_;
2852
+ std::shared_ptr<MyBlockCache> uncompressed_cache_;
2853
+ Options options_;
2854
+ bool compression_enabled_;
2855
+ std::vector<std::string> values_;
2856
+ std::vector<std::string> uncompressable_values_;
2857
+ bool fill_cache_;
2858
+ std::vector<std::string> cf_names_;
2859
+ };
2860
+
2861
+ class DBBasicTestWithParallelIO
2862
+ : public DBBasicTestMultiGet,
2863
+ public testing::WithParamInterface<
2864
+ std::tuple<bool, bool, bool, bool, uint32_t>> {
2865
+ public:
2866
+ DBBasicTestWithParallelIO()
2867
+ : DBBasicTestMultiGet("/db_basic_test_with_parallel_io", 1,
2868
+ std::get<0>(GetParam()), std::get<1>(GetParam()),
2869
+ std::get<2>(GetParam()), std::get<3>(GetParam()),
2870
+ std::get<4>(GetParam())) {}
2871
+ };
2872
+
2873
+ TEST_P(DBBasicTestWithParallelIO, MultiGet) {
2874
+ std::vector<std::string> key_data(10);
2875
+ std::vector<Slice> keys;
2876
+ // We cannot resize a PinnableSlice vector, so just set initial size to
2877
+ // largest we think we will need
2878
+ std::vector<PinnableSlice> values(10);
2879
+ std::vector<Status> statuses;
2880
+ ReadOptions ro;
2881
+ ro.fill_cache = fill_cache();
2882
+
2883
+ // Warm up the cache first
2884
+ key_data.emplace_back(Key(0));
2885
+ keys.emplace_back(Slice(key_data.back()));
2886
+ key_data.emplace_back(Key(50));
2887
+ keys.emplace_back(Slice(key_data.back()));
2888
+ statuses.resize(keys.size());
2889
+
2890
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
2891
+ keys.data(), values.data(), statuses.data(), true);
2892
+ ASSERT_TRUE(CheckValue(0, values[0].ToString()));
2893
+ ASSERT_TRUE(CheckValue(50, values[1].ToString()));
2894
+
2895
+ int random_reads = env_->random_read_counter_.Read();
2896
+ key_data[0] = Key(1);
2897
+ key_data[1] = Key(51);
2898
+ keys[0] = Slice(key_data[0]);
2899
+ keys[1] = Slice(key_data[1]);
2900
+ values[0].Reset();
2901
+ values[1].Reset();
2902
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
2903
+ keys.data(), values.data(), statuses.data(), true);
2904
+ ASSERT_TRUE(CheckValue(1, values[0].ToString()));
2905
+ ASSERT_TRUE(CheckValue(51, values[1].ToString()));
2906
+
2907
+ bool read_from_cache = false;
2908
+ if (fill_cache()) {
2909
+ if (has_uncompressed_cache()) {
2910
+ read_from_cache = true;
2911
+ } else if (has_compressed_cache() && compression_enabled()) {
2912
+ read_from_cache = true;
2913
+ }
2914
+ }
2915
+
2916
+ int expected_reads = random_reads + (read_from_cache ? 0 : 2);
2917
+ ASSERT_EQ(env_->random_read_counter_.Read(), expected_reads);
2918
+
2919
+ keys.resize(10);
2920
+ statuses.resize(10);
2921
+ std::vector<int> key_ints{1, 2, 15, 16, 55, 81, 82, 83, 84, 85};
2922
+ for (size_t i = 0; i < key_ints.size(); ++i) {
2923
+ key_data[i] = Key(key_ints[i]);
2924
+ keys[i] = Slice(key_data[i]);
2925
+ statuses[i] = Status::OK();
2926
+ values[i].Reset();
2927
+ }
2928
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
2929
+ keys.data(), values.data(), statuses.data(), true);
2930
+ for (size_t i = 0; i < key_ints.size(); ++i) {
2931
+ ASSERT_OK(statuses[i]);
2932
+ ASSERT_TRUE(CheckValue(key_ints[i], values[i].ToString()));
2933
+ }
2934
+ if (compression_enabled() && !has_compressed_cache()) {
2935
+ expected_reads += (read_from_cache ? 2 : 3);
2936
+ } else {
2937
+ expected_reads += (read_from_cache ? 2 : 4);
2938
+ }
2939
+ ASSERT_EQ(env_->random_read_counter_.Read(), expected_reads);
2940
+
2941
+ keys.resize(10);
2942
+ statuses.resize(10);
2943
+ std::vector<int> key_uncmp{1, 2, 15, 16, 55, 81, 82, 83, 84, 85};
2944
+ for (size_t i = 0; i < key_uncmp.size(); ++i) {
2945
+ key_data[i] = "a" + Key(key_uncmp[i]);
2946
+ keys[i] = Slice(key_data[i]);
2947
+ statuses[i] = Status::OK();
2948
+ values[i].Reset();
2949
+ }
2950
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
2951
+ keys.data(), values.data(), statuses.data(), true);
2952
+ for (size_t i = 0; i < key_uncmp.size(); ++i) {
2953
+ ASSERT_OK(statuses[i]);
2954
+ ASSERT_TRUE(CheckUncompressableValue(key_uncmp[i], values[i].ToString()));
2955
+ }
2956
+ if (compression_enabled() && !has_compressed_cache()) {
2957
+ expected_reads += (read_from_cache ? 3 : 3);
2958
+ } else {
2959
+ expected_reads += (read_from_cache ? 4 : 4);
2960
+ }
2961
+ ASSERT_EQ(env_->random_read_counter_.Read(), expected_reads);
2962
+
2963
+ keys.resize(5);
2964
+ statuses.resize(5);
2965
+ std::vector<int> key_tr{1, 2, 15, 16, 55};
2966
+ for (size_t i = 0; i < key_tr.size(); ++i) {
2967
+ key_data[i] = "a" + Key(key_tr[i]);
2968
+ keys[i] = Slice(key_data[i]);
2969
+ statuses[i] = Status::OK();
2970
+ values[i].Reset();
2971
+ }
2972
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
2973
+ keys.data(), values.data(), statuses.data(), true);
2974
+ for (size_t i = 0; i < key_tr.size(); ++i) {
2975
+ ASSERT_OK(statuses[i]);
2976
+ ASSERT_TRUE(CheckUncompressableValue(key_tr[i], values[i].ToString()));
2977
+ }
2978
+ if (compression_enabled() && !has_compressed_cache()) {
2979
+ expected_reads += (read_from_cache ? 0 : 2);
2980
+ ASSERT_EQ(env_->random_read_counter_.Read(), expected_reads);
2981
+ } else {
2982
+ if (has_uncompressed_cache()) {
2983
+ expected_reads += (read_from_cache ? 0 : 3);
2984
+ ASSERT_EQ(env_->random_read_counter_.Read(), expected_reads);
2985
+ } else {
2986
+ // A rare case, even we enable the block compression but some of data
2987
+ // blocks are not compressed due to content. If user only enable the
2988
+ // compressed cache, the uncompressed blocks will not tbe cached, and
2989
+ // block reads will be triggered. The number of reads is related to
2990
+ // the compression algorithm.
2991
+ ASSERT_TRUE(env_->random_read_counter_.Read() >= expected_reads);
2992
+ }
2993
+ }
2994
+ }
2995
+
2996
+ #ifndef ROCKSDB_LITE
2997
+ TEST_P(DBBasicTestWithParallelIO, MultiGetDirectIO) {
2998
+ class FakeDirectIOEnv : public EnvWrapper {
2999
+ class FakeDirectIOSequentialFile;
3000
+ class FakeDirectIORandomAccessFile;
3001
+
3002
+ public:
3003
+ FakeDirectIOEnv(Env* env) : EnvWrapper(env) {}
3004
+
3005
+ Status NewRandomAccessFile(const std::string& fname,
3006
+ std::unique_ptr<RandomAccessFile>* result,
3007
+ const EnvOptions& options) override {
3008
+ std::unique_ptr<RandomAccessFile> file;
3009
+ assert(options.use_direct_reads);
3010
+ EnvOptions opts = options;
3011
+ opts.use_direct_reads = false;
3012
+ Status s = target()->NewRandomAccessFile(fname, &file, opts);
3013
+ if (!s.ok()) {
3014
+ return s;
3015
+ }
3016
+ result->reset(new FakeDirectIORandomAccessFile(std::move(file)));
3017
+ return s;
3018
+ }
3019
+
3020
+ private:
3021
+ class FakeDirectIOSequentialFile : public SequentialFileWrapper {
3022
+ public:
3023
+ FakeDirectIOSequentialFile(std::unique_ptr<SequentialFile>&& file)
3024
+ : SequentialFileWrapper(file.get()), file_(std::move(file)) {}
3025
+ ~FakeDirectIOSequentialFile() {}
3026
+
3027
+ bool use_direct_io() const override { return true; }
3028
+ size_t GetRequiredBufferAlignment() const override { return 1; }
3029
+
3030
+ private:
3031
+ std::unique_ptr<SequentialFile> file_;
3032
+ };
3033
+
3034
+ class FakeDirectIORandomAccessFile : public RandomAccessFileWrapper {
3035
+ public:
3036
+ FakeDirectIORandomAccessFile(std::unique_ptr<RandomAccessFile>&& file)
3037
+ : RandomAccessFileWrapper(file.get()), file_(std::move(file)) {}
3038
+ ~FakeDirectIORandomAccessFile() {}
3039
+
3040
+ bool use_direct_io() const override { return true; }
3041
+ size_t GetRequiredBufferAlignment() const override { return 1; }
3042
+
3043
+ private:
3044
+ std::unique_ptr<RandomAccessFile> file_;
3045
+ };
3046
+ };
3047
+
3048
+ std::unique_ptr<FakeDirectIOEnv> env(new FakeDirectIOEnv(env_));
3049
+ Options opts = get_options();
3050
+ opts.env = env.get();
3051
+ opts.use_direct_reads = true;
3052
+ Reopen(opts);
3053
+
3054
+ std::vector<std::string> key_data(10);
3055
+ std::vector<Slice> keys;
3056
+ // We cannot resize a PinnableSlice vector, so just set initial size to
3057
+ // largest we think we will need
3058
+ std::vector<PinnableSlice> values(10);
3059
+ std::vector<Status> statuses;
3060
+ ReadOptions ro;
3061
+ ro.fill_cache = fill_cache();
3062
+
3063
+ // Warm up the cache first
3064
+ key_data.emplace_back(Key(0));
3065
+ keys.emplace_back(Slice(key_data.back()));
3066
+ key_data.emplace_back(Key(50));
3067
+ keys.emplace_back(Slice(key_data.back()));
3068
+ statuses.resize(keys.size());
3069
+
3070
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
3071
+ keys.data(), values.data(), statuses.data(), true);
3072
+ ASSERT_TRUE(CheckValue(0, values[0].ToString()));
3073
+ ASSERT_TRUE(CheckValue(50, values[1].ToString()));
3074
+
3075
+ int random_reads = env_->random_read_counter_.Read();
3076
+ key_data[0] = Key(1);
3077
+ key_data[1] = Key(51);
3078
+ keys[0] = Slice(key_data[0]);
3079
+ keys[1] = Slice(key_data[1]);
3080
+ values[0].Reset();
3081
+ values[1].Reset();
3082
+ if (uncompressed_cache_) {
3083
+ uncompressed_cache_->SetCapacity(0);
3084
+ uncompressed_cache_->SetCapacity(1048576);
3085
+ }
3086
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
3087
+ keys.data(), values.data(), statuses.data(), true);
3088
+ ASSERT_TRUE(CheckValue(1, values[0].ToString()));
3089
+ ASSERT_TRUE(CheckValue(51, values[1].ToString()));
3090
+
3091
+ bool read_from_cache = false;
3092
+ if (fill_cache()) {
3093
+ if (has_uncompressed_cache()) {
3094
+ read_from_cache = true;
3095
+ } else if (has_compressed_cache() && compression_enabled()) {
3096
+ read_from_cache = true;
3097
+ }
3098
+ }
3099
+
3100
+ int expected_reads = random_reads;
3101
+ if (!compression_enabled() || !has_compressed_cache()) {
3102
+ expected_reads += 2;
3103
+ } else {
3104
+ expected_reads += (read_from_cache ? 0 : 2);
3105
+ }
3106
+ if (env_->random_read_counter_.Read() != expected_reads) {
3107
+ ASSERT_EQ(env_->random_read_counter_.Read(), expected_reads);
3108
+ }
3109
+ Close();
3110
+ }
3111
+ #endif // ROCKSDB_LITE
3112
+
3113
+ TEST_P(DBBasicTestWithParallelIO, MultiGetWithChecksumMismatch) {
3114
+ std::vector<std::string> key_data(10);
3115
+ std::vector<Slice> keys;
3116
+ // We cannot resize a PinnableSlice vector, so just set initial size to
3117
+ // largest we think we will need
3118
+ std::vector<PinnableSlice> values(10);
3119
+ std::vector<Status> statuses;
3120
+ int read_count = 0;
3121
+ ReadOptions ro;
3122
+ ro.fill_cache = fill_cache();
3123
+
3124
+ SyncPoint::GetInstance()->SetCallBack(
3125
+ "RetrieveMultipleBlocks:VerifyChecksum", [&](void* status) {
3126
+ Status* s = static_cast<Status*>(status);
3127
+ read_count++;
3128
+ if (read_count == 2) {
3129
+ *s = Status::Corruption();
3130
+ }
3131
+ });
3132
+ SyncPoint::GetInstance()->EnableProcessing();
3133
+
3134
+ // Warm up the cache first
3135
+ key_data.emplace_back(Key(0));
3136
+ keys.emplace_back(Slice(key_data.back()));
3137
+ key_data.emplace_back(Key(50));
3138
+ keys.emplace_back(Slice(key_data.back()));
3139
+ statuses.resize(keys.size());
3140
+
3141
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
3142
+ keys.data(), values.data(), statuses.data(), true);
3143
+ ASSERT_TRUE(CheckValue(0, values[0].ToString()));
3144
+ // ASSERT_TRUE(CheckValue(50, values[1].ToString()));
3145
+ ASSERT_EQ(statuses[0], Status::OK());
3146
+ ASSERT_EQ(statuses[1], Status::Corruption());
3147
+
3148
+ SyncPoint::GetInstance()->DisableProcessing();
3149
+ }
3150
+
3151
+ TEST_P(DBBasicTestWithParallelIO, MultiGetWithMissingFile) {
3152
+ std::vector<std::string> key_data(10);
3153
+ std::vector<Slice> keys;
3154
+ // We cannot resize a PinnableSlice vector, so just set initial size to
3155
+ // largest we think we will need
3156
+ std::vector<PinnableSlice> values(10);
3157
+ std::vector<Status> statuses;
3158
+ ReadOptions ro;
3159
+ ro.fill_cache = fill_cache();
3160
+
3161
+ SyncPoint::GetInstance()->SetCallBack(
3162
+ "TableCache::MultiGet:FindTable", [&](void* status) {
3163
+ Status* s = static_cast<Status*>(status);
3164
+ *s = Status::IOError();
3165
+ });
3166
+ // DB open will create table readers unless we reduce the table cache
3167
+ // capacity.
3168
+ // SanitizeOptions will set max_open_files to minimum of 20. Table cache
3169
+ // is allocated with max_open_files - 10 as capacity. So override
3170
+ // max_open_files to 11 so table cache capacity will become 1. This will
3171
+ // prevent file open during DB open and force the file to be opened
3172
+ // during MultiGet
3173
+ SyncPoint::GetInstance()->SetCallBack(
3174
+ "SanitizeOptions::AfterChangeMaxOpenFiles", [&](void* arg) {
3175
+ int* max_open_files = (int*)arg;
3176
+ *max_open_files = 11;
3177
+ });
3178
+ SyncPoint::GetInstance()->EnableProcessing();
3179
+
3180
+ Reopen(CurrentOptions());
3181
+
3182
+ // Warm up the cache first
3183
+ key_data.emplace_back(Key(0));
3184
+ keys.emplace_back(Slice(key_data.back()));
3185
+ key_data.emplace_back(Key(50));
3186
+ keys.emplace_back(Slice(key_data.back()));
3187
+ statuses.resize(keys.size());
3188
+
3189
+ dbfull()->MultiGet(ro, dbfull()->DefaultColumnFamily(), keys.size(),
3190
+ keys.data(), values.data(), statuses.data(), true);
3191
+ ASSERT_EQ(statuses[0], Status::IOError());
3192
+ ASSERT_EQ(statuses[1], Status::IOError());
3193
+
3194
+ SyncPoint::GetInstance()->DisableProcessing();
3195
+ }
3196
+
3197
+ INSTANTIATE_TEST_CASE_P(ParallelIO, DBBasicTestWithParallelIO,
3198
+ // Params are as follows -
3199
+ // Param 0 - Compressed cache enabled
3200
+ // Param 1 - Uncompressed cache enabled
3201
+ // Param 2 - Data compression enabled
3202
+ // Param 3 - ReadOptions::fill_cache
3203
+ // Param 4 - CompressionOptions::parallel_threads
3204
+ ::testing::Combine(::testing::Bool(), ::testing::Bool(),
3205
+ ::testing::Bool(), ::testing::Bool(),
3206
+ ::testing::Values(1, 4)));
3207
+
3208
+ // Forward declaration
3209
+ class DeadlineFS;
3210
+
3211
+ class DeadlineRandomAccessFile : public FSRandomAccessFileWrapper {
3212
+ public:
3213
+ DeadlineRandomAccessFile(DeadlineFS& fs,
3214
+ std::unique_ptr<FSRandomAccessFile>& file)
3215
+ : FSRandomAccessFileWrapper(file.get()),
3216
+ fs_(fs),
3217
+ file_(std::move(file)) {}
3218
+
3219
+ IOStatus Read(uint64_t offset, size_t len, const IOOptions& opts,
3220
+ Slice* result, char* scratch,
3221
+ IODebugContext* dbg) const override;
3222
+
3223
+ IOStatus MultiRead(FSReadRequest* reqs, size_t num_reqs,
3224
+ const IOOptions& options, IODebugContext* dbg) override;
3225
+
3226
+ private:
3227
+ DeadlineFS& fs_;
3228
+ std::unique_ptr<FSRandomAccessFile> file_;
3229
+ };
3230
+
3231
+ class DeadlineFS : public FileSystemWrapper {
3232
+ public:
3233
+ // The error_on_delay parameter specifies whether a IOStatus::TimedOut()
3234
+ // status should be returned after delaying the IO to exceed the timeout,
3235
+ // or to simply delay but return success anyway. The latter mimics the
3236
+ // behavior of PosixFileSystem, which does not enforce any timeout
3237
+ explicit DeadlineFS(SpecialEnv* env, bool error_on_delay)
3238
+ : FileSystemWrapper(env->GetFileSystem()),
3239
+ deadline_(std::chrono::microseconds::zero()),
3240
+ io_timeout_(std::chrono::microseconds::zero()),
3241
+ env_(env),
3242
+ timedout_(false),
3243
+ ignore_deadline_(false),
3244
+ error_on_delay_(error_on_delay) {}
3245
+
3246
+ IOStatus NewRandomAccessFile(const std::string& fname,
3247
+ const FileOptions& opts,
3248
+ std::unique_ptr<FSRandomAccessFile>* result,
3249
+ IODebugContext* dbg) override {
3250
+ std::unique_ptr<FSRandomAccessFile> file;
3251
+ IOStatus s = target()->NewRandomAccessFile(fname, opts, &file, dbg);
3252
+ EXPECT_OK(s);
3253
+ result->reset(new DeadlineRandomAccessFile(*this, file));
3254
+
3255
+ const std::chrono::microseconds deadline = GetDeadline();
3256
+ const std::chrono::microseconds io_timeout = GetIOTimeout();
3257
+ if (deadline.count() || io_timeout.count()) {
3258
+ AssertDeadline(deadline, io_timeout, opts.io_options);
3259
+ }
3260
+ return ShouldDelay(opts.io_options);
3261
+ }
3262
+
3263
+ // Set a vector of {IO counter, delay in microseconds, return status} tuples
3264
+ // that control when to inject a delay and duration of the delay
3265
+ void SetDelayTrigger(const std::chrono::microseconds deadline,
3266
+ const std::chrono::microseconds io_timeout,
3267
+ const int trigger) {
3268
+ delay_trigger_ = trigger;
3269
+ io_count_ = 0;
3270
+ deadline_ = deadline;
3271
+ io_timeout_ = io_timeout;
3272
+ timedout_ = false;
3273
+ }
3274
+
3275
+ // Increment the IO counter and return a delay in microseconds
3276
+ IOStatus ShouldDelay(const IOOptions& opts) {
3277
+ if (timedout_) {
3278
+ return IOStatus::TimedOut();
3279
+ } else if (!deadline_.count() && !io_timeout_.count()) {
3280
+ return IOStatus::OK();
3281
+ }
3282
+ if (!ignore_deadline_ && delay_trigger_ == io_count_++) {
3283
+ env_->SleepForMicroseconds(static_cast<int>(opts.timeout.count() + 1));
3284
+ timedout_ = true;
3285
+ if (error_on_delay_) {
3286
+ return IOStatus::TimedOut();
3287
+ }
3288
+ }
3289
+ return IOStatus::OK();
3290
+ }
3291
+
3292
+ const std::chrono::microseconds GetDeadline() {
3293
+ return ignore_deadline_ ? std::chrono::microseconds::zero() : deadline_;
3294
+ }
3295
+
3296
+ const std::chrono::microseconds GetIOTimeout() {
3297
+ return ignore_deadline_ ? std::chrono::microseconds::zero() : io_timeout_;
3298
+ }
3299
+
3300
+ bool TimedOut() { return timedout_; }
3301
+
3302
+ void IgnoreDeadline(bool ignore) { ignore_deadline_ = ignore; }
3303
+
3304
+ void AssertDeadline(const std::chrono::microseconds deadline,
3305
+ const std::chrono::microseconds io_timeout,
3306
+ const IOOptions& opts) const {
3307
+ // Give a leeway of +- 10us as it can take some time for the Get/
3308
+ // MultiGet call to reach here, in order to avoid false alarms
3309
+ std::chrono::microseconds now =
3310
+ std::chrono::microseconds(env_->NowMicros());
3311
+ std::chrono::microseconds timeout;
3312
+ if (deadline.count()) {
3313
+ timeout = deadline - now;
3314
+ if (io_timeout.count()) {
3315
+ timeout = std::min(timeout, io_timeout);
3316
+ }
3317
+ } else {
3318
+ timeout = io_timeout;
3319
+ }
3320
+ if (opts.timeout != timeout) {
3321
+ ASSERT_EQ(timeout, opts.timeout);
3322
+ }
3323
+ }
3324
+
3325
+ private:
3326
+ // The number of IOs to trigger the delay after
3327
+ int delay_trigger_;
3328
+ // Current IO count
3329
+ int io_count_;
3330
+ // ReadOptions deadline for the Get/MultiGet/Iterator
3331
+ std::chrono::microseconds deadline_;
3332
+ // ReadOptions io_timeout for the Get/MultiGet/Iterator
3333
+ std::chrono::microseconds io_timeout_;
3334
+ SpecialEnv* env_;
3335
+ // Flag to indicate whether we injected a delay
3336
+ bool timedout_;
3337
+ // Temporarily ignore deadlines/timeouts
3338
+ bool ignore_deadline_;
3339
+ // Return IOStatus::TimedOut() or IOStatus::OK()
3340
+ bool error_on_delay_;
3341
+ };
3342
+
3343
+ IOStatus DeadlineRandomAccessFile::Read(uint64_t offset, size_t len,
3344
+ const IOOptions& opts, Slice* result,
3345
+ char* scratch,
3346
+ IODebugContext* dbg) const {
3347
+ const std::chrono::microseconds deadline = fs_.GetDeadline();
3348
+ const std::chrono::microseconds io_timeout = fs_.GetIOTimeout();
3349
+ IOStatus s;
3350
+ if (deadline.count() || io_timeout.count()) {
3351
+ fs_.AssertDeadline(deadline, io_timeout, opts);
3352
+ }
3353
+ if (s.ok()) {
3354
+ s = FSRandomAccessFileWrapper::Read(offset, len, opts, result, scratch,
3355
+ dbg);
3356
+ }
3357
+ if (s.ok()) {
3358
+ s = fs_.ShouldDelay(opts);
3359
+ }
3360
+ return s;
3361
+ }
3362
+
3363
+ IOStatus DeadlineRandomAccessFile::MultiRead(FSReadRequest* reqs,
3364
+ size_t num_reqs,
3365
+ const IOOptions& options,
3366
+ IODebugContext* dbg) {
3367
+ const std::chrono::microseconds deadline = fs_.GetDeadline();
3368
+ const std::chrono::microseconds io_timeout = fs_.GetIOTimeout();
3369
+ IOStatus s;
3370
+ if (deadline.count() || io_timeout.count()) {
3371
+ fs_.AssertDeadline(deadline, io_timeout, options);
3372
+ }
3373
+ if (s.ok()) {
3374
+ s = FSRandomAccessFileWrapper::MultiRead(reqs, num_reqs, options, dbg);
3375
+ }
3376
+ if (s.ok()) {
3377
+ s = fs_.ShouldDelay(options);
3378
+ }
3379
+ return s;
3380
+ }
3381
+
3382
+ // A test class for intercepting random reads and injecting artificial
3383
+ // delays. Used for testing the MultiGet deadline feature
3384
+ class DBBasicTestMultiGetDeadline : public DBBasicTestMultiGet {
3385
+ public:
3386
+ DBBasicTestMultiGetDeadline()
3387
+ : DBBasicTestMultiGet(
3388
+ "db_basic_test_multiget_deadline" /*Test dir*/,
3389
+ 10 /*# of column families*/, false /*compressed cache enabled*/,
3390
+ true /*uncompressed cache enabled*/, true /*compression enabled*/,
3391
+ true /*ReadOptions.fill_cache*/,
3392
+ 1 /*# of parallel compression threads*/) {}
3393
+
3394
+ inline void CheckStatus(std::vector<Status>& statuses, size_t num_ok) {
3395
+ for (size_t i = 0; i < statuses.size(); ++i) {
3396
+ if (i < num_ok) {
3397
+ EXPECT_OK(statuses[i]);
3398
+ } else {
3399
+ if (statuses[i] != Status::TimedOut()) {
3400
+ EXPECT_EQ(statuses[i], Status::TimedOut());
3401
+ }
3402
+ }
3403
+ }
3404
+ }
3405
+ };
3406
+
3407
+ TEST_F(DBBasicTestMultiGetDeadline, MultiGetDeadlineExceeded) {
3408
+ std::shared_ptr<DeadlineFS> fs = std::make_shared<DeadlineFS>(env_, false);
3409
+ std::unique_ptr<Env> env(new CompositeEnvWrapper(env_, fs));
3410
+ Options options = CurrentOptions();
3411
+
3412
+ std::shared_ptr<Cache> cache = NewLRUCache(1048576);
3413
+ BlockBasedTableOptions table_options;
3414
+ table_options.block_cache = cache;
3415
+ options.table_factory.reset(NewBlockBasedTableFactory(table_options));
3416
+ options.env = env.get();
3417
+ SetTimeElapseOnlySleepOnReopen(&options);
3418
+ ReopenWithColumnFamilies(GetCFNames(), options);
3419
+
3420
+ // Test the non-batched version of MultiGet with multiple column
3421
+ // families
3422
+ std::vector<std::string> key_str;
3423
+ size_t i;
3424
+ for (i = 0; i < 5; ++i) {
3425
+ key_str.emplace_back(Key(static_cast<int>(i)));
3426
+ }
3427
+ std::vector<ColumnFamilyHandle*> cfs(key_str.size());
3428
+ ;
3429
+ std::vector<Slice> keys(key_str.size());
3430
+ std::vector<std::string> values(key_str.size());
3431
+ for (i = 0; i < key_str.size(); ++i) {
3432
+ cfs[i] = handles_[i];
3433
+ keys[i] = Slice(key_str[i].data(), key_str[i].size());
3434
+ }
3435
+
3436
+ ReadOptions ro;
3437
+ ro.deadline = std::chrono::microseconds{env->NowMicros() + 10000};
3438
+ // Delay the first IO
3439
+ fs->SetDelayTrigger(ro.deadline, ro.io_timeout, 0);
3440
+
3441
+ std::vector<Status> statuses = dbfull()->MultiGet(ro, cfs, keys, &values);
3442
+ // The first key is successful because we check after the lookup, but
3443
+ // subsequent keys fail due to deadline exceeded
3444
+ CheckStatus(statuses, 1);
3445
+
3446
+ // Clear the cache
3447
+ cache->SetCapacity(0);
3448
+ cache->SetCapacity(1048576);
3449
+ // Test non-batched Multiget with multiple column families and
3450
+ // introducing an IO delay in one of the middle CFs
3451
+ key_str.clear();
3452
+ for (i = 0; i < 10; ++i) {
3453
+ key_str.emplace_back(Key(static_cast<int>(i)));
3454
+ }
3455
+ cfs.resize(key_str.size());
3456
+ keys.resize(key_str.size());
3457
+ values.resize(key_str.size());
3458
+ for (i = 0; i < key_str.size(); ++i) {
3459
+ // 2 keys per CF
3460
+ cfs[i] = handles_[i / 2];
3461
+ keys[i] = Slice(key_str[i].data(), key_str[i].size());
3462
+ }
3463
+ ro.deadline = std::chrono::microseconds{env->NowMicros() + 10000};
3464
+ fs->SetDelayTrigger(ro.deadline, ro.io_timeout, 1);
3465
+ statuses = dbfull()->MultiGet(ro, cfs, keys, &values);
3466
+ CheckStatus(statuses, 3);
3467
+
3468
+ // Test batched MultiGet with an IO delay in the first data block read.
3469
+ // Both keys in the first CF should succeed as they're in the same data
3470
+ // block and would form one batch, and we check for deadline between
3471
+ // batches.
3472
+ std::vector<PinnableSlice> pin_values(keys.size());
3473
+ cache->SetCapacity(0);
3474
+ cache->SetCapacity(1048576);
3475
+ statuses.clear();
3476
+ statuses.resize(keys.size());
3477
+ ro.deadline = std::chrono::microseconds{env->NowMicros() + 10000};
3478
+ fs->SetDelayTrigger(ro.deadline, ro.io_timeout, 0);
3479
+ dbfull()->MultiGet(ro, keys.size(), cfs.data(), keys.data(),
3480
+ pin_values.data(), statuses.data());
3481
+ CheckStatus(statuses, 2);
3482
+
3483
+ // Similar to the previous one, but an IO delay in the third CF data block
3484
+ // read
3485
+ for (PinnableSlice& value : pin_values) {
3486
+ value.Reset();
3487
+ }
3488
+ cache->SetCapacity(0);
3489
+ cache->SetCapacity(1048576);
3490
+ statuses.clear();
3491
+ statuses.resize(keys.size());
3492
+ ro.deadline = std::chrono::microseconds{env->NowMicros() + 10000};
3493
+ fs->SetDelayTrigger(ro.deadline, ro.io_timeout, 2);
3494
+ dbfull()->MultiGet(ro, keys.size(), cfs.data(), keys.data(),
3495
+ pin_values.data(), statuses.data());
3496
+ CheckStatus(statuses, 6);
3497
+
3498
+ // Similar to the previous one, but an IO delay in the last but one CF
3499
+ for (PinnableSlice& value : pin_values) {
3500
+ value.Reset();
3501
+ }
3502
+ cache->SetCapacity(0);
3503
+ cache->SetCapacity(1048576);
3504
+ statuses.clear();
3505
+ statuses.resize(keys.size());
3506
+ ro.deadline = std::chrono::microseconds{env->NowMicros() + 10000};
3507
+ fs->SetDelayTrigger(ro.deadline, ro.io_timeout, 3);
3508
+ dbfull()->MultiGet(ro, keys.size(), cfs.data(), keys.data(),
3509
+ pin_values.data(), statuses.data());
3510
+ CheckStatus(statuses, 8);
3511
+
3512
+ // Test batched MultiGet with single CF and lots of keys. Inject delay
3513
+ // into the second batch of keys. As each batch is 32, the first 64 keys,
3514
+ // i.e first two batches, should succeed and the rest should time out
3515
+ for (PinnableSlice& value : pin_values) {
3516
+ value.Reset();
3517
+ }
3518
+ cache->SetCapacity(0);
3519
+ cache->SetCapacity(1048576);
3520
+ key_str.clear();
3521
+ for (i = 0; i < 100; ++i) {
3522
+ key_str.emplace_back(Key(static_cast<int>(i)));
3523
+ }
3524
+ keys.resize(key_str.size());
3525
+ pin_values.clear();
3526
+ pin_values.resize(key_str.size());
3527
+ for (i = 0; i < key_str.size(); ++i) {
3528
+ keys[i] = Slice(key_str[i].data(), key_str[i].size());
3529
+ }
3530
+ statuses.clear();
3531
+ statuses.resize(keys.size());
3532
+ ro.deadline = std::chrono::microseconds{env->NowMicros() + 10000};
3533
+ fs->SetDelayTrigger(ro.deadline, ro.io_timeout, 1);
3534
+ dbfull()->MultiGet(ro, handles_[0], keys.size(), keys.data(),
3535
+ pin_values.data(), statuses.data());
3536
+ CheckStatus(statuses, 64);
3537
+ Close();
3538
+ }
3539
+
3540
+ TEST_F(DBBasicTest, ManifestWriteFailure) {
3541
+ Options options = GetDefaultOptions();
3542
+ options.create_if_missing = true;
3543
+ options.disable_auto_compactions = true;
3544
+ options.env = env_;
3545
+ DestroyAndReopen(options);
3546
+ ASSERT_OK(Put("foo", "bar"));
3547
+ ASSERT_OK(Flush());
3548
+ SyncPoint::GetInstance()->DisableProcessing();
3549
+ SyncPoint::GetInstance()->ClearAllCallBacks();
3550
+ SyncPoint::GetInstance()->SetCallBack(
3551
+ "VersionSet::ProcessManifestWrites:AfterSyncManifest", [&](void* arg) {
3552
+ ASSERT_NE(nullptr, arg);
3553
+ auto* s = reinterpret_cast<Status*>(arg);
3554
+ ASSERT_OK(*s);
3555
+ // Manually overwrite return status
3556
+ *s = Status::IOError();
3557
+ });
3558
+ SyncPoint::GetInstance()->EnableProcessing();
3559
+ ASSERT_OK(Put("key", "value"));
3560
+ ASSERT_NOK(Flush());
3561
+ SyncPoint::GetInstance()->DisableProcessing();
3562
+ SyncPoint::GetInstance()->ClearAllCallBacks();
3563
+ SyncPoint::GetInstance()->EnableProcessing();
3564
+ Reopen(options);
3565
+ }
3566
+
3567
+ #ifndef ROCKSDB_LITE
3568
+ TEST_F(DBBasicTest, VerifyFileChecksums) {
3569
+ Options options = GetDefaultOptions();
3570
+ options.create_if_missing = true;
3571
+ options.env = env_;
3572
+ DestroyAndReopen(options);
3573
+ ASSERT_OK(Put("a", "value"));
3574
+ ASSERT_OK(Flush());
3575
+ ASSERT_TRUE(db_->VerifyFileChecksums(ReadOptions()).IsInvalidArgument());
3576
+
3577
+ options.file_checksum_gen_factory = GetFileChecksumGenCrc32cFactory();
3578
+ Reopen(options);
3579
+ ASSERT_OK(db_->VerifyFileChecksums(ReadOptions()));
3580
+
3581
+ // Write an L0 with checksum computed.
3582
+ ASSERT_OK(Put("b", "value"));
3583
+ ASSERT_OK(Flush());
3584
+
3585
+ ASSERT_OK(db_->VerifyFileChecksums(ReadOptions()));
3586
+
3587
+ // Does the right thing but with the wrong name -- using it should lead to an
3588
+ // error.
3589
+ class MisnamedFileChecksumGenerator : public FileChecksumGenCrc32c {
3590
+ public:
3591
+ MisnamedFileChecksumGenerator(const FileChecksumGenContext& context)
3592
+ : FileChecksumGenCrc32c(context) {}
3593
+
3594
+ const char* Name() const override { return "sha1"; }
3595
+ };
3596
+
3597
+ class MisnamedFileChecksumGenFactory : public FileChecksumGenCrc32cFactory {
3598
+ public:
3599
+ std::unique_ptr<FileChecksumGenerator> CreateFileChecksumGenerator(
3600
+ const FileChecksumGenContext& context) override {
3601
+ return std::unique_ptr<FileChecksumGenerator>(
3602
+ new MisnamedFileChecksumGenerator(context));
3603
+ }
3604
+ };
3605
+
3606
+ options.file_checksum_gen_factory.reset(new MisnamedFileChecksumGenFactory());
3607
+ Reopen(options);
3608
+ ASSERT_TRUE(db_->VerifyFileChecksums(ReadOptions()).IsInvalidArgument());
3609
+ }
3610
+ #endif // !ROCKSDB_LITE
3611
+
3612
+ // A test class for intercepting random reads and injecting artificial
3613
+ // delays. Used for testing the deadline/timeout feature
3614
+ class DBBasicTestDeadline
3615
+ : public DBBasicTest,
3616
+ public testing::WithParamInterface<std::tuple<bool, bool>> {};
3617
+
3618
+ TEST_P(DBBasicTestDeadline, PointLookupDeadline) {
3619
+ std::shared_ptr<DeadlineFS> fs = std::make_shared<DeadlineFS>(env_, true);
3620
+ std::unique_ptr<Env> env(new CompositeEnvWrapper(env_, fs));
3621
+ bool set_deadline = std::get<0>(GetParam());
3622
+ bool set_timeout = std::get<1>(GetParam());
3623
+
3624
+ for (int option_config = kDefault; option_config < kEnd; ++option_config) {
3625
+ if (ShouldSkipOptions(option_config, kSkipPlainTable | kSkipMmapReads)) {
3626
+ continue;
3627
+ }
3628
+ option_config_ = option_config;
3629
+ Options options = CurrentOptions();
3630
+ if (options.use_direct_reads) {
3631
+ continue;
3632
+ }
3633
+ options.env = env.get();
3634
+ options.disable_auto_compactions = true;
3635
+ Cache* block_cache = nullptr;
3636
+ // Fileter block reads currently don't cause the request to get
3637
+ // aborted on a read timeout, so its possible those block reads
3638
+ // may get issued even if the deadline is past
3639
+ SyncPoint::GetInstance()->SetCallBack(
3640
+ "BlockBasedTable::Get:BeforeFilterMatch",
3641
+ [&](void* /*arg*/) { fs->IgnoreDeadline(true); });
3642
+ SyncPoint::GetInstance()->SetCallBack(
3643
+ "BlockBasedTable::Get:AfterFilterMatch",
3644
+ [&](void* /*arg*/) { fs->IgnoreDeadline(false); });
3645
+ // DB open will create table readers unless we reduce the table cache
3646
+ // capacity.
3647
+ // SanitizeOptions will set max_open_files to minimum of 20. Table cache
3648
+ // is allocated with max_open_files - 10 as capacity. So override
3649
+ // max_open_files to 11 so table cache capacity will become 1. This will
3650
+ // prevent file open during DB open and force the file to be opened
3651
+ // during MultiGet
3652
+ SyncPoint::GetInstance()->SetCallBack(
3653
+ "SanitizeOptions::AfterChangeMaxOpenFiles", [&](void* arg) {
3654
+ int* max_open_files = (int*)arg;
3655
+ *max_open_files = 11;
3656
+ });
3657
+ SyncPoint::GetInstance()->EnableProcessing();
3658
+
3659
+ SetTimeElapseOnlySleepOnReopen(&options);
3660
+ Reopen(options);
3661
+
3662
+ if (options.table_factory) {
3663
+ block_cache = options.table_factory->GetOptions<Cache>(
3664
+ TableFactory::kBlockCacheOpts());
3665
+ }
3666
+
3667
+ Random rnd(301);
3668
+ for (int i = 0; i < 400; ++i) {
3669
+ std::string key = "k" + ToString(i);
3670
+ ASSERT_OK(Put(key, rnd.RandomString(100)));
3671
+ }
3672
+ ASSERT_OK(Flush());
3673
+
3674
+ bool timedout = true;
3675
+ // A timeout will be forced when the IO counter reaches this value
3676
+ int io_deadline_trigger = 0;
3677
+ // Keep incrementing io_deadline_trigger and call Get() until there is an
3678
+ // iteration that doesn't cause a timeout. This ensures that we cover
3679
+ // all file reads in the point lookup path that can potentially timeout
3680
+ // and cause the Get() to fail.
3681
+ while (timedout) {
3682
+ ReadOptions ro;
3683
+ if (set_deadline) {
3684
+ ro.deadline = std::chrono::microseconds{env->NowMicros() + 10000};
3685
+ }
3686
+ if (set_timeout) {
3687
+ ro.io_timeout = std::chrono::microseconds{5000};
3688
+ }
3689
+ fs->SetDelayTrigger(ro.deadline, ro.io_timeout, io_deadline_trigger);
3690
+
3691
+ block_cache->SetCapacity(0);
3692
+ block_cache->SetCapacity(1048576);
3693
+
3694
+ std::string value;
3695
+ Status s = dbfull()->Get(ro, "k50", &value);
3696
+ if (fs->TimedOut()) {
3697
+ ASSERT_EQ(s, Status::TimedOut());
3698
+ } else {
3699
+ timedout = false;
3700
+ ASSERT_OK(s);
3701
+ }
3702
+ io_deadline_trigger++;
3703
+ }
3704
+ // Reset the delay sequence in order to avoid false alarms during Reopen
3705
+ fs->SetDelayTrigger(std::chrono::microseconds::zero(),
3706
+ std::chrono::microseconds::zero(), 0);
3707
+ }
3708
+ Close();
3709
+ }
3710
+
3711
+ TEST_P(DBBasicTestDeadline, IteratorDeadline) {
3712
+ std::shared_ptr<DeadlineFS> fs = std::make_shared<DeadlineFS>(env_, true);
3713
+ std::unique_ptr<Env> env(new CompositeEnvWrapper(env_, fs));
3714
+ bool set_deadline = std::get<0>(GetParam());
3715
+ bool set_timeout = std::get<1>(GetParam());
3716
+
3717
+ for (int option_config = kDefault; option_config < kEnd; ++option_config) {
3718
+ if (ShouldSkipOptions(option_config, kSkipPlainTable | kSkipMmapReads)) {
3719
+ continue;
3720
+ }
3721
+ Options options = CurrentOptions();
3722
+ if (options.use_direct_reads) {
3723
+ continue;
3724
+ }
3725
+ options.env = env.get();
3726
+ options.disable_auto_compactions = true;
3727
+ Cache* block_cache = nullptr;
3728
+ // DB open will create table readers unless we reduce the table cache
3729
+ // capacity.
3730
+ // SanitizeOptions will set max_open_files to minimum of 20. Table cache
3731
+ // is allocated with max_open_files - 10 as capacity. So override
3732
+ // max_open_files to 11 so table cache capacity will become 1. This will
3733
+ // prevent file open during DB open and force the file to be opened
3734
+ // during MultiGet
3735
+ SyncPoint::GetInstance()->SetCallBack(
3736
+ "SanitizeOptions::AfterChangeMaxOpenFiles", [&](void* arg) {
3737
+ int* max_open_files = (int*)arg;
3738
+ *max_open_files = 11;
3739
+ });
3740
+ SyncPoint::GetInstance()->EnableProcessing();
3741
+
3742
+ SetTimeElapseOnlySleepOnReopen(&options);
3743
+ Reopen(options);
3744
+
3745
+ if (options.table_factory) {
3746
+ block_cache = options.table_factory->GetOptions<Cache>(
3747
+ TableFactory::kBlockCacheOpts());
3748
+ }
3749
+
3750
+ Random rnd(301);
3751
+ for (int i = 0; i < 400; ++i) {
3752
+ std::string key = "k" + ToString(i);
3753
+ ASSERT_OK(Put(key, rnd.RandomString(100)));
3754
+ }
3755
+ ASSERT_OK(Flush());
3756
+
3757
+ bool timedout = true;
3758
+ // A timeout will be forced when the IO counter reaches this value
3759
+ int io_deadline_trigger = 0;
3760
+ // Keep incrementing io_deadline_trigger and call Get() until there is an
3761
+ // iteration that doesn't cause a timeout. This ensures that we cover
3762
+ // all file reads in the point lookup path that can potentially timeout
3763
+ while (timedout) {
3764
+ ReadOptions ro;
3765
+ if (set_deadline) {
3766
+ ro.deadline = std::chrono::microseconds{env->NowMicros() + 10000};
3767
+ }
3768
+ if (set_timeout) {
3769
+ ro.io_timeout = std::chrono::microseconds{5000};
3770
+ }
3771
+ fs->SetDelayTrigger(ro.deadline, ro.io_timeout, io_deadline_trigger);
3772
+
3773
+ block_cache->SetCapacity(0);
3774
+ block_cache->SetCapacity(1048576);
3775
+
3776
+ Iterator* iter = dbfull()->NewIterator(ro);
3777
+ int count = 0;
3778
+ iter->Seek("k50");
3779
+ while (iter->Valid() && count++ < 100) {
3780
+ iter->Next();
3781
+ }
3782
+ if (fs->TimedOut()) {
3783
+ ASSERT_FALSE(iter->Valid());
3784
+ ASSERT_EQ(iter->status(), Status::TimedOut());
3785
+ } else {
3786
+ timedout = false;
3787
+ ASSERT_OK(iter->status());
3788
+ }
3789
+ delete iter;
3790
+ io_deadline_trigger++;
3791
+ }
3792
+ // Reset the delay sequence in order to avoid false alarms during Reopen
3793
+ fs->SetDelayTrigger(std::chrono::microseconds::zero(),
3794
+ std::chrono::microseconds::zero(), 0);
3795
+ }
3796
+ Close();
3797
+ }
3798
+
3799
+ // Param 0: If true, set read_options.deadline
3800
+ // Param 1: If true, set read_options.io_timeout
3801
+ INSTANTIATE_TEST_CASE_P(DBBasicTestDeadline, DBBasicTestDeadline,
3802
+ ::testing::Values(std::make_tuple(true, false),
3803
+ std::make_tuple(false, true),
3804
+ std::make_tuple(true, true)));
3805
+ } // namespace ROCKSDB_NAMESPACE
3806
+
3807
+ #ifdef ROCKSDB_UNITTESTS_WITH_CUSTOM_OBJECTS_FROM_STATIC_LIBS
3808
+ extern "C" {
3809
+ void RegisterCustomObjects(int argc, char** argv);
3810
+ }
3811
+ #else
3812
+ void RegisterCustomObjects(int /*argc*/, char** /*argv*/) {}
3813
+ #endif // !ROCKSDB_UNITTESTS_WITH_CUSTOM_OBJECTS_FROM_STATIC_LIBS
3814
+
3815
+ int main(int argc, char** argv) {
3816
+ ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
3817
+ ::testing::InitGoogleTest(&argc, argv);
3818
+ RegisterCustomObjects(argc, argv);
3819
+ return RUN_ALL_TESTS();
3820
+ }