@nxtedition/rocksdb 6.0.1 → 7.0.0-alpha.1

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 (490) hide show
  1. package/BUILDING.md +12 -4
  2. package/binding.cc +421 -40
  3. package/deps/rocksdb/build_version.cc +4 -10
  4. package/deps/rocksdb/rocksdb/CMakeLists.txt +26 -3
  5. package/deps/rocksdb/rocksdb/Makefile +73 -91
  6. package/deps/rocksdb/rocksdb/TARGETS +27 -2
  7. package/deps/rocksdb/rocksdb/cache/cache_test.cc +29 -17
  8. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.cc +511 -0
  9. package/deps/rocksdb/rocksdb/cache/fast_lru_cache.h +299 -0
  10. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +3 -0
  11. package/deps/rocksdb/rocksdb/cache/lru_cache.h +7 -0
  12. package/deps/rocksdb/rocksdb/cmake/modules/CxxFlags.cmake +7 -0
  13. package/deps/rocksdb/rocksdb/cmake/modules/FindJeMalloc.cmake +29 -0
  14. package/deps/rocksdb/rocksdb/cmake/modules/FindNUMA.cmake +29 -0
  15. package/deps/rocksdb/rocksdb/cmake/modules/FindSnappy.cmake +29 -0
  16. package/deps/rocksdb/rocksdb/cmake/modules/FindTBB.cmake +33 -0
  17. package/deps/rocksdb/rocksdb/cmake/modules/Findgflags.cmake +29 -0
  18. package/deps/rocksdb/rocksdb/cmake/modules/Findlz4.cmake +29 -0
  19. package/deps/rocksdb/rocksdb/cmake/modules/Finduring.cmake +26 -0
  20. package/deps/rocksdb/rocksdb/cmake/modules/Findzstd.cmake +29 -0
  21. package/deps/rocksdb/rocksdb/cmake/modules/ReadVersion.cmake +10 -0
  22. package/deps/rocksdb/rocksdb/common.mk +30 -0
  23. package/deps/rocksdb/rocksdb/crash_test.mk +3 -3
  24. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.cc +1 -1
  25. package/deps/rocksdb/rocksdb/db/blob/blob_index.h +3 -3
  26. package/deps/rocksdb/rocksdb/db/blob/db_blob_index_test.cc +7 -7
  27. package/deps/rocksdb/rocksdb/db/builder.cc +22 -7
  28. package/deps/rocksdb/rocksdb/db/c.cc +71 -0
  29. package/deps/rocksdb/rocksdb/db/c_test.c +28 -2
  30. package/deps/rocksdb/rocksdb/db/column_family.cc +12 -5
  31. package/deps/rocksdb/rocksdb/db/column_family_test.cc +23 -22
  32. package/deps/rocksdb/rocksdb/db/compact_files_test.cc +11 -11
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +2 -2
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +36 -10
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +4 -1
  36. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +3 -2
  37. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +54 -16
  38. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +14 -2
  39. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_stats_test.cc +3 -3
  40. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +85 -18
  41. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +7 -7
  42. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +1 -1
  43. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +23 -22
  44. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +1 -1
  45. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +151 -32
  46. package/deps/rocksdb/rocksdb/db/comparator_db_test.cc +1 -1
  47. package/deps/rocksdb/rocksdb/db/convenience.cc +8 -6
  48. package/deps/rocksdb/rocksdb/db/corruption_test.cc +209 -38
  49. package/deps/rocksdb/rocksdb/db/cuckoo_table_db_test.cc +2 -2
  50. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +404 -32
  51. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +28 -25
  52. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +85 -138
  53. package/deps/rocksdb/rocksdb/db/db_compaction_filter_test.cc +68 -3
  54. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +38 -13
  55. package/deps/rocksdb/rocksdb/db/db_filesnapshot.cc +1 -1
  56. package/deps/rocksdb/rocksdb/db/db_flush_test.cc +1 -1
  57. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +11 -20
  58. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +15 -1
  59. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +12 -9
  60. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +5 -4
  61. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +1 -1
  62. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +2 -2
  63. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +42 -10
  64. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +54 -23
  65. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.h +3 -0
  66. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +14 -4
  67. package/deps/rocksdb/rocksdb/db/db_info_dumper.cc +26 -18
  68. package/deps/rocksdb/rocksdb/db/db_iter_stress_test.cc +8 -7
  69. package/deps/rocksdb/rocksdb/db/db_iter_test.cc +8 -8
  70. package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +6 -3
  71. package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +2 -2
  72. package/deps/rocksdb/rocksdb/db/db_log_iter_test.cc +6 -6
  73. package/deps/rocksdb/rocksdb/db/db_memtable_test.cc +2 -2
  74. package/deps/rocksdb/rocksdb/db/db_options_test.cc +28 -12
  75. package/deps/rocksdb/rocksdb/db/db_properties_test.cc +16 -15
  76. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +6 -4
  77. package/deps/rocksdb/rocksdb/db/db_readonly_with_timestamp_test.cc +331 -0
  78. package/deps/rocksdb/rocksdb/db/db_secondary_test.cc +11 -6
  79. package/deps/rocksdb/rocksdb/db/db_sst_test.cc +68 -7
  80. package/deps/rocksdb/rocksdb/db/db_table_properties_test.cc +6 -5
  81. package/deps/rocksdb/rocksdb/db/db_test.cc +60 -42
  82. package/deps/rocksdb/rocksdb/db/db_test2.cc +244 -111
  83. package/deps/rocksdb/rocksdb/db/db_test_util.cc +101 -19
  84. package/deps/rocksdb/rocksdb/db/db_test_util.h +52 -2
  85. package/deps/rocksdb/rocksdb/db/db_universal_compaction_test.cc +1 -1
  86. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +7 -7
  87. package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +5 -175
  88. package/deps/rocksdb/rocksdb/db/db_with_timestamp_test_util.cc +96 -0
  89. package/deps/rocksdb/rocksdb/db/db_with_timestamp_test_util.h +126 -0
  90. package/deps/rocksdb/rocksdb/db/db_write_test.cc +6 -6
  91. package/deps/rocksdb/rocksdb/db/dbformat.h +2 -1
  92. package/deps/rocksdb/rocksdb/db/deletefile_test.cc +1 -1
  93. package/deps/rocksdb/rocksdb/db/error_handler_fs_test.cc +8 -8
  94. package/deps/rocksdb/rocksdb/db/experimental.cc +1 -1
  95. package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +91 -12
  96. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +16 -2
  97. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +2 -0
  98. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +7 -7
  99. package/deps/rocksdb/rocksdb/db/file_indexer.h +1 -4
  100. package/deps/rocksdb/rocksdb/db/flush_job.cc +28 -15
  101. package/deps/rocksdb/rocksdb/db/flush_job.h +4 -0
  102. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +98 -30
  103. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +1 -1
  104. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +14 -1
  105. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +6 -0
  106. package/deps/rocksdb/rocksdb/db/internal_stats.cc +12 -12
  107. package/deps/rocksdb/rocksdb/db/listener_test.cc +4 -3
  108. package/deps/rocksdb/rocksdb/db/memtable.cc +2 -2
  109. package/deps/rocksdb/rocksdb/db/memtable_list.h +1 -1
  110. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +37 -25
  111. package/deps/rocksdb/rocksdb/db/obsolete_files_test.cc +1 -1
  112. package/deps/rocksdb/rocksdb/db/perf_context_test.cc +18 -18
  113. package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +6 -6
  114. package/deps/rocksdb/rocksdb/db/prefix_test.cc +1 -1
  115. package/deps/rocksdb/rocksdb/db/repair.cc +13 -2
  116. package/deps/rocksdb/rocksdb/db/repair_test.cc +37 -15
  117. package/deps/rocksdb/rocksdb/db/snapshot_checker.h +1 -2
  118. package/deps/rocksdb/rocksdb/db/snapshot_impl.h +3 -1
  119. package/deps/rocksdb/rocksdb/db/table_cache.cc +20 -130
  120. package/deps/rocksdb/rocksdb/db/table_cache.h +3 -2
  121. package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +140 -0
  122. package/deps/rocksdb/rocksdb/db/version_builder.cc +1 -1
  123. package/deps/rocksdb/rocksdb/db/version_builder_test.cc +133 -133
  124. package/deps/rocksdb/rocksdb/db/version_edit.cc +22 -2
  125. package/deps/rocksdb/rocksdb/db/version_edit.h +13 -4
  126. package/deps/rocksdb/rocksdb/db/version_edit_test.cc +14 -14
  127. package/deps/rocksdb/rocksdb/db/version_set.cc +207 -214
  128. package/deps/rocksdb/rocksdb/db/version_set.h +14 -3
  129. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +154 -0
  130. package/deps/rocksdb/rocksdb/db/version_set_test.cc +10 -9
  131. package/deps/rocksdb/rocksdb/db/wal_edit.h +2 -1
  132. package/deps/rocksdb/rocksdb/db/wal_manager.cc +2 -3
  133. package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +1 -1
  134. package/deps/rocksdb/rocksdb/db/write_batch.cc +178 -30
  135. package/deps/rocksdb/rocksdb/db/write_batch_test.cc +6 -6
  136. package/deps/rocksdb/rocksdb/db/write_controller.h +1 -1
  137. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +0 -2
  138. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +9 -6
  139. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_compaction_filter.h +2 -1
  140. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +4 -3
  141. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +44 -6
  142. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_listener.cc +4 -1
  143. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.cc +0 -10
  144. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.h +45 -42
  145. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +374 -275
  146. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +53 -3
  147. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +0 -12
  148. package/deps/rocksdb/rocksdb/db_stress_tool/expected_state.cc +13 -11
  149. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +276 -109
  150. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.h +63 -0
  151. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +45 -54
  152. package/deps/rocksdb/rocksdb/env/composite_env.cc +87 -14
  153. package/deps/rocksdb/rocksdb/env/env.cc +0 -60
  154. package/deps/rocksdb/rocksdb/env/env_encryption.cc +9 -0
  155. package/deps/rocksdb/rocksdb/env/env_encryption_ctr.h +1 -1
  156. package/deps/rocksdb/rocksdb/env/env_posix.cc +6 -5
  157. package/deps/rocksdb/rocksdb/env/env_test.cc +18 -5
  158. package/deps/rocksdb/rocksdb/env/fs_posix.cc +17 -12
  159. package/deps/rocksdb/rocksdb/env/io_posix.cc +39 -37
  160. package/deps/rocksdb/rocksdb/file/delete_scheduler_test.cc +9 -9
  161. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +159 -65
  162. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +44 -22
  163. package/deps/rocksdb/rocksdb/file/file_util.h +2 -0
  164. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +142 -17
  165. package/deps/rocksdb/rocksdb/file/random_access_file_reader.h +5 -2
  166. package/deps/rocksdb/rocksdb/file/sequence_file_reader.cc +7 -0
  167. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +60 -40
  168. package/deps/rocksdb/rocksdb/file/writable_file_writer.h +1 -0
  169. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +23 -5
  170. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +49 -1
  171. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +5 -5
  172. package/deps/rocksdb/rocksdb/include/rocksdb/cleanable.h +59 -2
  173. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_filter.h +1 -0
  174. package/deps/rocksdb/rocksdb/include/rocksdb/convenience.h +2 -1
  175. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +46 -44
  176. package/deps/rocksdb/rocksdb/include/rocksdb/env.h +1 -1
  177. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +2 -0
  178. package/deps/rocksdb/rocksdb/include/rocksdb/iostats_context.h +2 -4
  179. package/deps/rocksdb/rocksdb/include/rocksdb/memtablerep.h +3 -0
  180. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +45 -3
  181. package/deps/rocksdb/rocksdb/include/rocksdb/perf_context.h +2 -0
  182. package/deps/rocksdb/rocksdb/include/rocksdb/snapshot.h +4 -1
  183. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +3 -0
  184. package/deps/rocksdb/rocksdb/include/rocksdb/table.h +91 -40
  185. package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +1 -2
  186. package/deps/rocksdb/rocksdb/include/rocksdb/unique_id.h +22 -13
  187. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/customizable_util.h +9 -0
  188. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd.h +4 -0
  189. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/object_registry.h +25 -0
  190. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_type.h +378 -103
  191. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db.h +14 -0
  192. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
  193. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +18 -4
  194. package/deps/rocksdb/rocksdb/memory/arena.h +1 -1
  195. package/deps/rocksdb/rocksdb/memory/concurrent_arena.cc +1 -5
  196. package/deps/rocksdb/rocksdb/memory/concurrent_arena.h +1 -5
  197. package/deps/rocksdb/rocksdb/memory/jemalloc_nodump_allocator.cc +6 -8
  198. package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +1 -1
  199. package/deps/rocksdb/rocksdb/memtable/write_buffer_manager.cc +1 -1
  200. package/deps/rocksdb/rocksdb/memtable/write_buffer_manager_test.cc +5 -3
  201. package/deps/rocksdb/rocksdb/microbench/db_basic_bench.cc +266 -45
  202. package/deps/rocksdb/rocksdb/monitoring/histogram.cc +2 -1
  203. package/deps/rocksdb/rocksdb/monitoring/iostats_context.cc +1 -4
  204. package/deps/rocksdb/rocksdb/monitoring/iostats_context_imp.h +4 -4
  205. package/deps/rocksdb/rocksdb/monitoring/perf_context.cc +7 -8
  206. package/deps/rocksdb/rocksdb/monitoring/perf_context_imp.h +2 -2
  207. package/deps/rocksdb/rocksdb/monitoring/perf_level.cc +1 -5
  208. package/deps/rocksdb/rocksdb/monitoring/perf_level_imp.h +1 -5
  209. package/deps/rocksdb/rocksdb/monitoring/persistent_stats_history.cc +2 -2
  210. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +1 -1
  211. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.cc +2 -1
  212. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.h +1 -1
  213. package/deps/rocksdb/rocksdb/monitoring/thread_status_util.cc +3 -3
  214. package/deps/rocksdb/rocksdb/monitoring/thread_status_util.h +2 -2
  215. package/deps/rocksdb/rocksdb/options/cf_options.cc +47 -38
  216. package/deps/rocksdb/rocksdb/options/configurable.cc +9 -27
  217. package/deps/rocksdb/rocksdb/options/configurable_test.cc +1 -1
  218. package/deps/rocksdb/rocksdb/options/customizable.cc +3 -1
  219. package/deps/rocksdb/rocksdb/options/customizable_test.cc +379 -318
  220. package/deps/rocksdb/rocksdb/options/db_options.cc +46 -17
  221. package/deps/rocksdb/rocksdb/options/db_options.h +2 -0
  222. package/deps/rocksdb/rocksdb/options/options.cc +7 -0
  223. package/deps/rocksdb/rocksdb/options/options_helper.cc +86 -39
  224. package/deps/rocksdb/rocksdb/options/options_parser.cc +10 -10
  225. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +12 -7
  226. package/deps/rocksdb/rocksdb/options/options_test.cc +222 -68
  227. package/deps/rocksdb/rocksdb/port/port_posix.h +0 -15
  228. package/deps/rocksdb/rocksdb/port/win/env_win.cc +5 -4
  229. package/deps/rocksdb/rocksdb/port/win/env_win.h +2 -2
  230. package/deps/rocksdb/rocksdb/port/win/port_win.h +0 -31
  231. package/deps/rocksdb/rocksdb/rocksdb.pc.in +11 -0
  232. package/deps/rocksdb/rocksdb/src.mk +6 -1
  233. package/deps/rocksdb/rocksdb/table/block_based/binary_search_index_reader.cc +2 -1
  234. package/deps/rocksdb/rocksdb/table/block_based/block.cc +4 -2
  235. package/deps/rocksdb/rocksdb/table/block_based/block.h +21 -25
  236. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.cc +3 -4
  237. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +23 -8
  238. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +52 -15
  239. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +81 -7
  240. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +8 -2
  241. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +94 -726
  242. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +21 -15
  243. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +9 -3
  244. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +754 -0
  245. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +44 -73
  246. package/deps/rocksdb/rocksdb/table/block_based/block_prefetcher.cc +15 -5
  247. package/deps/rocksdb/rocksdb/table/block_based/block_prefetcher.h +2 -1
  248. package/deps/rocksdb/rocksdb/table/block_based/filter_block.h +2 -11
  249. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +59 -1
  250. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.h +18 -0
  251. package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +33 -17
  252. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +0 -61
  253. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.h +0 -13
  254. package/deps/rocksdb/rocksdb/table/block_based/hash_index_reader.cc +2 -1
  255. package/deps/rocksdb/rocksdb/table/block_based/index_builder.h +2 -2
  256. package/deps/rocksdb/rocksdb/table/block_based/index_reader_common.cc +3 -2
  257. package/deps/rocksdb/rocksdb/table/block_based/index_reader_common.h +2 -1
  258. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +3 -2
  259. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_iterator.cc +4 -3
  260. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_reader.cc +8 -4
  261. package/deps/rocksdb/rocksdb/table/block_based/reader_common.cc +4 -4
  262. package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.cc +2 -1
  263. package/deps/rocksdb/rocksdb/table/block_fetcher.cc +65 -7
  264. package/deps/rocksdb/rocksdb/table/block_fetcher.h +2 -0
  265. package/deps/rocksdb/rocksdb/table/cleanable_test.cc +113 -0
  266. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder.cc +1 -1
  267. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder.h +1 -1
  268. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader_test.cc +1 -1
  269. package/deps/rocksdb/rocksdb/table/format.cc +22 -20
  270. package/deps/rocksdb/rocksdb/table/iterator.cc +1 -81
  271. package/deps/rocksdb/rocksdb/table/merging_iterator.cc +39 -0
  272. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +2 -2
  273. package/deps/rocksdb/rocksdb/table/multiget_context.h +60 -13
  274. package/deps/rocksdb/rocksdb/table/persistent_cache_options.h +0 -3
  275. package/deps/rocksdb/rocksdb/table/plain/plain_table_factory.cc +12 -1
  276. package/deps/rocksdb/rocksdb/table/plain/plain_table_reader.cc +4 -4
  277. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +2 -1
  278. package/deps/rocksdb/rocksdb/table/sst_file_dumper.h +1 -1
  279. package/deps/rocksdb/rocksdb/table/sst_file_writer_collectors.h +1 -1
  280. package/deps/rocksdb/rocksdb/table/table_properties.cc +3 -5
  281. package/deps/rocksdb/rocksdb/table/table_reader.h +13 -0
  282. package/deps/rocksdb/rocksdb/table/table_test.cc +202 -78
  283. package/deps/rocksdb/rocksdb/table/unique_id.cc +84 -25
  284. package/deps/rocksdb/rocksdb/table/unique_id_impl.h +37 -4
  285. package/deps/rocksdb/rocksdb/test_util/testutil.cc +3 -1
  286. package/deps/rocksdb/rocksdb/test_util/testutil.h +11 -8
  287. package/deps/rocksdb/rocksdb/test_util/transaction_test_util.cc +8 -4
  288. package/deps/rocksdb/rocksdb/test_util/transaction_test_util.h +17 -0
  289. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer.cc +11 -9
  290. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc +3 -3
  291. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +277 -105
  292. package/deps/rocksdb/rocksdb/tools/db_sanity_test.cc +4 -4
  293. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +186 -42
  294. package/deps/rocksdb/rocksdb/tools/ldb_cmd_impl.h +75 -49
  295. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +9 -8
  296. package/deps/rocksdb/rocksdb/tools/ldb_tool.cc +4 -1
  297. package/deps/rocksdb/rocksdb/tools/reduce_levels_test.cc +2 -2
  298. package/deps/rocksdb/rocksdb/tools/sst_dump_tool.cc +26 -4
  299. package/deps/rocksdb/rocksdb/tools/trace_analyzer_tool.cc +1 -1
  300. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer.h +1 -1
  301. package/deps/rocksdb/rocksdb/util/async_file_reader.cc +72 -0
  302. package/deps/rocksdb/rocksdb/util/async_file_reader.h +144 -0
  303. package/deps/rocksdb/rocksdb/util/autovector_test.cc +4 -4
  304. package/deps/rocksdb/rocksdb/util/bloom_test.cc +14 -8
  305. package/deps/rocksdb/rocksdb/util/build_version.cc.in +5 -6
  306. package/deps/rocksdb/rocksdb/util/cleanable.cc +180 -0
  307. package/deps/rocksdb/rocksdb/util/comparator.cc +5 -3
  308. package/deps/rocksdb/rocksdb/util/compression.h +56 -7
  309. package/deps/rocksdb/rocksdb/util/coro_utils.h +111 -0
  310. package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +148 -0
  311. package/deps/rocksdb/rocksdb/util/filelock_test.cc +2 -2
  312. package/deps/rocksdb/rocksdb/util/filter_bench.cc +12 -4
  313. package/deps/rocksdb/rocksdb/util/heap.h +5 -3
  314. package/deps/rocksdb/rocksdb/util/random.cc +1 -5
  315. package/deps/rocksdb/rocksdb/util/rate_limiter.cc +12 -9
  316. package/deps/rocksdb/rocksdb/util/rate_limiter_test.cc +1 -1
  317. package/deps/rocksdb/rocksdb/util/ribbon_alg.h +1 -1
  318. package/deps/rocksdb/rocksdb/util/ribbon_test.cc +2 -4
  319. package/deps/rocksdb/rocksdb/util/single_thread_executor.h +55 -0
  320. package/deps/rocksdb/rocksdb/util/slice.cc +8 -9
  321. package/deps/rocksdb/rocksdb/util/string_util.cc +3 -2
  322. package/deps/rocksdb/rocksdb/util/string_util.h +0 -13
  323. package/deps/rocksdb/rocksdb/util/thread_local.cc +4 -23
  324. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +99 -22
  325. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_impl.h +7 -0
  326. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +102 -59
  327. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_test.cc +38 -36
  328. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_dump_tool.cc +2 -2
  329. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.cc +28 -0
  330. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.h +3 -0
  331. package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +1 -1
  332. package/deps/rocksdb/rocksdb/utilities/object_registry.cc +71 -0
  333. package/deps/rocksdb/rocksdb/utilities/object_registry_test.cc +71 -0
  334. package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +1 -1
  335. package/deps/rocksdb/rocksdb/utilities/simulator_cache/sim_cache_test.cc +5 -5
  336. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_on_deletion_collector.cc +3 -3
  337. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_tracker.cc +0 -13
  338. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_locking_test.cc +40 -0
  339. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/lock_request.cc +10 -8
  340. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/lock_request.h +4 -2
  341. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_time.h +17 -0
  342. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/range_tree_lock_manager.cc +7 -7
  343. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.cc +8 -1
  344. package/deps/rocksdb/rocksdb/utilities/transactions/snapshot_checker.cc +5 -1
  345. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +21 -15
  346. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_util.cc +2 -2
  347. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +69 -11
  348. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +22 -9
  349. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.cc +26 -5
  350. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.h +17 -4
  351. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_transaction_test.cc +19 -16
  352. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn.cc +7 -3
  353. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +3 -2
  354. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.cc +2 -2
  355. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +2 -2
  356. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +6 -6
  357. package/deps/rocksdb/rocksdb.gyp +20 -13
  358. package/index.js +187 -3
  359. package/iterator.js +1 -0
  360. package/package-lock.json +23687 -0
  361. package/package.json +2 -30
  362. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  363. package/snapshot.js +23 -0
  364. package/deps/liburing/liburing/README +0 -46
  365. package/deps/liburing/liburing/test/232c93d07b74-test.c +0 -305
  366. package/deps/liburing/liburing/test/35fa71a030ca-test.c +0 -329
  367. package/deps/liburing/liburing/test/500f9fbadef8-test.c +0 -89
  368. package/deps/liburing/liburing/test/7ad0e4b2f83c-test.c +0 -93
  369. package/deps/liburing/liburing/test/8a9973408177-test.c +0 -106
  370. package/deps/liburing/liburing/test/917257daa0fe-test.c +0 -53
  371. package/deps/liburing/liburing/test/Makefile +0 -312
  372. package/deps/liburing/liburing/test/a0908ae19763-test.c +0 -58
  373. package/deps/liburing/liburing/test/a4c0b3decb33-test.c +0 -180
  374. package/deps/liburing/liburing/test/accept-link.c +0 -251
  375. package/deps/liburing/liburing/test/accept-reuse.c +0 -164
  376. package/deps/liburing/liburing/test/accept-test.c +0 -79
  377. package/deps/liburing/liburing/test/accept.c +0 -476
  378. package/deps/liburing/liburing/test/across-fork.c +0 -283
  379. package/deps/liburing/liburing/test/b19062a56726-test.c +0 -53
  380. package/deps/liburing/liburing/test/b5837bd5311d-test.c +0 -77
  381. package/deps/liburing/liburing/test/ce593a6c480a-test.c +0 -135
  382. package/deps/liburing/liburing/test/close-opath.c +0 -122
  383. package/deps/liburing/liburing/test/config +0 -10
  384. package/deps/liburing/liburing/test/connect.c +0 -398
  385. package/deps/liburing/liburing/test/cq-full.c +0 -96
  386. package/deps/liburing/liburing/test/cq-overflow.c +0 -294
  387. package/deps/liburing/liburing/test/cq-peek-batch.c +0 -102
  388. package/deps/liburing/liburing/test/cq-ready.c +0 -94
  389. package/deps/liburing/liburing/test/cq-size.c +0 -58
  390. package/deps/liburing/liburing/test/d4ae271dfaae-test.c +0 -96
  391. package/deps/liburing/liburing/test/d77a67ed5f27-test.c +0 -65
  392. package/deps/liburing/liburing/test/defer.c +0 -307
  393. package/deps/liburing/liburing/test/double-poll-crash.c +0 -186
  394. package/deps/liburing/liburing/test/eeed8b54e0df-test.c +0 -114
  395. package/deps/liburing/liburing/test/empty-eownerdead.c +0 -42
  396. package/deps/liburing/liburing/test/eventfd-disable.c +0 -151
  397. package/deps/liburing/liburing/test/eventfd-ring.c +0 -97
  398. package/deps/liburing/liburing/test/eventfd.c +0 -112
  399. package/deps/liburing/liburing/test/fadvise.c +0 -202
  400. package/deps/liburing/liburing/test/fallocate.c +0 -249
  401. package/deps/liburing/liburing/test/fc2a85cb02ef-test.c +0 -138
  402. package/deps/liburing/liburing/test/file-register.c +0 -843
  403. package/deps/liburing/liburing/test/file-update.c +0 -173
  404. package/deps/liburing/liburing/test/files-exit-hang-poll.c +0 -128
  405. package/deps/liburing/liburing/test/files-exit-hang-timeout.c +0 -134
  406. package/deps/liburing/liburing/test/fixed-link.c +0 -90
  407. package/deps/liburing/liburing/test/fsync.c +0 -224
  408. package/deps/liburing/liburing/test/hardlink.c +0 -136
  409. package/deps/liburing/liburing/test/helpers.c +0 -135
  410. package/deps/liburing/liburing/test/helpers.h +0 -67
  411. package/deps/liburing/liburing/test/io-cancel.c +0 -537
  412. package/deps/liburing/liburing/test/io_uring_enter.c +0 -296
  413. package/deps/liburing/liburing/test/io_uring_register.c +0 -664
  414. package/deps/liburing/liburing/test/io_uring_setup.c +0 -192
  415. package/deps/liburing/liburing/test/iopoll.c +0 -366
  416. package/deps/liburing/liburing/test/lfs-openat-write.c +0 -117
  417. package/deps/liburing/liburing/test/lfs-openat.c +0 -273
  418. package/deps/liburing/liburing/test/link-timeout.c +0 -1107
  419. package/deps/liburing/liburing/test/link.c +0 -496
  420. package/deps/liburing/liburing/test/link_drain.c +0 -229
  421. package/deps/liburing/liburing/test/madvise.c +0 -195
  422. package/deps/liburing/liburing/test/mkdir.c +0 -108
  423. package/deps/liburing/liburing/test/multicqes_drain.c +0 -383
  424. package/deps/liburing/liburing/test/nop-all-sizes.c +0 -107
  425. package/deps/liburing/liburing/test/nop.c +0 -115
  426. package/deps/liburing/liburing/test/open-close.c +0 -146
  427. package/deps/liburing/liburing/test/openat2.c +0 -240
  428. package/deps/liburing/liburing/test/personality.c +0 -204
  429. package/deps/liburing/liburing/test/pipe-eof.c +0 -81
  430. package/deps/liburing/liburing/test/pipe-reuse.c +0 -105
  431. package/deps/liburing/liburing/test/poll-cancel-ton.c +0 -139
  432. package/deps/liburing/liburing/test/poll-cancel.c +0 -135
  433. package/deps/liburing/liburing/test/poll-link.c +0 -227
  434. package/deps/liburing/liburing/test/poll-many.c +0 -208
  435. package/deps/liburing/liburing/test/poll-mshot-update.c +0 -273
  436. package/deps/liburing/liburing/test/poll-ring.c +0 -48
  437. package/deps/liburing/liburing/test/poll-v-poll.c +0 -353
  438. package/deps/liburing/liburing/test/poll.c +0 -109
  439. package/deps/liburing/liburing/test/probe.c +0 -137
  440. package/deps/liburing/liburing/test/read-write.c +0 -876
  441. package/deps/liburing/liburing/test/register-restrictions.c +0 -633
  442. package/deps/liburing/liburing/test/rename.c +0 -134
  443. package/deps/liburing/liburing/test/ring-leak.c +0 -173
  444. package/deps/liburing/liburing/test/ring-leak2.c +0 -249
  445. package/deps/liburing/liburing/test/rsrc_tags.c +0 -449
  446. package/deps/liburing/liburing/test/runtests-loop.sh +0 -16
  447. package/deps/liburing/liburing/test/runtests.sh +0 -170
  448. package/deps/liburing/liburing/test/rw_merge_test.c +0 -97
  449. package/deps/liburing/liburing/test/self.c +0 -91
  450. package/deps/liburing/liburing/test/send_recv.c +0 -291
  451. package/deps/liburing/liburing/test/send_recvmsg.c +0 -345
  452. package/deps/liburing/liburing/test/sendmsg_fs_cve.c +0 -198
  453. package/deps/liburing/liburing/test/shared-wq.c +0 -84
  454. package/deps/liburing/liburing/test/short-read.c +0 -75
  455. package/deps/liburing/liburing/test/shutdown.c +0 -163
  456. package/deps/liburing/liburing/test/sigfd-deadlock.c +0 -74
  457. package/deps/liburing/liburing/test/socket-rw-eagain.c +0 -156
  458. package/deps/liburing/liburing/test/socket-rw.c +0 -147
  459. package/deps/liburing/liburing/test/splice.c +0 -511
  460. package/deps/liburing/liburing/test/sq-full-cpp.cc +0 -45
  461. package/deps/liburing/liburing/test/sq-full.c +0 -45
  462. package/deps/liburing/liburing/test/sq-poll-dup.c +0 -200
  463. package/deps/liburing/liburing/test/sq-poll-kthread.c +0 -168
  464. package/deps/liburing/liburing/test/sq-poll-share.c +0 -137
  465. package/deps/liburing/liburing/test/sq-space_left.c +0 -159
  466. package/deps/liburing/liburing/test/sqpoll-cancel-hang.c +0 -159
  467. package/deps/liburing/liburing/test/sqpoll-disable-exit.c +0 -195
  468. package/deps/liburing/liburing/test/sqpoll-exit-hang.c +0 -77
  469. package/deps/liburing/liburing/test/sqpoll-sleep.c +0 -68
  470. package/deps/liburing/liburing/test/statx.c +0 -172
  471. package/deps/liburing/liburing/test/stdout.c +0 -232
  472. package/deps/liburing/liburing/test/submit-link-fail.c +0 -154
  473. package/deps/liburing/liburing/test/submit-reuse.c +0 -239
  474. package/deps/liburing/liburing/test/symlink.c +0 -116
  475. package/deps/liburing/liburing/test/teardowns.c +0 -58
  476. package/deps/liburing/liburing/test/thread-exit.c +0 -131
  477. package/deps/liburing/liburing/test/timeout-new.c +0 -246
  478. package/deps/liburing/liburing/test/timeout-overflow.c +0 -204
  479. package/deps/liburing/liburing/test/timeout.c +0 -1354
  480. package/deps/liburing/liburing/test/unlink.c +0 -111
  481. package/deps/liburing/liburing/test/wakeup-hang.c +0 -162
  482. package/deps/rocksdb/rocksdb/README.md +0 -32
  483. package/deps/rocksdb/rocksdb/microbench/README.md +0 -60
  484. package/deps/rocksdb/rocksdb/plugin/README.md +0 -43
  485. package/deps/rocksdb/rocksdb/port/README +0 -10
  486. package/deps/rocksdb/rocksdb/python.mk +0 -9
  487. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/README +0 -13
  488. package/prebuilds/darwin-x64/node.napi.node +0 -0
  489. package/prebuilds/linux-arm64/node.napi.node +0 -0
  490. package/prebuilds/linux-x64/node.napi.node +0 -0
package/binding.cc CHANGED
@@ -30,6 +30,8 @@ class NullLogger : public rocksdb::Logger {
30
30
 
31
31
  struct Database;
32
32
  struct Iterator;
33
+ struct Updates;
34
+ struct Snapshot;
33
35
 
34
36
  #define NAPI_STATUS_RETURN(call) \
35
37
  { \
@@ -47,6 +49,10 @@ struct Iterator;
47
49
  Iterator* iterator = nullptr; \
48
50
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&iterator));
49
51
 
52
+ #define NAPI_UPDATES_CONTEXT() \
53
+ Updates* updates = nullptr; \
54
+ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&updates));
55
+
50
56
  #define NAPI_BATCH_CONTEXT() \
51
57
  rocksdb::WriteBatch* batch = nullptr; \
52
58
  NAPI_STATUS_THROWS(napi_get_value_external(env, argv[0], (void**)&batch));
@@ -133,6 +139,18 @@ static std::optional<int> Int32Property(napi_env env, napi_value obj, const std:
133
139
  return {};
134
140
  }
135
141
 
142
+ static std::optional<int64_t> Int64Property(napi_env env, napi_value obj, const std::string_view& key) {
143
+ if (HasProperty(env, obj, key.data())) {
144
+ const auto value = GetProperty(env, obj, key.data());
145
+ int64_t result;
146
+ bool lossless;
147
+ napi_get_value_bigint_int64(env, value, &result, &lossless);
148
+ return result;
149
+ }
150
+
151
+ return {};
152
+ }
153
+
136
154
  static std::string ToString(napi_env env, napi_value from, const std::string& defaultValue = "") {
137
155
  if (IsString(env, from)) {
138
156
  size_t length = 0;
@@ -200,22 +218,25 @@ static void Finalize(napi_env env, void* data, void* hint) {
200
218
  }
201
219
  }
202
220
 
203
- napi_status Convert(napi_env env, std::string s, bool asBuffer, napi_value& result) {
221
+ napi_status Convert(napi_env env, rocksdb::PinnableSlice&& s, bool asBuffer, napi_value& result) {
204
222
  if (asBuffer) {
205
- auto ptr = new std::string(std::move(s));
206
- return napi_create_external_buffer(env, ptr->size(), ptr->data(), Finalize<std::string>, ptr, &result);
223
+ auto ptr = new rocksdb::PinnableSlice(std::move(s));
224
+ return napi_create_external_buffer(env, ptr->size(), const_cast<char*>(ptr->data()),
225
+ Finalize<rocksdb::PinnableSlice>, ptr, &result);
207
226
  } else {
208
227
  return napi_create_string_utf8(env, s.data(), s.size(), &result);
209
228
  }
210
229
  }
211
230
 
212
- napi_status Convert(napi_env env, rocksdb::PinnableSlice s, bool asBuffer, napi_value& result) {
213
- if (asBuffer) {
214
- auto ptr = new rocksdb::PinnableSlice(std::move(s));
215
- return napi_create_external_buffer(env, ptr->size(), const_cast<char*>(ptr->data()),
216
- Finalize<rocksdb::PinnableSlice>, ptr, &result);
231
+ napi_status Convert(napi_env env, std::optional<std::string>&& s, bool asBuffer, napi_value& result) {
232
+ if (!s) {
233
+ return napi_get_null(env, &result);
234
+ } else if (asBuffer) {
235
+ auto ptr = new std::string(std::move(*s));
236
+ return napi_create_external_buffer(env, ptr->size(), const_cast<char*>(ptr->data()), Finalize<std::string>, ptr,
237
+ &result);
217
238
  } else {
218
- return napi_create_string_utf8(env, s.data(), s.size(), &result);
239
+ return napi_create_string_utf8(env, s->data(), s->size(), &result);
219
240
  }
220
241
  }
221
242
 
@@ -327,6 +348,26 @@ struct Database {
327
348
  DecrementPriorityWork(env);
328
349
  }
329
350
 
351
+ void AttachSnapshot(napi_env env, Snapshot* snapshot) {
352
+ snapshots_.insert(snapshot);
353
+ IncrementPriorityWork(env);
354
+ }
355
+
356
+ void DetachSnapshot(napi_env env, Snapshot* snapshot) {
357
+ snapshots_.erase(snapshot);
358
+ DecrementPriorityWork(env);
359
+ }
360
+
361
+ void AttachUpdates(napi_env env, Updates* updates) {
362
+ updates_.insert(updates);
363
+ IncrementPriorityWork(env);
364
+ }
365
+
366
+ void DetachUpdates(napi_env env, Updates* updates) {
367
+ updates_.erase(updates);
368
+ DecrementPriorityWork(env);
369
+ }
370
+
330
371
  void IncrementPriorityWork(napi_env env) { napi_reference_ref(env, priorityRef_, &priorityWork_); }
331
372
 
332
373
  void DecrementPriorityWork(napi_env env) {
@@ -343,12 +384,42 @@ struct Database {
343
384
  std::unique_ptr<rocksdb::DB> db_;
344
385
  Worker* pendingCloseWorker_;
345
386
  std::set<Iterator*> iterators_;
387
+ std::set<Snapshot*> snapshots_;
388
+ std::set<Updates*> updates_;
346
389
  napi_ref priorityRef_;
347
390
 
348
391
  private:
349
392
  uint32_t priorityWork_ = 0;
350
393
  };
351
394
 
395
+ struct Snapshot {
396
+ Snapshot(Database* database)
397
+ : snapshot_(database->db_->GetSnapshot(), [=](auto ptr) { database->db_->ReleaseSnapshot(ptr); }),
398
+ database_(database) {}
399
+
400
+ void Close() { snapshot_.reset(); }
401
+
402
+ void Attach(napi_env env, napi_value context) {
403
+ napi_create_reference(env, context, 1, &ref_);
404
+ database_->AttachSnapshot(env, this);
405
+ }
406
+
407
+ void Detach(napi_env env) {
408
+ database_->DetachSnapshot(env, this);
409
+ if (ref_) {
410
+ napi_delete_reference(env, ref_);
411
+ }
412
+ }
413
+
414
+ int64_t GetSequenceNumber() const { return snapshot_->GetSequenceNumber(); }
415
+
416
+ std::shared_ptr<const rocksdb::Snapshot> snapshot_;
417
+
418
+ private:
419
+ Database* database_;
420
+ napi_ref ref_ = nullptr;
421
+ };
422
+
352
423
  struct BaseIterator {
353
424
  BaseIterator(Database* database,
354
425
  const bool reverse,
@@ -357,13 +428,9 @@ struct BaseIterator {
357
428
  const std::optional<std::string>& gt,
358
429
  const std::optional<std::string>& gte,
359
430
  const int limit,
360
- const bool fillCache)
361
- : database_(database),
362
- snapshot_(database_->db_->GetSnapshot(),
363
- [this](const rocksdb::Snapshot* ptr) { database_->db_->ReleaseSnapshot(ptr); }),
364
- reverse_(reverse),
365
- limit_(limit),
366
- fillCache_(fillCache) {
431
+ const bool fillCache,
432
+ std::shared_ptr<const rocksdb::Snapshot> snapshot)
433
+ : database_(database), snapshot_(snapshot), reverse_(reverse), limit_(limit), fillCache_(fillCache) {
367
434
  if (lte) {
368
435
  upper_bound_ = rocksdb::PinnableSlice();
369
436
  *upper_bound_->GetSelf() = std::move(*lte) + '\0';
@@ -443,6 +510,7 @@ struct BaseIterator {
443
510
  rocksdb::Status Status() const { return iterator_->status(); }
444
511
 
445
512
  Database* database_;
513
+ std::shared_ptr<const rocksdb::Snapshot> snapshot_;
446
514
 
447
515
  private:
448
516
  void Init() {
@@ -455,13 +523,13 @@ struct BaseIterator {
455
523
  }
456
524
  options.fill_cache = fillCache_;
457
525
  options.snapshot = snapshot_.get();
526
+ options.async_io = true;
458
527
 
459
528
  iterator_.reset(database_->db_->NewIterator(options));
460
529
  }
461
530
 
462
531
  std::optional<rocksdb::PinnableSlice> lower_bound_;
463
532
  std::optional<rocksdb::PinnableSlice> upper_bound_;
464
- std::shared_ptr<const rocksdb::Snapshot> snapshot_;
465
533
  std::unique_ptr<rocksdb::Iterator> iterator_;
466
534
  const bool reverse_;
467
535
  const int limit_;
@@ -482,8 +550,9 @@ struct Iterator final : public BaseIterator {
482
550
  const bool fillCache,
483
551
  const bool keyAsBuffer,
484
552
  const bool valueAsBuffer,
485
- const uint32_t highWaterMarkBytes)
486
- : BaseIterator(database, reverse, lt, lte, gt, gte, limit, fillCache),
553
+ const uint32_t highWaterMarkBytes,
554
+ std::shared_ptr<const rocksdb::Snapshot> snapshot)
555
+ : BaseIterator(database, reverse, lt, lte, gt, gte, limit, fillCache, snapshot),
487
556
  keys_(keys),
488
557
  values_(values),
489
558
  keyAsBuffer_(keyAsBuffer),
@@ -513,6 +582,34 @@ struct Iterator final : public BaseIterator {
513
582
  napi_ref ref_ = nullptr;
514
583
  };
515
584
 
585
+ struct Updates {
586
+ Updates(Database* database, const bool keyAsBuffer, const bool valueAsBuffer, int64_t seqNumber)
587
+ : database_(database), keyAsBuffer_(keyAsBuffer), valueAsBuffer_(valueAsBuffer), seqNumber_(seqNumber) {}
588
+
589
+ void Close() { iterator_.reset(); }
590
+
591
+ void Attach(napi_env env, napi_value context) {
592
+ napi_create_reference(env, context, 1, &ref_);
593
+ database_->AttachUpdates(env, this);
594
+ }
595
+
596
+ void Detach(napi_env env) {
597
+ database_->DetachUpdates(env, this);
598
+ if (ref_) {
599
+ napi_delete_reference(env, ref_);
600
+ }
601
+ }
602
+
603
+ Database* database_;
604
+ const bool keyAsBuffer_;
605
+ const bool valueAsBuffer_;
606
+ int64_t seqNumber_;
607
+ std::unique_ptr<rocksdb::TransactionLogIterator> iterator_;
608
+
609
+ private:
610
+ napi_ref ref_ = nullptr;
611
+ };
612
+
516
613
  /**
517
614
  * Hook for when the environment exits. This hook will be called after
518
615
  * already-scheduled napi_async_work items have finished, which gives us
@@ -529,8 +626,18 @@ static void env_cleanup_hook(void* arg) {
529
626
  // following code must be a safe noop if called before db_open() or after
530
627
  // db_close().
531
628
  if (database && database->db_) {
532
- // TODO: does not do `napi_delete_reference(env, iterator->ref_)`. Problem?
533
629
  for (auto it : database->iterators_) {
630
+ // TODO: does not do `napi_delete_reference`. Problem?
631
+ it->Close();
632
+ }
633
+
634
+ for (auto it : database->snapshots_) {
635
+ // TODO: does not do `napi_delete_reference`. Problem?
636
+ it->Close();
637
+ }
638
+
639
+ for (auto it : database->updates_) {
640
+ // TODO: does not do `napi_delete_reference`. Problem?
534
641
  it->Close();
535
642
  }
536
643
 
@@ -595,11 +702,48 @@ NAPI_METHOD(db_open) {
595
702
  options.IncreaseParallelism(
596
703
  Uint32Property(env, argv[2], "parallelism").value_or(std::thread::hardware_concurrency() / 2));
597
704
 
705
+ options.avoid_unnecessary_blocking_io = true;
706
+
707
+ const auto memtable_memory_budget = Uint32Property(env, argv[2], "memtableMemoryBudget").value_or(256 * 1024 * 1024);
708
+
709
+ const auto compaction = StringProperty(env, argv[2], "compaction").value_or("level");
710
+
711
+ if (compaction == "universal") {
712
+ options.write_buffer_size = static_cast<size_t>(memtable_memory_budget / 4);
713
+ // merge two memtables when flushing to L0
714
+ options.min_write_buffer_number_to_merge = 2;
715
+ // this means we'll use 50% extra memory in the worst case, but will reduce
716
+ // write stalls.
717
+ options.max_write_buffer_number = 6;
718
+ // universal style compaction
719
+ options.compaction_style = rocksdb::kCompactionStyleUniversal;
720
+ options.compaction_options_universal.compression_size_percent = 80;
721
+ } else {
722
+ // merge two memtables when flushing to L0
723
+ options.min_write_buffer_number_to_merge = 2;
724
+ // this means we'll use 50% extra memory in the worst case, but will reduce
725
+ // write stalls.
726
+ options.max_write_buffer_number = 6;
727
+ // start flushing L0->L1 as soon as possible. each file on level0 is
728
+ // (memtable_memory_budget / 2). This will flush level 0 when it's bigger than
729
+ // memtable_memory_budget.
730
+ options.level0_file_num_compaction_trigger = 2;
731
+ // doesn't really matter much, but we don't want to create too many files
732
+ options.target_file_size_base = memtable_memory_budget / 8;
733
+ // make Level1 size equal to Level0 size, so that L0->L1 compactions are fast
734
+ options.max_bytes_for_level_base = memtable_memory_budget;
735
+
736
+ // level style compaction
737
+ options.compaction_style = rocksdb::kCompactionStyleLevel;
738
+
739
+ // TODO (perf): only compress levels >= 2
740
+ }
741
+
598
742
  const auto location = ToString(env, argv[1]);
599
743
  options.create_if_missing = BooleanProperty(env, argv[2], "createIfMissing").value_or(true);
600
744
  options.error_if_exists = BooleanProperty(env, argv[2], "errorIfExists").value_or(false);
601
- options.compression = BooleanProperty(env, argv[2], "compression").value_or((true)) ? rocksdb::kZSTD
602
- : rocksdb::kNoCompression;
745
+ options.compression =
746
+ BooleanProperty(env, argv[2], "compression").value_or((true)) ? rocksdb::kZSTD : rocksdb::kNoCompression;
603
747
  if (options.compression == rocksdb::kZSTD) {
604
748
  options.compression_opts.max_dict_bytes = 16 * 1024;
605
749
  options.compression_opts.zstd_max_train_bytes = 16 * 1024 * 100;
@@ -611,6 +755,9 @@ NAPI_METHOD(db_open) {
611
755
  options.max_background_jobs =
612
756
  Uint32Property(env, argv[2], "maxBackgroundJobs").value_or(std::thread::hardware_concurrency() / 4);
613
757
 
758
+ options.WAL_ttl_seconds = Uint32Property(env, argv[2], "walTTL").value_or(0) / 1e3;
759
+ options.WAL_size_limit_MB = Uint32Property(env, argv[2], "walSizeLimit").value_or(0) / 1e6;
760
+
614
761
  // TODO: Consider direct IO (https://github.com/facebook/rocksdb/wiki/Direct-IO) once
615
762
  // secondary compressed cache is stable.
616
763
 
@@ -655,9 +802,21 @@ NAPI_METHOD(db_open) {
655
802
  tableOptions.cache_index_and_filter_blocks = false;
656
803
  }
657
804
 
805
+ const auto optimize = StringProperty(env, argv[2], "optimize").value_or("");
806
+
807
+ if (optimize == "point-lookup") {
808
+ tableOptions.data_block_index_type = rocksdb::BlockBasedTableOptions::kDataBlockBinaryAndHash;
809
+ tableOptions.data_block_hash_table_util_ratio = 0.75;
810
+ tableOptions.filter_policy.reset(rocksdb::NewRibbonFilterPolicy(10));
811
+
812
+ options.memtable_prefix_bloom_size_ratio = 0.02;
813
+ options.memtable_whole_key_filtering = true;
814
+ } else {
815
+ tableOptions.filter_policy.reset(rocksdb::NewRibbonFilterPolicy(10));
816
+ }
817
+
658
818
  tableOptions.block_size = Uint32Property(env, argv[2], "blockSize").value_or(4096);
659
819
  tableOptions.block_restart_interval = Uint32Property(env, argv[2], "blockRestartInterval").value_or(16);
660
- tableOptions.filter_policy.reset(rocksdb::NewRibbonFilterPolicy(10));
661
820
  tableOptions.format_version = 5;
662
821
  tableOptions.checksum = rocksdb::kXXH3;
663
822
  tableOptions.optimize_filters_for_memory = BooleanProperty(env, argv[2], "optimizeFiltersForMemory").value_or(true);
@@ -700,6 +859,136 @@ NAPI_METHOD(db_close) {
700
859
  return 0;
701
860
  }
702
861
 
862
+ struct UpdateNextWorker final : public rocksdb::WriteBatch::Handler, public Worker {
863
+ UpdateNextWorker(napi_env env, Updates* updates, napi_value callback)
864
+ : Worker(env, updates->database_, callback, "rocks_level.db.get"), updates_(updates) {
865
+ database_->IncrementPriorityWork(env);
866
+ }
867
+
868
+ rocksdb::Status Execute(Database& database) override {
869
+ rocksdb::TransactionLogIterator::ReadOptions options;
870
+
871
+ if (!updates_->iterator_) {
872
+ const auto status = database_->db_->GetUpdatesSince(updates_->seqNumber_, &updates_->iterator_, options);
873
+ if (!status.ok()) {
874
+ return status;
875
+ }
876
+ }
877
+
878
+ if (!updates_->iterator_->Valid()) {
879
+ return rocksdb::Status::OK();
880
+ }
881
+
882
+ auto batch = updates_->iterator_->GetBatch();
883
+
884
+ updates_->seqNumber_ = batch.sequence;
885
+
886
+ const auto status = batch.writeBatchPtr->Iterate(this);
887
+ if (!status.ok()) {
888
+ return status;
889
+ }
890
+
891
+ updates_->iterator_->Next();
892
+
893
+ return rocksdb::Status::OK();
894
+ }
895
+
896
+ napi_status OnOk(napi_env env, napi_value callback) override {
897
+ const auto size = cache_.size();
898
+ napi_value result;
899
+
900
+ if (cache_.size()) {
901
+ NAPI_STATUS_RETURN(napi_create_array_with_length(env, size, &result));
902
+
903
+ for (size_t idx = 0; idx < cache_.size(); idx += 2) {
904
+ napi_value key;
905
+ napi_value val;
906
+
907
+ NAPI_STATUS_RETURN(Convert(env, std::move(cache_[idx + 0]), updates_->keyAsBuffer_, key));
908
+ NAPI_STATUS_RETURN(Convert(env, std::move(cache_[idx + 1]), updates_->valueAsBuffer_, val));
909
+
910
+ NAPI_STATUS_RETURN(napi_set_element(env, result, static_cast<int>(idx + 0), key));
911
+ NAPI_STATUS_RETURN(napi_set_element(env, result, static_cast<int>(idx + 1), val));
912
+ }
913
+
914
+ cache_.clear();
915
+ } else {
916
+ NAPI_STATUS_RETURN(napi_get_null(env, &result));
917
+ }
918
+
919
+ napi_value argv[3];
920
+ NAPI_STATUS_RETURN(napi_get_null(env, &argv[0]));
921
+ argv[1] = result;
922
+ NAPI_STATUS_RETURN(napi_create_bigint_int64(env, updates_->seqNumber_, &argv[2]));
923
+ return CallFunction(env, callback, 3, argv);
924
+ }
925
+
926
+ void Destroy(napi_env env) override {
927
+ database_->DecrementPriorityWork(env);
928
+ Worker::Destroy(env);
929
+ }
930
+
931
+ void Put(const rocksdb::Slice& key, const rocksdb::Slice& value) override {
932
+ cache_.emplace_back(key.ToString());
933
+ cache_.emplace_back(value.ToString());
934
+ }
935
+
936
+ void Delete(const rocksdb::Slice& key) override {
937
+ cache_.emplace_back(key.ToString());
938
+ cache_.emplace_back(std::nullopt);
939
+ }
940
+
941
+ bool Continue() override { return true; }
942
+
943
+ private:
944
+ std::vector<std::optional<std::string>> cache_;
945
+ Updates* updates_;
946
+ };
947
+
948
+ NAPI_METHOD(updates_init) {
949
+ NAPI_ARGV(2);
950
+ NAPI_DB_CONTEXT();
951
+
952
+ const auto options = argv[1];
953
+
954
+ const bool keyAsBuffer = EncodingIsBuffer(env, options, "keyEncoding");
955
+ const bool valueAsBuffer = EncodingIsBuffer(env, options, "valueEncoding");
956
+ const auto seqNumber = Int64Property(env, options, "since").value_or(database->db_->GetLatestSequenceNumber());
957
+
958
+ auto updates = std::make_unique<Updates>(database, keyAsBuffer, valueAsBuffer, seqNumber);
959
+
960
+ napi_value result;
961
+ NAPI_STATUS_THROWS(napi_create_external(env, updates.get(), Finalize<Updates>, updates.get(), &result));
962
+
963
+ // Prevent GC of JS object before the iterator is closed (explicitly or on
964
+ // db close) and keep track of non-closed iterators to end them on db close.
965
+ updates.release()->Attach(env, result);
966
+
967
+ return result;
968
+ }
969
+
970
+ NAPI_METHOD(updates_next) {
971
+ NAPI_ARGV(2);
972
+ NAPI_UPDATES_CONTEXT();
973
+
974
+ const auto callback = argv[1];
975
+
976
+ auto worker = new UpdateNextWorker(env, updates, callback);
977
+ worker->Queue(env);
978
+
979
+ return 0;
980
+ }
981
+
982
+ NAPI_METHOD(updates_close) {
983
+ NAPI_ARGV(1);
984
+ NAPI_UPDATES_CONTEXT();
985
+
986
+ updates->Detach(env);
987
+ updates->Close();
988
+
989
+ return 0;
990
+ }
991
+
703
992
  NAPI_METHOD(db_put) {
704
993
  NAPI_ARGV(4);
705
994
  NAPI_DB_CONTEXT();
@@ -735,7 +1024,7 @@ struct GetWorker final : public Worker {
735
1024
  options.fill_cache = fillCache_;
736
1025
  options.snapshot = snapshot_.get();
737
1026
 
738
- auto status = database.db_->Get(options, key_, &value_);
1027
+ auto status = database.db_->Get(options, database.db_->DefaultColumnFamily(), key_, &value_);
739
1028
 
740
1029
  key_.clear();
741
1030
  snapshot_ = nullptr;
@@ -757,7 +1046,7 @@ struct GetWorker final : public Worker {
757
1046
 
758
1047
  private:
759
1048
  std::string key_;
760
- std::string value_;
1049
+ rocksdb::PinnableSlice value_;
761
1050
  const bool asBuffer_;
762
1051
  const bool fillCache_;
763
1052
  std::shared_ptr<const rocksdb::Snapshot> snapshot_;
@@ -790,8 +1079,7 @@ struct GetManyWorker final : public Worker {
790
1079
  keys_(std::move(keys)),
791
1080
  valueAsBuffer_(valueAsBuffer),
792
1081
  fillCache_(fillCache),
793
- snapshot_(database_->db_->GetSnapshot(),
794
- [this](const rocksdb::Snapshot* ptr) { database_->db_->ReleaseSnapshot(ptr); }) {
1082
+ snapshot_(database_->db_->GetSnapshot(), [=](const auto ptr) { database_->db_->ReleaseSnapshot(ptr); }) {
795
1083
  database_->IncrementPriorityWork(env);
796
1084
  }
797
1085
 
@@ -799,6 +1087,7 @@ struct GetManyWorker final : public Worker {
799
1087
  rocksdb::ReadOptions options;
800
1088
  options.fill_cache = fillCache_;
801
1089
  options.snapshot = snapshot_.get();
1090
+ options.async_io = true;
802
1091
 
803
1092
  const auto numKeys = keys_.size();
804
1093
 
@@ -917,7 +1206,7 @@ NAPI_METHOD(db_clear) {
917
1206
  const auto lte = StringProperty(env, argv[1], "lte");
918
1207
  const auto gt = StringProperty(env, argv[1], "gt");
919
1208
  const auto gte = StringProperty(env, argv[1], "gte");
920
-
1209
+
921
1210
  if (!reverse && limit == -1 && (lte || lt)) {
922
1211
  rocksdb::Slice begin;
923
1212
  if (gte) {
@@ -945,7 +1234,8 @@ NAPI_METHOD(db_clear) {
945
1234
  } else {
946
1235
  // TODO (perf): Use DeleteRange.
947
1236
 
948
- BaseIterator it(database, reverse, lt, lte, gt, gte, limit, false);
1237
+ Snapshot snapshot(database);
1238
+ BaseIterator it(database, reverse, lt, lte, gt, gte, limit, false, snapshot.snapshot_);
949
1239
 
950
1240
  it.SeekToRange();
951
1241
 
@@ -1001,6 +1291,18 @@ NAPI_METHOD(db_get_property) {
1001
1291
  return result;
1002
1292
  }
1003
1293
 
1294
+ NAPI_METHOD(db_get_latest_sequence_number) {
1295
+ NAPI_ARGV(1);
1296
+ NAPI_DB_CONTEXT();
1297
+
1298
+ const auto seq = database->db_->GetLatestSequenceNumber();
1299
+
1300
+ napi_value result;
1301
+ NAPI_STATUS_THROWS(napi_create_bigint_int64(env, seq, &result));
1302
+
1303
+ return result;
1304
+ }
1305
+
1004
1306
  NAPI_METHOD(iterator_init) {
1005
1307
  NAPI_ARGV(2);
1006
1308
  NAPI_DB_CONTEXT();
@@ -1020,8 +1322,20 @@ NAPI_METHOD(iterator_init) {
1020
1322
  const auto gt = StringProperty(env, options, "gt");
1021
1323
  const auto gte = StringProperty(env, options, "gte");
1022
1324
 
1325
+ std::shared_ptr<const rocksdb::Snapshot> snapshotRaw;
1326
+
1327
+ if (HasProperty(env, options, "snapshot")) {
1328
+ const auto property = GetProperty(env, options, "snapshot");
1329
+ Snapshot* snapshot;
1330
+ NAPI_STATUS_THROWS(napi_get_value_external(env, property, reinterpret_cast<void**>(&snapshot)));
1331
+ snapshotRaw = snapshot->snapshot_;
1332
+ } else {
1333
+ Snapshot snapshot(database);
1334
+ snapshotRaw = snapshot.snapshot_;
1335
+ }
1336
+
1023
1337
  auto iterator = std::make_unique<Iterator>(database, reverse, keys, values, limit, lt, lte, gt, gte, fillCache,
1024
- keyAsBuffer, valueAsBuffer, highWaterMarkBytes);
1338
+ keyAsBuffer, valueAsBuffer, highWaterMarkBytes, std::move(snapshotRaw));
1025
1339
 
1026
1340
  napi_value result;
1027
1341
  NAPI_STATUS_THROWS(napi_create_external(env, iterator.get(), Finalize<Iterator>, iterator.get(), &result));
@@ -1056,6 +1370,18 @@ NAPI_METHOD(iterator_close) {
1056
1370
  return 0;
1057
1371
  }
1058
1372
 
1373
+ NAPI_METHOD(iterator_get_sequence) {
1374
+ NAPI_ARGV(1);
1375
+ NAPI_ITERATOR_CONTEXT();
1376
+
1377
+ const auto seq = iterator->snapshot_->GetSequenceNumber();
1378
+
1379
+ napi_value result;
1380
+ NAPI_STATUS_THROWS(napi_create_bigint_int64(env, seq, &result));
1381
+
1382
+ return 0;
1383
+ }
1384
+
1059
1385
  struct NextWorker final : public Worker {
1060
1386
  NextWorker(napi_env env, Iterator* iterator, uint32_t size, napi_value callback)
1061
1387
  : Worker(env, iterator->database_, callback, "leveldown.iterator.next"), iterator_(iterator), size_(size) {}
@@ -1080,27 +1406,29 @@ struct NextWorker final : public Worker {
1080
1406
  if (iterator_->keys_ && iterator_->values_) {
1081
1407
  auto k = iterator_->CurrentKey();
1082
1408
  auto v = iterator_->CurrentValue();
1083
- cache_.emplace_back(k.data(), k.size());
1084
- cache_.emplace_back(v.data(), v.size());
1085
1409
  bytesRead += k.size() + v.size();
1410
+ cache_.push_back(k.ToString());
1411
+ cache_.push_back(v.ToString());
1086
1412
  } else if (iterator_->keys_) {
1087
1413
  auto k = iterator_->CurrentKey();
1088
- cache_.emplace_back(k.data(), k.size());
1089
- cache_.push_back({});
1090
1414
  bytesRead += k.size();
1415
+ cache_.push_back(k.ToString());
1416
+ cache_.push_back(std::nullopt);
1091
1417
  } else if (iterator_->values_) {
1092
1418
  auto v = iterator_->CurrentValue();
1093
- cache_.push_back({});
1094
- cache_.emplace_back(v.data(), v.size());
1095
1419
  bytesRead += v.size();
1420
+ cache_.push_back(std::nullopt);
1421
+ cache_.push_back(v.ToString());
1096
1422
  }
1097
1423
 
1098
1424
  if (bytesRead > iterator_->highWaterMarkBytes_ || cache_.size() / 2 >= size_) {
1099
- finished_ = true;
1425
+ finished_ = false;
1100
1426
  return rocksdb::Status::OK();
1101
1427
  }
1102
1428
  }
1103
1429
 
1430
+ finished_ = true;
1431
+
1104
1432
  return iterator_->Status();
1105
1433
  }
1106
1434
 
@@ -1125,15 +1453,15 @@ struct NextWorker final : public Worker {
1125
1453
  napi_value argv[3];
1126
1454
  NAPI_STATUS_RETURN(napi_get_null(env, &argv[0]));
1127
1455
  argv[1] = result;
1128
- NAPI_STATUS_RETURN(napi_get_boolean(env, !finished_, &argv[2]));
1456
+ NAPI_STATUS_RETURN(napi_get_boolean(env, finished_, &argv[2]));
1129
1457
  return CallFunction(env, callback, 3, argv);
1130
1458
  }
1131
1459
 
1132
1460
  private:
1133
- std::vector<std::string> cache_;
1461
+ std::vector<std::optional<std::string>> cache_;
1134
1462
  Iterator* iterator_ = nullptr;
1135
1463
  uint32_t size_ = 0;
1136
- bool finished_ = false;
1464
+ bool finished_ = true;
1137
1465
  };
1138
1466
 
1139
1467
  NAPI_METHOD(iterator_nextv) {
@@ -1244,10 +1572,54 @@ NAPI_METHOD(batch_write) {
1244
1572
  return ToError(env, database->db_->Write(options, batch));
1245
1573
  }
1246
1574
 
1575
+ NAPI_METHOD(snapshot_init) {
1576
+ NAPI_ARGV(1);
1577
+ NAPI_DB_CONTEXT();
1578
+
1579
+ auto snapshot = std::make_unique<Snapshot>(database);
1580
+
1581
+ napi_value result;
1582
+ NAPI_STATUS_THROWS(napi_create_external(env, snapshot.get(), Finalize<Snapshot>, snapshot.get(), &result));
1583
+
1584
+ // Prevent GC of JS object before the iterator is closed (explicitly or on
1585
+ // db close) and keep track of non-closed iterators to end them on db close.
1586
+ snapshot.release()->Attach(env, result);
1587
+
1588
+ return result;
1589
+ }
1590
+
1591
+ NAPI_METHOD(snapshot_get_sequence_number) {
1592
+ NAPI_ARGV(3);
1593
+ NAPI_DB_CONTEXT();
1594
+
1595
+ Snapshot* snapshot;
1596
+ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], reinterpret_cast<void**>(&snapshot)));
1597
+
1598
+ const auto seq = snapshot->GetSequenceNumber();
1599
+
1600
+ napi_value result;
1601
+ NAPI_STATUS_THROWS(napi_create_bigint_int64(env, seq, &result));
1602
+
1603
+ return result;
1604
+ }
1605
+
1606
+ NAPI_METHOD(snapshot_close) {
1607
+ NAPI_ARGV(2);
1608
+ NAPI_DB_CONTEXT();
1609
+
1610
+ Snapshot* snapshot;
1611
+ NAPI_STATUS_THROWS(napi_get_value_external(env, argv[1], reinterpret_cast<void**>(&snapshot)));
1612
+
1613
+ snapshot->Close();
1614
+
1615
+ return 0;
1616
+ }
1617
+
1247
1618
  NAPI_INIT() {
1248
1619
  NAPI_EXPORT_FUNCTION(db_init);
1249
1620
  NAPI_EXPORT_FUNCTION(db_open);
1250
1621
  NAPI_EXPORT_FUNCTION(db_close);
1622
+ NAPI_EXPORT_FUNCTION(db_get_latest_sequence_number);
1251
1623
  NAPI_EXPORT_FUNCTION(db_put);
1252
1624
  NAPI_EXPORT_FUNCTION(db_get);
1253
1625
  NAPI_EXPORT_FUNCTION(db_get_many);
@@ -1259,6 +1631,11 @@ NAPI_INIT() {
1259
1631
  NAPI_EXPORT_FUNCTION(iterator_seek);
1260
1632
  NAPI_EXPORT_FUNCTION(iterator_close);
1261
1633
  NAPI_EXPORT_FUNCTION(iterator_nextv);
1634
+ NAPI_EXPORT_FUNCTION(iterator_get_sequence);
1635
+
1636
+ NAPI_EXPORT_FUNCTION(updates_init);
1637
+ NAPI_EXPORT_FUNCTION(updates_close);
1638
+ NAPI_EXPORT_FUNCTION(updates_next);
1262
1639
 
1263
1640
  NAPI_EXPORT_FUNCTION(batch_do);
1264
1641
  NAPI_EXPORT_FUNCTION(batch_init);
@@ -1266,4 +1643,8 @@ NAPI_INIT() {
1266
1643
  NAPI_EXPORT_FUNCTION(batch_del);
1267
1644
  NAPI_EXPORT_FUNCTION(batch_clear);
1268
1645
  NAPI_EXPORT_FUNCTION(batch_write);
1646
+
1647
+ NAPI_EXPORT_FUNCTION(snapshot_init);
1648
+ NAPI_EXPORT_FUNCTION(snapshot_get_sequence_number);
1649
+ NAPI_EXPORT_FUNCTION(snapshot_close);
1269
1650
  }