@nxtedition/rocksdb 7.0.5 → 7.0.8

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 (262) hide show
  1. package/binding.cc +363 -329
  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/darwin-x64/node.napi.node +0 -0
  136. package/prebuilds/linux-x64/node.napi.node +0 -0
  137. package/deps/liburing/liburing/README +0 -46
  138. package/deps/liburing/liburing/test/232c93d07b74-test.c +0 -305
  139. package/deps/liburing/liburing/test/35fa71a030ca-test.c +0 -329
  140. package/deps/liburing/liburing/test/500f9fbadef8-test.c +0 -89
  141. package/deps/liburing/liburing/test/7ad0e4b2f83c-test.c +0 -93
  142. package/deps/liburing/liburing/test/8a9973408177-test.c +0 -106
  143. package/deps/liburing/liburing/test/917257daa0fe-test.c +0 -53
  144. package/deps/liburing/liburing/test/Makefile +0 -312
  145. package/deps/liburing/liburing/test/a0908ae19763-test.c +0 -58
  146. package/deps/liburing/liburing/test/a4c0b3decb33-test.c +0 -180
  147. package/deps/liburing/liburing/test/accept-link.c +0 -251
  148. package/deps/liburing/liburing/test/accept-reuse.c +0 -164
  149. package/deps/liburing/liburing/test/accept-test.c +0 -79
  150. package/deps/liburing/liburing/test/accept.c +0 -476
  151. package/deps/liburing/liburing/test/across-fork.c +0 -283
  152. package/deps/liburing/liburing/test/b19062a56726-test.c +0 -53
  153. package/deps/liburing/liburing/test/b5837bd5311d-test.c +0 -77
  154. package/deps/liburing/liburing/test/ce593a6c480a-test.c +0 -135
  155. package/deps/liburing/liburing/test/close-opath.c +0 -122
  156. package/deps/liburing/liburing/test/config +0 -10
  157. package/deps/liburing/liburing/test/connect.c +0 -398
  158. package/deps/liburing/liburing/test/cq-full.c +0 -96
  159. package/deps/liburing/liburing/test/cq-overflow.c +0 -294
  160. package/deps/liburing/liburing/test/cq-peek-batch.c +0 -102
  161. package/deps/liburing/liburing/test/cq-ready.c +0 -94
  162. package/deps/liburing/liburing/test/cq-size.c +0 -58
  163. package/deps/liburing/liburing/test/d4ae271dfaae-test.c +0 -96
  164. package/deps/liburing/liburing/test/d77a67ed5f27-test.c +0 -65
  165. package/deps/liburing/liburing/test/defer.c +0 -307
  166. package/deps/liburing/liburing/test/double-poll-crash.c +0 -186
  167. package/deps/liburing/liburing/test/eeed8b54e0df-test.c +0 -114
  168. package/deps/liburing/liburing/test/empty-eownerdead.c +0 -42
  169. package/deps/liburing/liburing/test/eventfd-disable.c +0 -151
  170. package/deps/liburing/liburing/test/eventfd-ring.c +0 -97
  171. package/deps/liburing/liburing/test/eventfd.c +0 -112
  172. package/deps/liburing/liburing/test/fadvise.c +0 -202
  173. package/deps/liburing/liburing/test/fallocate.c +0 -249
  174. package/deps/liburing/liburing/test/fc2a85cb02ef-test.c +0 -138
  175. package/deps/liburing/liburing/test/file-register.c +0 -843
  176. package/deps/liburing/liburing/test/file-update.c +0 -173
  177. package/deps/liburing/liburing/test/files-exit-hang-poll.c +0 -128
  178. package/deps/liburing/liburing/test/files-exit-hang-timeout.c +0 -134
  179. package/deps/liburing/liburing/test/fixed-link.c +0 -90
  180. package/deps/liburing/liburing/test/fsync.c +0 -224
  181. package/deps/liburing/liburing/test/hardlink.c +0 -136
  182. package/deps/liburing/liburing/test/helpers.c +0 -135
  183. package/deps/liburing/liburing/test/helpers.h +0 -67
  184. package/deps/liburing/liburing/test/io-cancel.c +0 -537
  185. package/deps/liburing/liburing/test/io_uring_enter.c +0 -296
  186. package/deps/liburing/liburing/test/io_uring_register.c +0 -664
  187. package/deps/liburing/liburing/test/io_uring_setup.c +0 -192
  188. package/deps/liburing/liburing/test/iopoll.c +0 -366
  189. package/deps/liburing/liburing/test/lfs-openat-write.c +0 -117
  190. package/deps/liburing/liburing/test/lfs-openat.c +0 -273
  191. package/deps/liburing/liburing/test/link-timeout.c +0 -1107
  192. package/deps/liburing/liburing/test/link.c +0 -496
  193. package/deps/liburing/liburing/test/link_drain.c +0 -229
  194. package/deps/liburing/liburing/test/madvise.c +0 -195
  195. package/deps/liburing/liburing/test/mkdir.c +0 -108
  196. package/deps/liburing/liburing/test/multicqes_drain.c +0 -383
  197. package/deps/liburing/liburing/test/nop-all-sizes.c +0 -107
  198. package/deps/liburing/liburing/test/nop.c +0 -115
  199. package/deps/liburing/liburing/test/open-close.c +0 -146
  200. package/deps/liburing/liburing/test/openat2.c +0 -240
  201. package/deps/liburing/liburing/test/personality.c +0 -204
  202. package/deps/liburing/liburing/test/pipe-eof.c +0 -81
  203. package/deps/liburing/liburing/test/pipe-reuse.c +0 -105
  204. package/deps/liburing/liburing/test/poll-cancel-ton.c +0 -139
  205. package/deps/liburing/liburing/test/poll-cancel.c +0 -135
  206. package/deps/liburing/liburing/test/poll-link.c +0 -227
  207. package/deps/liburing/liburing/test/poll-many.c +0 -208
  208. package/deps/liburing/liburing/test/poll-mshot-update.c +0 -273
  209. package/deps/liburing/liburing/test/poll-ring.c +0 -48
  210. package/deps/liburing/liburing/test/poll-v-poll.c +0 -353
  211. package/deps/liburing/liburing/test/poll.c +0 -109
  212. package/deps/liburing/liburing/test/probe.c +0 -137
  213. package/deps/liburing/liburing/test/read-write.c +0 -876
  214. package/deps/liburing/liburing/test/register-restrictions.c +0 -633
  215. package/deps/liburing/liburing/test/rename.c +0 -134
  216. package/deps/liburing/liburing/test/ring-leak.c +0 -173
  217. package/deps/liburing/liburing/test/ring-leak2.c +0 -249
  218. package/deps/liburing/liburing/test/rsrc_tags.c +0 -449
  219. package/deps/liburing/liburing/test/runtests-loop.sh +0 -16
  220. package/deps/liburing/liburing/test/runtests.sh +0 -170
  221. package/deps/liburing/liburing/test/rw_merge_test.c +0 -97
  222. package/deps/liburing/liburing/test/self.c +0 -91
  223. package/deps/liburing/liburing/test/send_recv.c +0 -291
  224. package/deps/liburing/liburing/test/send_recvmsg.c +0 -345
  225. package/deps/liburing/liburing/test/sendmsg_fs_cve.c +0 -198
  226. package/deps/liburing/liburing/test/shared-wq.c +0 -84
  227. package/deps/liburing/liburing/test/short-read.c +0 -75
  228. package/deps/liburing/liburing/test/shutdown.c +0 -163
  229. package/deps/liburing/liburing/test/sigfd-deadlock.c +0 -74
  230. package/deps/liburing/liburing/test/socket-rw-eagain.c +0 -156
  231. package/deps/liburing/liburing/test/socket-rw.c +0 -147
  232. package/deps/liburing/liburing/test/splice.c +0 -511
  233. package/deps/liburing/liburing/test/sq-full-cpp.cc +0 -45
  234. package/deps/liburing/liburing/test/sq-full.c +0 -45
  235. package/deps/liburing/liburing/test/sq-poll-dup.c +0 -200
  236. package/deps/liburing/liburing/test/sq-poll-kthread.c +0 -168
  237. package/deps/liburing/liburing/test/sq-poll-share.c +0 -137
  238. package/deps/liburing/liburing/test/sq-space_left.c +0 -159
  239. package/deps/liburing/liburing/test/sqpoll-cancel-hang.c +0 -159
  240. package/deps/liburing/liburing/test/sqpoll-disable-exit.c +0 -195
  241. package/deps/liburing/liburing/test/sqpoll-exit-hang.c +0 -77
  242. package/deps/liburing/liburing/test/sqpoll-sleep.c +0 -68
  243. package/deps/liburing/liburing/test/statx.c +0 -172
  244. package/deps/liburing/liburing/test/stdout.c +0 -232
  245. package/deps/liburing/liburing/test/submit-link-fail.c +0 -154
  246. package/deps/liburing/liburing/test/submit-reuse.c +0 -239
  247. package/deps/liburing/liburing/test/symlink.c +0 -116
  248. package/deps/liburing/liburing/test/teardowns.c +0 -58
  249. package/deps/liburing/liburing/test/thread-exit.c +0 -131
  250. package/deps/liburing/liburing/test/timeout-new.c +0 -246
  251. package/deps/liburing/liburing/test/timeout-overflow.c +0 -204
  252. package/deps/liburing/liburing/test/timeout.c +0 -1354
  253. package/deps/liburing/liburing/test/unlink.c +0 -111
  254. package/deps/liburing/liburing/test/wakeup-hang.c +0 -162
  255. package/deps/rocksdb/rocksdb/README.md +0 -32
  256. package/deps/rocksdb/rocksdb/microbench/README.md +0 -60
  257. package/deps/rocksdb/rocksdb/plugin/README.md +0 -43
  258. package/deps/rocksdb/rocksdb/port/README +0 -10
  259. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.cc +0 -358
  260. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.h +0 -127
  261. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block_test.cc +0 -219
  262. 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