@nxtedition/rocksdb 7.0.5 → 7.0.6

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 (261) hide show
  1. package/binding.cc +320 -324
  2. package/chained-batch.js +6 -1
  3. package/deps/rocksdb/rocksdb/CMakeLists.txt +8 -3
  4. package/deps/rocksdb/rocksdb/Makefile +10 -4
  5. package/deps/rocksdb/rocksdb/TARGETS +6 -4
  6. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +9 -0
  7. package/deps/rocksdb/rocksdb/cache/cache_test.cc +14 -0
  8. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +8 -8
  9. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +272 -174
  10. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.h +201 -57
  11. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +19 -19
  12. package/deps/rocksdb/rocksdb/cache/lru_cache.h +2 -1
  13. package/deps/rocksdb/rocksdb/cmake/modules/CxxFlags.cmake +7 -0
  14. package/deps/rocksdb/rocksdb/cmake/modules/FindJeMalloc.cmake +29 -0
  15. package/deps/rocksdb/rocksdb/cmake/modules/FindNUMA.cmake +29 -0
  16. package/deps/rocksdb/rocksdb/cmake/modules/FindSnappy.cmake +29 -0
  17. package/deps/rocksdb/rocksdb/cmake/modules/FindTBB.cmake +33 -0
  18. package/deps/rocksdb/rocksdb/cmake/modules/Findgflags.cmake +29 -0
  19. package/deps/rocksdb/rocksdb/cmake/modules/Findlz4.cmake +29 -0
  20. package/deps/rocksdb/rocksdb/cmake/modules/Finduring.cmake +26 -0
  21. package/deps/rocksdb/rocksdb/cmake/modules/Findzstd.cmake +29 -0
  22. package/deps/rocksdb/rocksdb/cmake/modules/ReadVersion.cmake +10 -0
  23. package/deps/rocksdb/rocksdb/db/blob/blob_source.cc +170 -0
  24. package/deps/rocksdb/rocksdb/db/blob/blob_source.h +95 -0
  25. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +298 -0
  26. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +172 -0
  27. package/deps/rocksdb/rocksdb/db/column_family.cc +8 -3
  28. package/deps/rocksdb/rocksdb/db/column_family.h +6 -3
  29. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +10 -0
  30. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +6 -6
  31. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +22 -2
  32. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +38 -0
  33. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +17 -5
  34. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +4 -7
  35. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +74 -71
  36. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +70 -1
  37. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +13 -12
  38. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +36 -0
  39. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +11 -4
  40. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +1 -1
  41. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +139 -91
  42. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +48 -14
  43. package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +90 -55
  44. package/deps/rocksdb/rocksdb/db/db_rate_limiter_test.cc +9 -4
  45. package/deps/rocksdb/rocksdb/db/db_test.cc +3 -1
  46. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +12 -7
  47. package/deps/rocksdb/rocksdb/db/db_write_test.cc +35 -0
  48. package/deps/rocksdb/rocksdb/db/dbformat.cc +3 -1
  49. package/deps/rocksdb/rocksdb/db/dbformat.h +5 -3
  50. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +1 -1
  51. package/deps/rocksdb/rocksdb/db/memtable.cc +1 -0
  52. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +4 -2
  53. package/deps/rocksdb/rocksdb/db/repair.cc +1 -1
  54. package/deps/rocksdb/rocksdb/db/version_builder.cc +43 -1
  55. package/deps/rocksdb/rocksdb/db/version_edit.cc +13 -5
  56. package/deps/rocksdb/rocksdb/db/version_edit.h +22 -1
  57. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +4 -5
  58. package/deps/rocksdb/rocksdb/db/version_set.cc +109 -41
  59. package/deps/rocksdb/rocksdb/db/version_set.h +36 -3
  60. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +1 -4
  61. package/deps/rocksdb/rocksdb/db/version_set_test.cc +10 -10
  62. package/deps/rocksdb/rocksdb/db/version_util.h +1 -1
  63. package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +1 -1
  64. package/deps/rocksdb/rocksdb/db/write_batch.cc +34 -10
  65. package/deps/rocksdb/rocksdb/db/write_batch_internal.h +2 -0
  66. package/deps/rocksdb/rocksdb/db/write_callback_test.cc +4 -0
  67. package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +2 -0
  68. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +4 -1
  69. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +1 -1
  70. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +7 -5
  71. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +5 -10
  72. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +0 -7
  73. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +2 -0
  74. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +24 -3
  75. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +8 -0
  76. package/deps/rocksdb/rocksdb/file/writable_file_writer.h +10 -0
  77. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +5 -0
  78. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +4 -4
  79. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +9 -5
  80. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +5 -0
  81. package/deps/rocksdb/rocksdb/include/rocksdb/types.h +1 -0
  82. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/write_batch_with_index.h +1 -1
  83. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +1 -1
  84. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +0 -3
  85. package/deps/rocksdb/rocksdb/microbench/ribbon_bench.cc +8 -6
  86. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +3 -1
  87. package/deps/rocksdb/rocksdb/options/options_helper.cc +4 -2
  88. package/deps/rocksdb/rocksdb/options/options_test.cc +1 -11
  89. package/deps/rocksdb/rocksdb/port/port_posix.h +7 -0
  90. package/deps/rocksdb/rocksdb/port/win/port_win.h +11 -3
  91. package/deps/rocksdb/rocksdb/src.mk +6 -2
  92. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +4 -33
  93. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +3 -3
  94. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +38 -118
  95. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +6 -8
  96. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +10 -13
  97. package/deps/rocksdb/rocksdb/table/block_based/block_like_traits.h +4 -9
  98. package/deps/rocksdb/rocksdb/table/block_based/block_type.h +0 -1
  99. package/deps/rocksdb/rocksdb/table/block_based/filter_block.h +10 -28
  100. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +2 -3
  101. package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +0 -91
  102. package/deps/rocksdb/rocksdb/table/block_based/filter_policy_internal.h +2 -30
  103. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +6 -27
  104. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.h +11 -13
  105. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +28 -40
  106. package/deps/rocksdb/rocksdb/table/block_based/mock_block_based_table.h +0 -1
  107. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +22 -43
  108. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +11 -22
  109. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +24 -25
  110. package/deps/rocksdb/rocksdb/table/block_fetcher.cc +0 -1
  111. package/deps/rocksdb/rocksdb/table/get_context.h +0 -1
  112. package/deps/rocksdb/rocksdb/table/table_test.cc +3 -18
  113. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +3 -16
  114. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +3 -3
  115. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +1 -1
  116. package/deps/rocksdb/rocksdb/util/bloom_test.cc +0 -201
  117. package/deps/rocksdb/rocksdb/util/distributed_mutex.h +48 -0
  118. package/deps/rocksdb/rocksdb/util/filter_bench.cc +5 -11
  119. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +3 -0
  120. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +7 -21
  121. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.h +1 -1
  122. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +45 -0
  123. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.h +21 -14
  124. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +10 -1
  125. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +3 -1
  126. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.cc +9 -0
  127. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn.cc +3 -2
  128. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn_db.cc +3 -1
  129. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +5 -4
  130. package/deps/rocksdb/rocksdb.gyp +1 -1
  131. package/index.js +36 -14
  132. package/package-lock.json +23687 -0
  133. package/package.json +1 -1
  134. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  135. package/prebuilds/linux-x64/node.napi.node +0 -0
  136. package/deps/liburing/liburing/README +0 -46
  137. package/deps/liburing/liburing/test/232c93d07b74-test.c +0 -305
  138. package/deps/liburing/liburing/test/35fa71a030ca-test.c +0 -329
  139. package/deps/liburing/liburing/test/500f9fbadef8-test.c +0 -89
  140. package/deps/liburing/liburing/test/7ad0e4b2f83c-test.c +0 -93
  141. package/deps/liburing/liburing/test/8a9973408177-test.c +0 -106
  142. package/deps/liburing/liburing/test/917257daa0fe-test.c +0 -53
  143. package/deps/liburing/liburing/test/Makefile +0 -312
  144. package/deps/liburing/liburing/test/a0908ae19763-test.c +0 -58
  145. package/deps/liburing/liburing/test/a4c0b3decb33-test.c +0 -180
  146. package/deps/liburing/liburing/test/accept-link.c +0 -251
  147. package/deps/liburing/liburing/test/accept-reuse.c +0 -164
  148. package/deps/liburing/liburing/test/accept-test.c +0 -79
  149. package/deps/liburing/liburing/test/accept.c +0 -476
  150. package/deps/liburing/liburing/test/across-fork.c +0 -283
  151. package/deps/liburing/liburing/test/b19062a56726-test.c +0 -53
  152. package/deps/liburing/liburing/test/b5837bd5311d-test.c +0 -77
  153. package/deps/liburing/liburing/test/ce593a6c480a-test.c +0 -135
  154. package/deps/liburing/liburing/test/close-opath.c +0 -122
  155. package/deps/liburing/liburing/test/config +0 -10
  156. package/deps/liburing/liburing/test/connect.c +0 -398
  157. package/deps/liburing/liburing/test/cq-full.c +0 -96
  158. package/deps/liburing/liburing/test/cq-overflow.c +0 -294
  159. package/deps/liburing/liburing/test/cq-peek-batch.c +0 -102
  160. package/deps/liburing/liburing/test/cq-ready.c +0 -94
  161. package/deps/liburing/liburing/test/cq-size.c +0 -58
  162. package/deps/liburing/liburing/test/d4ae271dfaae-test.c +0 -96
  163. package/deps/liburing/liburing/test/d77a67ed5f27-test.c +0 -65
  164. package/deps/liburing/liburing/test/defer.c +0 -307
  165. package/deps/liburing/liburing/test/double-poll-crash.c +0 -186
  166. package/deps/liburing/liburing/test/eeed8b54e0df-test.c +0 -114
  167. package/deps/liburing/liburing/test/empty-eownerdead.c +0 -42
  168. package/deps/liburing/liburing/test/eventfd-disable.c +0 -151
  169. package/deps/liburing/liburing/test/eventfd-ring.c +0 -97
  170. package/deps/liburing/liburing/test/eventfd.c +0 -112
  171. package/deps/liburing/liburing/test/fadvise.c +0 -202
  172. package/deps/liburing/liburing/test/fallocate.c +0 -249
  173. package/deps/liburing/liburing/test/fc2a85cb02ef-test.c +0 -138
  174. package/deps/liburing/liburing/test/file-register.c +0 -843
  175. package/deps/liburing/liburing/test/file-update.c +0 -173
  176. package/deps/liburing/liburing/test/files-exit-hang-poll.c +0 -128
  177. package/deps/liburing/liburing/test/files-exit-hang-timeout.c +0 -134
  178. package/deps/liburing/liburing/test/fixed-link.c +0 -90
  179. package/deps/liburing/liburing/test/fsync.c +0 -224
  180. package/deps/liburing/liburing/test/hardlink.c +0 -136
  181. package/deps/liburing/liburing/test/helpers.c +0 -135
  182. package/deps/liburing/liburing/test/helpers.h +0 -67
  183. package/deps/liburing/liburing/test/io-cancel.c +0 -537
  184. package/deps/liburing/liburing/test/io_uring_enter.c +0 -296
  185. package/deps/liburing/liburing/test/io_uring_register.c +0 -664
  186. package/deps/liburing/liburing/test/io_uring_setup.c +0 -192
  187. package/deps/liburing/liburing/test/iopoll.c +0 -366
  188. package/deps/liburing/liburing/test/lfs-openat-write.c +0 -117
  189. package/deps/liburing/liburing/test/lfs-openat.c +0 -273
  190. package/deps/liburing/liburing/test/link-timeout.c +0 -1107
  191. package/deps/liburing/liburing/test/link.c +0 -496
  192. package/deps/liburing/liburing/test/link_drain.c +0 -229
  193. package/deps/liburing/liburing/test/madvise.c +0 -195
  194. package/deps/liburing/liburing/test/mkdir.c +0 -108
  195. package/deps/liburing/liburing/test/multicqes_drain.c +0 -383
  196. package/deps/liburing/liburing/test/nop-all-sizes.c +0 -107
  197. package/deps/liburing/liburing/test/nop.c +0 -115
  198. package/deps/liburing/liburing/test/open-close.c +0 -146
  199. package/deps/liburing/liburing/test/openat2.c +0 -240
  200. package/deps/liburing/liburing/test/personality.c +0 -204
  201. package/deps/liburing/liburing/test/pipe-eof.c +0 -81
  202. package/deps/liburing/liburing/test/pipe-reuse.c +0 -105
  203. package/deps/liburing/liburing/test/poll-cancel-ton.c +0 -139
  204. package/deps/liburing/liburing/test/poll-cancel.c +0 -135
  205. package/deps/liburing/liburing/test/poll-link.c +0 -227
  206. package/deps/liburing/liburing/test/poll-many.c +0 -208
  207. package/deps/liburing/liburing/test/poll-mshot-update.c +0 -273
  208. package/deps/liburing/liburing/test/poll-ring.c +0 -48
  209. package/deps/liburing/liburing/test/poll-v-poll.c +0 -353
  210. package/deps/liburing/liburing/test/poll.c +0 -109
  211. package/deps/liburing/liburing/test/probe.c +0 -137
  212. package/deps/liburing/liburing/test/read-write.c +0 -876
  213. package/deps/liburing/liburing/test/register-restrictions.c +0 -633
  214. package/deps/liburing/liburing/test/rename.c +0 -134
  215. package/deps/liburing/liburing/test/ring-leak.c +0 -173
  216. package/deps/liburing/liburing/test/ring-leak2.c +0 -249
  217. package/deps/liburing/liburing/test/rsrc_tags.c +0 -449
  218. package/deps/liburing/liburing/test/runtests-loop.sh +0 -16
  219. package/deps/liburing/liburing/test/runtests.sh +0 -170
  220. package/deps/liburing/liburing/test/rw_merge_test.c +0 -97
  221. package/deps/liburing/liburing/test/self.c +0 -91
  222. package/deps/liburing/liburing/test/send_recv.c +0 -291
  223. package/deps/liburing/liburing/test/send_recvmsg.c +0 -345
  224. package/deps/liburing/liburing/test/sendmsg_fs_cve.c +0 -198
  225. package/deps/liburing/liburing/test/shared-wq.c +0 -84
  226. package/deps/liburing/liburing/test/short-read.c +0 -75
  227. package/deps/liburing/liburing/test/shutdown.c +0 -163
  228. package/deps/liburing/liburing/test/sigfd-deadlock.c +0 -74
  229. package/deps/liburing/liburing/test/socket-rw-eagain.c +0 -156
  230. package/deps/liburing/liburing/test/socket-rw.c +0 -147
  231. package/deps/liburing/liburing/test/splice.c +0 -511
  232. package/deps/liburing/liburing/test/sq-full-cpp.cc +0 -45
  233. package/deps/liburing/liburing/test/sq-full.c +0 -45
  234. package/deps/liburing/liburing/test/sq-poll-dup.c +0 -200
  235. package/deps/liburing/liburing/test/sq-poll-kthread.c +0 -168
  236. package/deps/liburing/liburing/test/sq-poll-share.c +0 -137
  237. package/deps/liburing/liburing/test/sq-space_left.c +0 -159
  238. package/deps/liburing/liburing/test/sqpoll-cancel-hang.c +0 -159
  239. package/deps/liburing/liburing/test/sqpoll-disable-exit.c +0 -195
  240. package/deps/liburing/liburing/test/sqpoll-exit-hang.c +0 -77
  241. package/deps/liburing/liburing/test/sqpoll-sleep.c +0 -68
  242. package/deps/liburing/liburing/test/statx.c +0 -172
  243. package/deps/liburing/liburing/test/stdout.c +0 -232
  244. package/deps/liburing/liburing/test/submit-link-fail.c +0 -154
  245. package/deps/liburing/liburing/test/submit-reuse.c +0 -239
  246. package/deps/liburing/liburing/test/symlink.c +0 -116
  247. package/deps/liburing/liburing/test/teardowns.c +0 -58
  248. package/deps/liburing/liburing/test/thread-exit.c +0 -131
  249. package/deps/liburing/liburing/test/timeout-new.c +0 -246
  250. package/deps/liburing/liburing/test/timeout-overflow.c +0 -204
  251. package/deps/liburing/liburing/test/timeout.c +0 -1354
  252. package/deps/liburing/liburing/test/unlink.c +0 -111
  253. package/deps/liburing/liburing/test/wakeup-hang.c +0 -162
  254. package/deps/rocksdb/rocksdb/README.md +0 -32
  255. package/deps/rocksdb/rocksdb/microbench/README.md +0 -60
  256. package/deps/rocksdb/rocksdb/plugin/README.md +0 -43
  257. package/deps/rocksdb/rocksdb/port/README +0 -10
  258. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.cc +0 -358
  259. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.h +0 -127
  260. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block_test.cc +0 -219
  261. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/README +0 -13
@@ -0,0 +1,298 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
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
+ #include "db/blob/blob_source.h"
7
+
8
+ #include <cassert>
9
+ #include <cstdint>
10
+ #include <cstdio>
11
+ #include <memory>
12
+ #include <string>
13
+
14
+ #include "db/blob/blob_file_cache.h"
15
+ #include "db/blob/blob_log_format.h"
16
+ #include "db/blob/blob_log_writer.h"
17
+ #include "db/db_test_util.h"
18
+ #include "file/filename.h"
19
+ #include "file/read_write_util.h"
20
+ #include "options/cf_options.h"
21
+ #include "rocksdb/options.h"
22
+ #include "util/compression.h"
23
+
24
+ namespace ROCKSDB_NAMESPACE {
25
+
26
+ namespace {
27
+
28
+ // Creates a test blob file with `num` blobs in it.
29
+ void WriteBlobFile(const ImmutableOptions& immutable_options,
30
+ uint32_t column_family_id, bool has_ttl,
31
+ const ExpirationRange& expiration_range_header,
32
+ const ExpirationRange& expiration_range_footer,
33
+ uint64_t blob_file_number, const std::vector<Slice>& keys,
34
+ const std::vector<Slice>& blobs, CompressionType compression,
35
+ std::vector<uint64_t>& blob_offsets,
36
+ std::vector<uint64_t>& blob_sizes) {
37
+ assert(!immutable_options.cf_paths.empty());
38
+ size_t num = keys.size();
39
+ assert(num == blobs.size());
40
+ assert(num == blob_offsets.size());
41
+ assert(num == blob_sizes.size());
42
+
43
+ const std::string blob_file_path =
44
+ BlobFileName(immutable_options.cf_paths.front().path, blob_file_number);
45
+ std::unique_ptr<FSWritableFile> file;
46
+ ASSERT_OK(NewWritableFile(immutable_options.fs.get(), blob_file_path, &file,
47
+ FileOptions()));
48
+
49
+ std::unique_ptr<WritableFileWriter> file_writer(new WritableFileWriter(
50
+ std::move(file), blob_file_path, FileOptions(), immutable_options.clock));
51
+
52
+ constexpr Statistics* statistics = nullptr;
53
+ constexpr bool use_fsync = false;
54
+ constexpr bool do_flush = false;
55
+
56
+ BlobLogWriter blob_log_writer(std::move(file_writer), immutable_options.clock,
57
+ statistics, blob_file_number, use_fsync,
58
+ do_flush);
59
+
60
+ BlobLogHeader header(column_family_id, compression, has_ttl,
61
+ expiration_range_header);
62
+
63
+ ASSERT_OK(blob_log_writer.WriteHeader(header));
64
+
65
+ std::vector<std::string> compressed_blobs(num);
66
+ std::vector<Slice> blobs_to_write(num);
67
+ if (kNoCompression == compression) {
68
+ for (size_t i = 0; i < num; ++i) {
69
+ blobs_to_write[i] = blobs[i];
70
+ blob_sizes[i] = blobs[i].size();
71
+ }
72
+ } else {
73
+ CompressionOptions opts;
74
+ CompressionContext context(compression);
75
+ constexpr uint64_t sample_for_compression = 0;
76
+ CompressionInfo info(opts, context, CompressionDict::GetEmptyDict(),
77
+ compression, sample_for_compression);
78
+
79
+ constexpr uint32_t compression_format_version = 2;
80
+
81
+ for (size_t i = 0; i < num; ++i) {
82
+ ASSERT_TRUE(CompressData(blobs[i], info, compression_format_version,
83
+ &compressed_blobs[i]));
84
+ blobs_to_write[i] = compressed_blobs[i];
85
+ blob_sizes[i] = compressed_blobs[i].size();
86
+ }
87
+ }
88
+
89
+ for (size_t i = 0; i < num; ++i) {
90
+ uint64_t key_offset = 0;
91
+ ASSERT_OK(blob_log_writer.AddRecord(keys[i], blobs_to_write[i], &key_offset,
92
+ &blob_offsets[i]));
93
+ }
94
+
95
+ BlobLogFooter footer;
96
+ footer.blob_count = num;
97
+ footer.expiration_range = expiration_range_footer;
98
+
99
+ std::string checksum_method;
100
+ std::string checksum_value;
101
+ ASSERT_OK(
102
+ blob_log_writer.AppendFooter(footer, &checksum_method, &checksum_value));
103
+ }
104
+
105
+ } // anonymous namespace
106
+
107
+ class BlobSourceTest : public DBTestBase {
108
+ protected:
109
+ public:
110
+ explicit BlobSourceTest()
111
+ : DBTestBase("blob_source_test", /*env_do_fsync=*/true) {}
112
+ };
113
+
114
+ TEST_F(BlobSourceTest, GetBlobsFromCache) {
115
+ Options options;
116
+ options.env = env_;
117
+ options.cf_paths.emplace_back(
118
+ test::PerThreadDBPath(env_, "BlobSourceTest_GetBlobsFromCache"), 0);
119
+ options.enable_blob_files = true;
120
+
121
+ LRUCacheOptions co;
122
+ co.capacity = 2048;
123
+ co.num_shard_bits = 2;
124
+ co.metadata_charge_policy = kDontChargeCacheMetadata;
125
+ options.blob_cache = NewLRUCache(co);
126
+ options.lowest_used_cache_tier = CacheTier::kVolatileTier;
127
+
128
+ Reopen(options);
129
+
130
+ std::string db_id;
131
+ ASSERT_OK(db_->GetDbIdentity(db_id));
132
+
133
+ std::string db_session_id;
134
+ ASSERT_OK(db_->GetDbSessionId(db_session_id));
135
+
136
+ ImmutableOptions immutable_options(options);
137
+
138
+ constexpr uint32_t column_family_id = 1;
139
+ constexpr bool has_ttl = false;
140
+ constexpr ExpirationRange expiration_range;
141
+ constexpr uint64_t blob_file_number = 1;
142
+ constexpr size_t num_blobs = 16;
143
+
144
+ std::vector<std::string> key_strs;
145
+ std::vector<std::string> blob_strs;
146
+
147
+ for (size_t i = 0; i < num_blobs; ++i) {
148
+ key_strs.push_back("key" + std::to_string(i));
149
+ blob_strs.push_back("blob" + std::to_string(i));
150
+ }
151
+
152
+ std::vector<Slice> keys;
153
+ std::vector<Slice> blobs;
154
+
155
+ uint64_t file_size = BlobLogHeader::kSize;
156
+ for (size_t i = 0; i < num_blobs; ++i) {
157
+ keys.push_back({key_strs[i]});
158
+ blobs.push_back({blob_strs[i]});
159
+ file_size += BlobLogRecord::kHeaderSize + keys[i].size() + blobs[i].size();
160
+ }
161
+ file_size += BlobLogFooter::kSize;
162
+
163
+ std::vector<uint64_t> blob_offsets(keys.size());
164
+ std::vector<uint64_t> blob_sizes(keys.size());
165
+
166
+ WriteBlobFile(immutable_options, column_family_id, has_ttl, expiration_range,
167
+ expiration_range, blob_file_number, keys, blobs, kNoCompression,
168
+ blob_offsets, blob_sizes);
169
+
170
+ constexpr size_t capacity = 1024;
171
+ std::shared_ptr<Cache> backing_cache =
172
+ NewLRUCache(capacity); // Blob file cache
173
+
174
+ FileOptions file_options;
175
+ constexpr HistogramImpl* blob_file_read_hist = nullptr;
176
+
177
+ std::unique_ptr<BlobFileCache> blob_file_cache(new BlobFileCache(
178
+ backing_cache.get(), &immutable_options, &file_options, column_family_id,
179
+ blob_file_read_hist, nullptr /*IOTracer*/));
180
+
181
+ BlobSource blob_source(&immutable_options, db_id, db_session_id,
182
+ blob_file_cache.get());
183
+
184
+ ReadOptions read_options;
185
+ read_options.verify_checksums = true;
186
+
187
+ constexpr FilePrefetchBuffer* prefetch_buffer = nullptr;
188
+
189
+ {
190
+ // GetBlob
191
+ std::vector<PinnableSlice> values(keys.size());
192
+ uint64_t bytes_read = 0;
193
+
194
+ read_options.fill_cache = false;
195
+
196
+ for (size_t i = 0; i < num_blobs; ++i) {
197
+ ASSERT_FALSE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
198
+ blob_offsets[i]));
199
+
200
+ ASSERT_OK(blob_source.GetBlob(read_options, keys[i], blob_file_number,
201
+ blob_offsets[i], file_size, blob_sizes[i],
202
+ kNoCompression, prefetch_buffer, &values[i],
203
+ &bytes_read));
204
+ ASSERT_EQ(values[i], blobs[i]);
205
+ ASSERT_EQ(bytes_read,
206
+ blob_sizes[i] + keys[i].size() + BlobLogRecord::kHeaderSize);
207
+
208
+ ASSERT_FALSE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
209
+ blob_offsets[i]));
210
+ }
211
+
212
+ read_options.fill_cache = true;
213
+
214
+ for (size_t i = 0; i < num_blobs; ++i) {
215
+ ASSERT_FALSE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
216
+ blob_offsets[i]));
217
+
218
+ ASSERT_OK(blob_source.GetBlob(read_options, keys[i], blob_file_number,
219
+ blob_offsets[i], file_size, blob_sizes[i],
220
+ kNoCompression, prefetch_buffer, &values[i],
221
+ &bytes_read));
222
+ ASSERT_EQ(values[i], blobs[i]);
223
+ ASSERT_EQ(bytes_read,
224
+ blob_sizes[i] + keys[i].size() + BlobLogRecord::kHeaderSize);
225
+
226
+ ASSERT_TRUE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
227
+ blob_offsets[i]));
228
+ }
229
+
230
+ read_options.fill_cache = true;
231
+
232
+ for (size_t i = 0; i < num_blobs; ++i) {
233
+ ASSERT_TRUE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
234
+ blob_offsets[i]));
235
+
236
+ ASSERT_OK(blob_source.GetBlob(read_options, keys[i], blob_file_number,
237
+ blob_offsets[i], file_size, blob_sizes[i],
238
+ kNoCompression, prefetch_buffer, &values[i],
239
+ &bytes_read));
240
+ ASSERT_EQ(values[i], blobs[i]);
241
+ ASSERT_EQ(bytes_read, blob_sizes[i]);
242
+
243
+ ASSERT_TRUE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
244
+ blob_offsets[i]));
245
+ }
246
+
247
+ // Cache-only GetBlob
248
+ read_options.read_tier = ReadTier::kBlockCacheTier;
249
+
250
+ for (size_t i = 0; i < num_blobs; ++i) {
251
+ ASSERT_TRUE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
252
+ blob_offsets[i]));
253
+
254
+ ASSERT_OK(blob_source.GetBlob(read_options, keys[i], blob_file_number,
255
+ blob_offsets[i], file_size, blob_sizes[i],
256
+ kNoCompression, prefetch_buffer, &values[i],
257
+ &bytes_read));
258
+ ASSERT_EQ(values[i], blobs[i]);
259
+ ASSERT_EQ(bytes_read, blob_sizes[i]);
260
+
261
+ ASSERT_TRUE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
262
+ blob_offsets[i]));
263
+ }
264
+ }
265
+
266
+ options.blob_cache->EraseUnRefEntries();
267
+
268
+ {
269
+ // Cache-only GetBlob
270
+ std::vector<PinnableSlice> values(keys.size());
271
+ uint64_t bytes_read = 0;
272
+
273
+ read_options.read_tier = ReadTier::kBlockCacheTier;
274
+ read_options.fill_cache = true;
275
+
276
+ for (size_t i = 0; i < num_blobs; ++i) {
277
+ ASSERT_FALSE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
278
+ blob_offsets[i]));
279
+
280
+ ASSERT_NOK(blob_source.GetBlob(read_options, keys[i], blob_file_number,
281
+ blob_offsets[i], file_size, blob_sizes[i],
282
+ kNoCompression, prefetch_buffer,
283
+ &values[i], &bytes_read));
284
+ ASSERT_TRUE(values[i].empty());
285
+ ASSERT_EQ(bytes_read, 0);
286
+
287
+ ASSERT_FALSE(blob_source.TEST_BlobInCache(blob_file_number, file_size,
288
+ blob_offsets[i]));
289
+ }
290
+ }
291
+ }
292
+
293
+ } // namespace ROCKSDB_NAMESPACE
294
+
295
+ int main(int argc, char** argv) {
296
+ ::testing::InitGoogleTest(&argc, argv);
297
+ return RUN_ALL_TESTS();
298
+ }
@@ -5,6 +5,7 @@
5
5
 
6
6
  #include <array>
7
7
  #include <sstream>
8
+ #include <string>
8
9
 
9
10
  #include "db/blob/blob_index.h"
10
11
  #include "db/blob/blob_log_format.h"
@@ -48,6 +49,177 @@ TEST_F(DBBlobBasicTest, GetBlob) {
48
49
  .IsIncomplete());
49
50
  }
50
51
 
52
+ TEST_F(DBBlobBasicTest, GetBlobFromCache) {
53
+ Options options = GetDefaultOptions();
54
+
55
+ LRUCacheOptions co;
56
+ co.capacity = 2048;
57
+ co.num_shard_bits = 2;
58
+ co.metadata_charge_policy = kDontChargeCacheMetadata;
59
+ auto backing_cache = NewLRUCache(co);
60
+
61
+ options.enable_blob_files = true;
62
+ options.blob_cache = backing_cache;
63
+
64
+ BlockBasedTableOptions block_based_options;
65
+ block_based_options.no_block_cache = false;
66
+ block_based_options.block_cache = backing_cache;
67
+ block_based_options.cache_index_and_filter_blocks = true;
68
+ options.table_factory.reset(NewBlockBasedTableFactory(block_based_options));
69
+
70
+ Reopen(options);
71
+
72
+ constexpr char key[] = "key";
73
+ constexpr char blob_value[] = "blob_value";
74
+
75
+ ASSERT_OK(Put(key, blob_value));
76
+
77
+ ASSERT_OK(Flush());
78
+
79
+ ReadOptions read_options;
80
+
81
+ read_options.fill_cache = false;
82
+
83
+ {
84
+ PinnableSlice result;
85
+
86
+ read_options.read_tier = kReadAllTier;
87
+ ASSERT_OK(db_->Get(read_options, db_->DefaultColumnFamily(), key, &result));
88
+ ASSERT_EQ(result, blob_value);
89
+
90
+ result.Reset();
91
+ read_options.read_tier = kBlockCacheTier;
92
+
93
+ // Try again with no I/O allowed. Since we didn't re-fill the cache, the
94
+ // blob itself can only be read from the blob file, so the read should
95
+ // return Incomplete.
96
+ ASSERT_TRUE(db_->Get(read_options, db_->DefaultColumnFamily(), key, &result)
97
+ .IsIncomplete());
98
+ ASSERT_TRUE(result.empty());
99
+ }
100
+
101
+ read_options.fill_cache = true;
102
+
103
+ {
104
+ PinnableSlice result;
105
+
106
+ read_options.read_tier = kReadAllTier;
107
+ ASSERT_OK(db_->Get(read_options, db_->DefaultColumnFamily(), key, &result));
108
+ ASSERT_EQ(result, blob_value);
109
+
110
+ result.Reset();
111
+ read_options.read_tier = kBlockCacheTier;
112
+
113
+ // Try again with no I/O allowed. The table and the necessary blocks/blobs
114
+ // should already be in their respective caches.
115
+ ASSERT_OK(db_->Get(read_options, db_->DefaultColumnFamily(), key, &result));
116
+ ASSERT_EQ(result, blob_value);
117
+ }
118
+ }
119
+
120
+ TEST_F(DBBlobBasicTest, IterateBlobsFromCache) {
121
+ Options options = GetDefaultOptions();
122
+
123
+ LRUCacheOptions co;
124
+ co.capacity = 2048;
125
+ co.num_shard_bits = 2;
126
+ co.metadata_charge_policy = kDontChargeCacheMetadata;
127
+ auto backing_cache = NewLRUCache(co);
128
+
129
+ options.enable_blob_files = true;
130
+ options.blob_cache = backing_cache;
131
+
132
+ BlockBasedTableOptions block_based_options;
133
+ block_based_options.no_block_cache = false;
134
+ block_based_options.block_cache = backing_cache;
135
+ block_based_options.cache_index_and_filter_blocks = true;
136
+ options.table_factory.reset(NewBlockBasedTableFactory(block_based_options));
137
+
138
+ Reopen(options);
139
+
140
+ int num_blobs = 5;
141
+ std::vector<std::string> keys;
142
+ std::vector<std::string> blobs;
143
+
144
+ for (int i = 0; i < num_blobs; ++i) {
145
+ keys.push_back("key" + std::to_string(i));
146
+ blobs.push_back("blob" + std::to_string(i));
147
+ ASSERT_OK(Put(keys[i], blobs[i]));
148
+ }
149
+ ASSERT_OK(Flush());
150
+
151
+ ReadOptions read_options;
152
+
153
+ {
154
+ read_options.fill_cache = false;
155
+ read_options.read_tier = kReadAllTier;
156
+
157
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
158
+ ASSERT_OK(iter->status());
159
+
160
+ int i = 0;
161
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
162
+ ASSERT_OK(iter->status());
163
+ ASSERT_EQ(iter->key().ToString(), keys[i]);
164
+ ASSERT_EQ(iter->value().ToString(), blobs[i]);
165
+ ++i;
166
+ }
167
+ ASSERT_EQ(i, num_blobs);
168
+ }
169
+
170
+ {
171
+ read_options.fill_cache = false;
172
+ read_options.read_tier = kBlockCacheTier;
173
+
174
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
175
+ ASSERT_OK(iter->status());
176
+
177
+ // Try again with no I/O allowed. Since we didn't re-fill the cache,
178
+ // the blob itself can only be read from the blob file, so iter->Valid()
179
+ // should be false.
180
+ iter->SeekToFirst();
181
+ ASSERT_NOK(iter->status());
182
+ ASSERT_FALSE(iter->Valid());
183
+ }
184
+
185
+ {
186
+ read_options.fill_cache = true;
187
+ read_options.read_tier = kReadAllTier;
188
+
189
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
190
+ ASSERT_OK(iter->status());
191
+
192
+ // Read blobs from the file and refill the cache.
193
+ int i = 0;
194
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
195
+ ASSERT_OK(iter->status());
196
+ ASSERT_EQ(iter->key().ToString(), keys[i]);
197
+ ASSERT_EQ(iter->value().ToString(), blobs[i]);
198
+ ++i;
199
+ }
200
+ ASSERT_EQ(i, num_blobs);
201
+ }
202
+
203
+ {
204
+ read_options.fill_cache = false;
205
+ read_options.read_tier = kBlockCacheTier;
206
+
207
+ std::unique_ptr<Iterator> iter(db_->NewIterator(read_options));
208
+ ASSERT_OK(iter->status());
209
+
210
+ // Try again with no I/O allowed. The table and the necessary blocks/blobs
211
+ // should already be in their respective caches.
212
+ int i = 0;
213
+ for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
214
+ ASSERT_OK(iter->status());
215
+ ASSERT_EQ(iter->key().ToString(), keys[i]);
216
+ ASSERT_EQ(iter->value().ToString(), blobs[i]);
217
+ ++i;
218
+ }
219
+ ASSERT_EQ(i, num_blobs);
220
+ }
221
+ }
222
+
51
223
  TEST_F(DBBlobBasicTest, MultiGetBlobs) {
52
224
  constexpr size_t min_blob_size = 6;
53
225
 
@@ -17,6 +17,7 @@
17
17
  #include <vector>
18
18
 
19
19
  #include "db/blob/blob_file_cache.h"
20
+ #include "db/blob/blob_source.h"
20
21
  #include "db/compaction/compaction_picker.h"
21
22
  #include "db/compaction/compaction_picker_fifo.h"
22
23
  #include "db/compaction/compaction_picker_level.h"
@@ -516,7 +517,7 @@ ColumnFamilyData::ColumnFamilyData(
516
517
  const ColumnFamilyOptions& cf_options, const ImmutableDBOptions& db_options,
517
518
  const FileOptions* file_options, ColumnFamilySet* column_family_set,
518
519
  BlockCacheTracer* const block_cache_tracer,
519
- const std::shared_ptr<IOTracer>& io_tracer,
520
+ const std::shared_ptr<IOTracer>& io_tracer, const std::string& db_id,
520
521
  const std::string& db_session_id)
521
522
  : id_(id),
522
523
  name_(name),
@@ -580,6 +581,8 @@ ColumnFamilyData::ColumnFamilyData(
580
581
  blob_file_cache_.reset(
581
582
  new BlobFileCache(_table_cache, ioptions(), soptions(), id_,
582
583
  internal_stats_->GetBlobFileReadHist(), io_tracer));
584
+ blob_source_.reset(new BlobSource(ioptions(), db_id, db_session_id,
585
+ blob_file_cache_.get()));
583
586
 
584
587
  if (ioptions_.compaction_style == kCompactionStyleLevel) {
585
588
  compaction_picker_.reset(
@@ -1504,13 +1507,14 @@ ColumnFamilySet::ColumnFamilySet(const std::string& dbname,
1504
1507
  WriteController* _write_controller,
1505
1508
  BlockCacheTracer* const block_cache_tracer,
1506
1509
  const std::shared_ptr<IOTracer>& io_tracer,
1510
+ const std::string& db_id,
1507
1511
  const std::string& db_session_id)
1508
1512
  : max_column_family_(0),
1509
1513
  file_options_(file_options),
1510
1514
  dummy_cfd_(new ColumnFamilyData(
1511
1515
  ColumnFamilyData::kDummyColumnFamilyDataId, "", nullptr, nullptr,
1512
1516
  nullptr, ColumnFamilyOptions(), *db_options, &file_options_, nullptr,
1513
- block_cache_tracer, io_tracer, db_session_id)),
1517
+ block_cache_tracer, io_tracer, db_id, db_session_id)),
1514
1518
  default_cfd_cache_(nullptr),
1515
1519
  db_name_(dbname),
1516
1520
  db_options_(db_options),
@@ -1519,6 +1523,7 @@ ColumnFamilySet::ColumnFamilySet(const std::string& dbname,
1519
1523
  write_controller_(_write_controller),
1520
1524
  block_cache_tracer_(block_cache_tracer),
1521
1525
  io_tracer_(io_tracer),
1526
+ db_id_(db_id),
1522
1527
  db_session_id_(db_session_id) {
1523
1528
  // initialize linked list
1524
1529
  dummy_cfd_->prev_ = dummy_cfd_;
@@ -1586,7 +1591,7 @@ ColumnFamilyData* ColumnFamilySet::CreateColumnFamily(
1586
1591
  ColumnFamilyData* new_cfd = new ColumnFamilyData(
1587
1592
  id, name, dummy_versions, table_cache_, write_buffer_manager_, options,
1588
1593
  *db_options_, &file_options_, this, block_cache_tracer_, io_tracer_,
1589
- db_session_id_);
1594
+ db_id_, db_session_id_);
1590
1595
  column_families_.insert({name, id});
1591
1596
  column_family_data_.insert({id, new_cfd});
1592
1597
  max_column_family_ = std::max(max_column_family_, id);
@@ -47,6 +47,7 @@ class InstrumentedMutex;
47
47
  class InstrumentedMutexLock;
48
48
  struct SuperVersionContext;
49
49
  class BlobFileCache;
50
+ class BlobSource;
50
51
 
51
52
  extern const double kIncSlowdownRatio;
52
53
  // This file contains a list of data structures for managing column family
@@ -376,7 +377,7 @@ class ColumnFamilyData {
376
377
  SequenceNumber earliest_seq);
377
378
 
378
379
  TableCache* table_cache() const { return table_cache_.get(); }
379
- BlobFileCache* blob_file_cache() const { return blob_file_cache_.get(); }
380
+ BlobSource* blob_source() const { return blob_source_.get(); }
380
381
 
381
382
  // See documentation in compaction_picker.h
382
383
  // REQUIRES: DB mutex held
@@ -539,7 +540,7 @@ class ColumnFamilyData {
539
540
  ColumnFamilySet* column_family_set,
540
541
  BlockCacheTracer* const block_cache_tracer,
541
542
  const std::shared_ptr<IOTracer>& io_tracer,
542
- const std::string& db_session_id);
543
+ const std::string& db_id, const std::string& db_session_id);
543
544
 
544
545
  std::vector<std::string> GetDbPaths() const;
545
546
 
@@ -563,6 +564,7 @@ class ColumnFamilyData {
563
564
 
564
565
  std::unique_ptr<TableCache> table_cache_;
565
566
  std::unique_ptr<BlobFileCache> blob_file_cache_;
567
+ std::unique_ptr<BlobSource> blob_source_;
566
568
 
567
569
  std::unique_ptr<InternalStats> internal_stats_;
568
570
 
@@ -673,7 +675,7 @@ class ColumnFamilySet {
673
675
  WriteController* _write_controller,
674
676
  BlockCacheTracer* const block_cache_tracer,
675
677
  const std::shared_ptr<IOTracer>& io_tracer,
676
- const std::string& db_session_id);
678
+ const std::string& db_id, const std::string& db_session_id);
677
679
  ~ColumnFamilySet();
678
680
 
679
681
  ColumnFamilyData* GetDefault() const;
@@ -735,6 +737,7 @@ class ColumnFamilySet {
735
737
  WriteController* write_controller_;
736
738
  BlockCacheTracer* const block_cache_tracer_;
737
739
  std::shared_ptr<IOTracer> io_tracer_;
740
+ const std::string& db_id_;
738
741
  std::string db_session_id_;
739
742
  };
740
743
 
@@ -2160,6 +2160,16 @@ Status CompactionJob::InstallCompactionResults(
2160
2160
  stats.GetBytes());
2161
2161
  }
2162
2162
 
2163
+ if (compaction->compaction_reason() == CompactionReason::kLevelMaxLevelSize &&
2164
+ compaction->immutable_options()->compaction_pri == kRoundRobin) {
2165
+ int start_level = compaction->start_level();
2166
+ if (start_level > 0) {
2167
+ auto vstorage = compaction->input_version()->storage_info();
2168
+ edit->AddCompactCursor(start_level,
2169
+ vstorage->GetNextCompactCursor(start_level));
2170
+ }
2171
+ }
2172
+
2163
2173
  return versions_->LogAndApply(compaction->column_family_data(),
2164
2174
  mutable_cf_options, edit, db_mutex_,
2165
2175
  db_directory_);
@@ -208,11 +208,11 @@ class CompactionJobTestBase : public testing::Test {
208
208
  mutable_db_options_(),
209
209
  table_cache_(NewLRUCache(50000, 16)),
210
210
  write_buffer_manager_(db_options_.db_write_buffer_size),
211
- versions_(new VersionSet(dbname_, &db_options_, env_options_,
212
- table_cache_.get(), &write_buffer_manager_,
213
- &write_controller_,
214
- /*block_cache_tracer=*/nullptr,
215
- /*io_tracer=*/nullptr, /*db_session_id*/ "")),
211
+ versions_(new VersionSet(
212
+ dbname_, &db_options_, env_options_, table_cache_.get(),
213
+ &write_buffer_manager_, &write_controller_,
214
+ /*block_cache_tracer=*/nullptr,
215
+ /*io_tracer=*/nullptr, /*db_id*/ "", /*db_session_id*/ "")),
216
216
  shutting_down_(false),
217
217
  mock_table_factory_(new mock::MockTableFactory()),
218
218
  error_handler_(nullptr, db_options_, &mutex_),
@@ -444,7 +444,7 @@ class CompactionJobTestBase : public testing::Test {
444
444
  new VersionSet(dbname_, &db_options_, env_options_, table_cache_.get(),
445
445
  &write_buffer_manager_, &write_controller_,
446
446
  /*block_cache_tracer=*/nullptr, /*io_tracer=*/nullptr,
447
- /*db_session_id*/ ""));
447
+ /*db_id*/ "", /*db_session_id*/ ""));
448
448
  compaction_job_stats_.Reset();
449
449
  ASSERT_OK(SetIdentityFile(env_, dbname_));
450
450
 
@@ -448,6 +448,14 @@ bool LevelCompactionBuilder::PickFileToCompact() {
448
448
  // do not pick a file to compact if it is being compacted
449
449
  // from n-1 level.
450
450
  if (f->being_compacted) {
451
+ if (ioptions_.compaction_pri == kRoundRobin) {
452
+ // TODO(zichen): this file may be involved in one compaction from
453
+ // an upper level, cannot advance the cursor for round-robin policy.
454
+ // Currently, we do not pick any file to compact in this case. We
455
+ // should fix this later to ensure a compaction is picked but the
456
+ // cursor shall not be advanced.
457
+ return false;
458
+ }
451
459
  continue;
452
460
  }
453
461
 
@@ -460,6 +468,13 @@ bool LevelCompactionBuilder::PickFileToCompact() {
460
468
  // A locked (pending compaction) input-level file was pulled in due to
461
469
  // user-key overlap.
462
470
  start_level_inputs_.clear();
471
+
472
+ // To ensure every file is selcted in a round-robin manner, we cannot
473
+ // skip the current file. So we return false and wait for the next time
474
+ // we can pick this file to compact
475
+ if (ioptions_.compaction_pri == kRoundRobin) {
476
+ return false;
477
+ }
463
478
  continue;
464
479
  }
465
480
 
@@ -479,6 +494,10 @@ bool LevelCompactionBuilder::PickFileToCompact() {
479
494
  !compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
480
495
  &output_level_inputs)) {
481
496
  start_level_inputs_.clear();
497
+ // The same reason as above to ensure the round-robin compaction
498
+ if (ioptions_.compaction_pri == kRoundRobin) {
499
+ return false;
500
+ }
482
501
  continue;
483
502
  }
484
503
  base_index_ = index;
@@ -486,8 +505,9 @@ bool LevelCompactionBuilder::PickFileToCompact() {
486
505
  }
487
506
 
488
507
  // store where to start the iteration in the next call to PickCompaction
489
- vstorage_->SetNextCompactionIndex(start_level_, cmp_idx);
490
-
508
+ if (ioptions_.compaction_pri != kRoundRobin) {
509
+ vstorage_->SetNextCompactionIndex(start_level_, cmp_idx);
510
+ }
491
511
  return start_level_inputs_.size() > 0;
492
512
  }
493
513