@nxtedition/rocksdb 15.4.1 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. package/binding.cc +70 -23
  2. package/deps/rocksdb/rocksdb/.clang-tidy +86 -0
  3. package/deps/rocksdb/rocksdb/BUCK +42 -0
  4. package/deps/rocksdb/rocksdb/CMakeLists.txt +11 -0
  5. package/deps/rocksdb/rocksdb/Makefile +59 -32
  6. package/deps/rocksdb/rocksdb/cache/cache.cc +0 -5
  7. package/deps/rocksdb/rocksdb/cache/cache_entry_stats.h +9 -9
  8. package/deps/rocksdb/rocksdb/cache/cache_key.cc +3 -3
  9. package/deps/rocksdb/rocksdb/cache/cache_key.h +5 -5
  10. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager.h +16 -16
  11. package/deps/rocksdb/rocksdb/cache/cache_test.cc +1 -1
  12. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +258 -294
  13. package/deps/rocksdb/rocksdb/cache/clock_cache.h +98 -49
  14. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +1 -5
  15. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +2 -3
  16. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +18 -18
  17. package/deps/rocksdb/rocksdb/crash_test.mk +5 -1
  18. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.cc +23 -22
  19. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.h +6 -1
  20. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder_test.cc +14 -16
  21. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +38 -26
  22. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.h +5 -1
  23. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader_test.cc +101 -18
  24. package/deps/rocksdb/rocksdb/db/blob/blob_index.h +12 -0
  25. package/deps/rocksdb/rocksdb/db/blob/blob_source_test.cc +6 -9
  26. package/deps/rocksdb/rocksdb/db/builder.cc +23 -0
  27. package/deps/rocksdb/rocksdb/db/builder.h +7 -0
  28. package/deps/rocksdb/rocksdb/db/c.cc +373 -57
  29. package/deps/rocksdb/rocksdb/db/c_test.c +101 -1
  30. package/deps/rocksdb/rocksdb/db/column_family.cc +31 -3
  31. package/deps/rocksdb/rocksdb/db/column_family_test.cc +10 -13
  32. package/deps/rocksdb/rocksdb/db/compact_files_test.cc +35 -48
  33. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +13 -5
  34. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +201 -39
  35. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +15 -10
  36. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_stats_test.cc +7 -7
  37. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +2 -455
  38. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.cc +4 -2
  39. package/deps/rocksdb/rocksdb/db/compaction/compaction_outputs.h +19 -0
  40. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +72 -9
  41. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +12 -10
  42. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +405 -83
  43. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +25 -1
  44. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +23 -10
  45. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +1 -0
  46. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +1410 -106
  47. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +12 -5
  48. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +2 -1
  49. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_job.cc +19 -10
  50. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +505 -45
  51. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.cc +2 -2
  52. package/deps/rocksdb/rocksdb/db/compaction/subcompaction_state.h +9 -1
  53. package/deps/rocksdb/rocksdb/db/compaction/tiered_compaction_test.cc +4 -4
  54. package/deps/rocksdb/rocksdb/db/comparator_db_test.cc +7 -9
  55. package/deps/rocksdb/rocksdb/db/convenience.cc +4 -4
  56. package/deps/rocksdb/rocksdb/db/convenience_impl.h +2 -1
  57. package/deps/rocksdb/rocksdb/db/corruption_test.cc +60 -88
  58. package/deps/rocksdb/rocksdb/db/cuckoo_table_db_test.cc +10 -12
  59. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +471 -40
  60. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +116 -2
  61. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +5 -15
  62. package/deps/rocksdb/rocksdb/db/db_compaction_abort_test.cc +993 -0
  63. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +329 -29
  64. package/deps/rocksdb/rocksdb/db/db_flush_test.cc +155 -13
  65. package/deps/rocksdb/rocksdb/db/db_impl/compacted_db_impl.cc +54 -31
  66. package/deps/rocksdb/rocksdb/db/db_impl/compacted_db_impl.h +1 -0
  67. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +232 -70
  68. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +57 -9
  69. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +224 -31
  70. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +5 -0
  71. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +4 -2
  72. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +1 -1
  73. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_follower.cc +1 -0
  74. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +164 -8
  75. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +6 -0
  76. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.h +5 -0
  77. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +47 -35
  78. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.h +22 -9
  79. package/deps/rocksdb/rocksdb/db/db_iter.cc +9 -0
  80. package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +371 -6
  81. package/deps/rocksdb/rocksdb/db/db_log_iter_test.cc +7 -5
  82. package/deps/rocksdb/rocksdb/db/db_logical_block_size_cache_test.cc +22 -23
  83. package/deps/rocksdb/rocksdb/db/db_memtable_test.cc +0 -2
  84. package/deps/rocksdb/rocksdb/db/db_merge_operator_test.cc +4 -4
  85. package/deps/rocksdb/rocksdb/db/db_options_test.cc +40 -0
  86. package/deps/rocksdb/rocksdb/db/db_properties_test.cc +32 -13
  87. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +1 -1
  88. package/deps/rocksdb/rocksdb/db/db_readonly_with_timestamp_test.cc +4 -4
  89. package/deps/rocksdb/rocksdb/db/db_secondary_test.cc +68 -15
  90. package/deps/rocksdb/rocksdb/db/db_sst_test.cc +1 -1
  91. package/deps/rocksdb/rocksdb/db/db_statistics_test.cc +2 -3
  92. package/deps/rocksdb/rocksdb/db/db_table_properties_test.cc +6 -21
  93. package/deps/rocksdb/rocksdb/db/db_test.cc +644 -128
  94. package/deps/rocksdb/rocksdb/db/db_test2.cc +198 -81
  95. package/deps/rocksdb/rocksdb/db/db_test_util.cc +35 -10
  96. package/deps/rocksdb/rocksdb/db/db_test_util.h +8 -2
  97. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +36 -32
  98. package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +11 -7
  99. package/deps/rocksdb/rocksdb/db/db_with_timestamp_compaction_test.cc +499 -0
  100. package/deps/rocksdb/rocksdb/db/db_write_buffer_manager_test.cc +284 -20
  101. package/deps/rocksdb/rocksdb/db/db_write_test.cc +3 -3
  102. package/deps/rocksdb/rocksdb/db/dbformat.h +0 -5
  103. package/deps/rocksdb/rocksdb/db/error_handler.cc +24 -0
  104. package/deps/rocksdb/rocksdb/db/error_handler_fs_test.cc +12 -14
  105. package/deps/rocksdb/rocksdb/db/experimental.cc +13 -10
  106. package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +1 -1
  107. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +22 -3
  108. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +21 -15
  109. package/deps/rocksdb/rocksdb/db/fault_injection_test.cc +4 -6
  110. package/deps/rocksdb/rocksdb/db/flush_job.cc +11 -3
  111. package/deps/rocksdb/rocksdb/db/forward_iterator_bench.cc +5 -6
  112. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +4 -2
  113. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +17 -17
  114. package/deps/rocksdb/rocksdb/db/internal_stats.cc +13 -0
  115. package/deps/rocksdb/rocksdb/db/internal_stats.h +2 -0
  116. package/deps/rocksdb/rocksdb/db/listener_test.cc +154 -27
  117. package/deps/rocksdb/rocksdb/db/manual_compaction_test.cc +6 -6
  118. package/deps/rocksdb/rocksdb/db/memtable.cc +197 -51
  119. package/deps/rocksdb/rocksdb/db/memtable.h +6 -0
  120. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +3 -4
  121. package/deps/rocksdb/rocksdb/db/merge_test.cc +37 -35
  122. package/deps/rocksdb/rocksdb/db/obsolete_files_test.cc +2 -1
  123. package/deps/rocksdb/rocksdb/db/options_file_test.cc +4 -4
  124. package/deps/rocksdb/rocksdb/db/perf_context_test.cc +9 -11
  125. package/deps/rocksdb/rocksdb/db/periodic_task_scheduler.cc +10 -1
  126. package/deps/rocksdb/rocksdb/db/periodic_task_scheduler_test.cc +292 -15
  127. package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +10 -17
  128. package/deps/rocksdb/rocksdb/db/prefix_test.cc +6 -8
  129. package/deps/rocksdb/rocksdb/db/repair.cc +10 -10
  130. package/deps/rocksdb/rocksdb/db/seqno_time_test.cc +5 -5
  131. package/deps/rocksdb/rocksdb/db/table_cache.cc +142 -135
  132. package/deps/rocksdb/rocksdb/db/table_cache.h +30 -6
  133. package/deps/rocksdb/rocksdb/db/table_cache_sync_and_async.h +7 -7
  134. package/deps/rocksdb/rocksdb/db/version_builder.cc +11 -50
  135. package/deps/rocksdb/rocksdb/db/version_builder.h +2 -1
  136. package/deps/rocksdb/rocksdb/db/version_builder_test.cc +2 -1
  137. package/deps/rocksdb/rocksdb/db/version_edit.cc +51 -2
  138. package/deps/rocksdb/rocksdb/db/version_edit.h +91 -29
  139. package/deps/rocksdb/rocksdb/db/version_edit_handler.h +7 -7
  140. package/deps/rocksdb/rocksdb/db/version_set.cc +211 -50
  141. package/deps/rocksdb/rocksdb/db/version_set.h +40 -3
  142. package/deps/rocksdb/rocksdb/db/version_set_sync_and_async.h +5 -0
  143. package/deps/rocksdb/rocksdb/db/version_set_test.cc +294 -21
  144. package/deps/rocksdb/rocksdb/db/version_util.cc +96 -0
  145. package/deps/rocksdb/rocksdb/db/version_util.h +24 -0
  146. package/deps/rocksdb/rocksdb/db/wide/db_wide_basic_test.cc +5 -5
  147. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.cc +647 -31
  148. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization.h +219 -1
  149. package/deps/rocksdb/rocksdb/db/wide/wide_column_serialization_test.cc +549 -12
  150. package/deps/rocksdb/rocksdb/db/write_callback_test.cc +3 -3
  151. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +1 -1
  152. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +19 -0
  153. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +21 -4
  154. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_env_wrapper.h +32 -0
  155. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +74 -22
  156. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_listener.h +9 -0
  157. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +143 -61
  158. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +15 -2
  159. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +76 -2
  160. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +92 -72
  161. package/deps/rocksdb/rocksdb/env/env.cc +1 -0
  162. package/deps/rocksdb/rocksdb/env/env_test.cc +365 -2
  163. package/deps/rocksdb/rocksdb/env/fs_posix.cc +31 -30
  164. package/deps/rocksdb/rocksdb/env/io_posix.cc +8 -11
  165. package/deps/rocksdb/rocksdb/env/io_posix.h +30 -1
  166. package/deps/rocksdb/rocksdb/env/io_posix_test.cc +43 -0
  167. package/deps/rocksdb/rocksdb/file/delete_scheduler.cc +1 -1
  168. package/deps/rocksdb/rocksdb/file/delete_scheduler_test.cc +108 -0
  169. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +32 -4
  170. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +4 -4
  171. package/deps/rocksdb/rocksdb/file/file_util.cc +8 -2
  172. package/deps/rocksdb/rocksdb/file/file_util.h +2 -1
  173. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +331 -12
  174. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +52 -35
  175. package/deps/rocksdb/rocksdb/folly.mk +22 -5
  176. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_cache.h +1 -1
  177. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_compression.h +100 -54
  178. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +67 -2
  179. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +149 -13
  180. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +1 -12
  181. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +78 -97
  182. package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +3 -3
  183. package/deps/rocksdb/rocksdb/include/rocksdb/external_table.h +2 -2
  184. package/deps/rocksdb/rocksdb/include/rocksdb/file_checksum.h +5 -0
  185. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +17 -2
  186. package/deps/rocksdb/rocksdb/include/rocksdb/functor_wrapper.h +1 -1
  187. package/deps/rocksdb/rocksdb/include/rocksdb/io_dispatcher.h +358 -0
  188. package/deps/rocksdb/rocksdb/include/rocksdb/iostats_context.h +13 -0
  189. package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +43 -0
  190. package/deps/rocksdb/rocksdb/include/rocksdb/memtablerep.h +20 -0
  191. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +63 -21
  192. package/deps/rocksdb/rocksdb/include/rocksdb/perf_context.h +10 -1
  193. package/deps/rocksdb/rocksdb/include/rocksdb/rate_limiter.h +1 -1
  194. package/deps/rocksdb/rocksdb/include/rocksdb/slice_transform.h +2 -7
  195. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_reader.h +13 -0
  196. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +3 -14
  197. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +49 -9
  198. package/deps/rocksdb/rocksdb/include/rocksdb/status.h +8 -0
  199. package/deps/rocksdb/rocksdb/include/rocksdb/table.h +77 -6
  200. package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +15 -0
  201. package/deps/rocksdb/rocksdb/include/rocksdb/tool_hooks.h +16 -10
  202. package/deps/rocksdb/rocksdb/include/rocksdb/unique_id.h +5 -5
  203. package/deps/rocksdb/rocksdb/include/rocksdb/universal_compaction.h +2 -4
  204. package/deps/rocksdb/rocksdb/include/rocksdb/user_defined_index.h +106 -46
  205. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/db_ttl.h +1 -1
  206. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd.h +14 -1
  207. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/memory_util.h +5 -1
  208. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/optimistic_transaction_db.h +2 -1
  209. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +7 -9
  210. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +2 -2
  211. package/deps/rocksdb/rocksdb/logging/auto_roll_logger_test.cc +1 -2
  212. package/deps/rocksdb/rocksdb/memory/memory_allocator_test.cc +2 -2
  213. package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +226 -8
  214. package/deps/rocksdb/rocksdb/memtable/inlineskiplist_test.cc +490 -0
  215. package/deps/rocksdb/rocksdb/memtable/skiplist.h +3 -3
  216. package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +11 -0
  217. package/deps/rocksdb/rocksdb/microbench/db_basic_bench.cc +4 -12
  218. package/deps/rocksdb/rocksdb/microbench/ribbon_bench.cc +5 -5
  219. package/deps/rocksdb/rocksdb/monitoring/file_read_sample.h +21 -4
  220. package/deps/rocksdb/rocksdb/monitoring/perf_context.cc +9 -3
  221. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +21 -2
  222. package/deps/rocksdb/rocksdb/monitoring/stats_history_test.cc +2 -2
  223. package/deps/rocksdb/rocksdb/options/cf_options.cc +21 -1
  224. package/deps/rocksdb/rocksdb/options/cf_options.h +2 -0
  225. package/deps/rocksdb/rocksdb/options/customizable_test.cc +0 -2
  226. package/deps/rocksdb/rocksdb/options/db_options.cc +26 -5
  227. package/deps/rocksdb/rocksdb/options/db_options.h +3 -1
  228. package/deps/rocksdb/rocksdb/options/options.cc +5 -1
  229. package/deps/rocksdb/rocksdb/options/options_helper.cc +7 -2
  230. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +109 -103
  231. package/deps/rocksdb/rocksdb/options/options_test.cc +14 -0
  232. package/deps/rocksdb/rocksdb/port/jemalloc_helper.h +15 -17
  233. package/deps/rocksdb/rocksdb/port/lang.h +4 -0
  234. package/deps/rocksdb/rocksdb/port/port_example.h +0 -23
  235. package/deps/rocksdb/rocksdb/port/stack_trace.cc +36 -0
  236. package/deps/rocksdb/rocksdb/port/stack_trace.h +9 -0
  237. package/deps/rocksdb/rocksdb/src.mk +12 -0
  238. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.cc +1 -2
  239. package/deps/rocksdb/rocksdb/table/block_based/binary_search_index_reader.cc +2 -1
  240. package/deps/rocksdb/rocksdb/table/block_based/block.cc +571 -292
  241. package/deps/rocksdb/rocksdb/table/block_based/block.h +143 -53
  242. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +154 -90
  243. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +5 -1
  244. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +51 -14
  245. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +0 -2
  246. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +147 -734
  247. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +30 -233
  248. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +178 -108
  249. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +13 -0
  250. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +17 -4
  251. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_sync_and_async.h +5 -2
  252. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +70 -0
  253. package/deps/rocksdb/rocksdb/table/block_based/block_builder.cc +168 -24
  254. package/deps/rocksdb/rocksdb/table/block_based/block_builder.h +25 -9
  255. package/deps/rocksdb/rocksdb/table/block_based/block_cache.cc +7 -4
  256. package/deps/rocksdb/rocksdb/table/block_based/block_cache.h +9 -2
  257. package/deps/rocksdb/rocksdb/table/block_based/block_test.cc +548 -169
  258. package/deps/rocksdb/rocksdb/table/block_based/block_type.h +30 -0
  259. package/deps/rocksdb/rocksdb/table/block_based/block_util.h +156 -0
  260. package/deps/rocksdb/rocksdb/table/block_based/data_block_footer.cc +73 -30
  261. package/deps/rocksdb/rocksdb/table/block_based/data_block_footer.h +74 -7
  262. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index.h +1 -1
  263. package/deps/rocksdb/rocksdb/table/block_based/index_builder.cc +20 -14
  264. package/deps/rocksdb/rocksdb/table/block_based/index_builder.h +22 -12
  265. package/deps/rocksdb/rocksdb/table/block_based/mock_block_based_table.h +1 -1
  266. package/deps/rocksdb/rocksdb/table/block_based/multi_scan_index_iterator.cc +332 -0
  267. package/deps/rocksdb/rocksdb/table/block_based/multi_scan_index_iterator.h +133 -0
  268. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +4 -2
  269. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +1 -1
  270. package/deps/rocksdb/rocksdb/table/block_based/reader_common.cc +3 -2
  271. package/deps/rocksdb/rocksdb/table/block_based/reader_common.h +4 -1
  272. package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.h +0 -1
  273. package/deps/rocksdb/rocksdb/table/block_based/user_defined_index_wrapper.h +126 -46
  274. package/deps/rocksdb/rocksdb/table/block_fetcher.cc +31 -3
  275. package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +1 -2
  276. package/deps/rocksdb/rocksdb/table/cleanable_test.cc +3 -1
  277. package/deps/rocksdb/rocksdb/table/external_table.cc +25 -4
  278. package/deps/rocksdb/rocksdb/table/format.cc +27 -15
  279. package/deps/rocksdb/rocksdb/table/format.h +41 -15
  280. package/deps/rocksdb/rocksdb/table/merging_iterator.cc +1 -0
  281. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +22 -12
  282. package/deps/rocksdb/rocksdb/table/meta_blocks.h +0 -1
  283. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +7 -21
  284. package/deps/rocksdb/rocksdb/table/sst_file_dumper.h +0 -1
  285. package/deps/rocksdb/rocksdb/table/sst_file_reader.cc +88 -13
  286. package/deps/rocksdb/rocksdb/table/sst_file_reader_test.cc +53 -42
  287. package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +3 -12
  288. package/deps/rocksdb/rocksdb/table/table_builder.h +0 -4
  289. package/deps/rocksdb/rocksdb/table/table_properties.cc +18 -0
  290. package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +2 -3
  291. package/deps/rocksdb/rocksdb/table/table_test.cc +848 -172
  292. package/deps/rocksdb/rocksdb/table/unique_id.cc +24 -20
  293. package/deps/rocksdb/rocksdb/table/unique_id_impl.h +8 -8
  294. package/deps/rocksdb/rocksdb/test_util/sync_point.h +5 -4
  295. package/deps/rocksdb/rocksdb/test_util/testutil.cc +2 -1
  296. package/deps/rocksdb/rocksdb/test_util/testutil.h +2 -2
  297. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc +2 -1
  298. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +238 -120
  299. package/deps/rocksdb/rocksdb/tools/db_repl_stress.cc +2 -2
  300. package/deps/rocksdb/rocksdb/tools/db_sanity_test.cc +2 -4
  301. package/deps/rocksdb/rocksdb/tools/dump/db_dump_tool.cc +4 -8
  302. package/deps/rocksdb/rocksdb/tools/dump/rocksdb_undump.cc +1 -1
  303. package/deps/rocksdb/rocksdb/tools/io_tracer_parser_test.cc +2 -3
  304. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +82 -20
  305. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +41 -47
  306. package/deps/rocksdb/rocksdb/tools/ldb_tool.cc +9 -0
  307. package/deps/rocksdb/rocksdb/tools/reduce_levels_test.cc +5 -6
  308. package/deps/rocksdb/rocksdb/tools/sst_dump_tool.cc +1 -1
  309. package/deps/rocksdb/rocksdb/tools/tool_hooks.cc +6 -5
  310. package/deps/rocksdb/rocksdb/tools/trace_analyzer_test.cc +4 -4
  311. package/deps/rocksdb/rocksdb/tools/write_stress.cc +1 -3
  312. package/deps/rocksdb/rocksdb/util/atomic.h +30 -23
  313. package/deps/rocksdb/rocksdb/util/auto_tune_compressor.cc +6 -7
  314. package/deps/rocksdb/rocksdb/util/auto_tune_compressor.h +3 -3
  315. package/deps/rocksdb/rocksdb/util/bit_fields.h +68 -46
  316. package/deps/rocksdb/rocksdb/util/bloom_impl.h +16 -16
  317. package/deps/rocksdb/rocksdb/util/coding.h +14 -27
  318. package/deps/rocksdb/rocksdb/util/compression.cc +365 -207
  319. package/deps/rocksdb/rocksdb/util/compression.h +16 -1298
  320. package/deps/rocksdb/rocksdb/util/compression_test.cc +347 -61
  321. package/deps/rocksdb/rocksdb/util/crc32c_arm64.cc +8 -9
  322. package/deps/rocksdb/rocksdb/util/crc32c_arm64.h +1 -1
  323. package/deps/rocksdb/rocksdb/util/crc32c_ppc.h +1 -1
  324. package/deps/rocksdb/rocksdb/util/dynamic_bloom_test.cc +3 -3
  325. package/deps/rocksdb/rocksdb/util/filter_bench.cc +18 -18
  326. package/deps/rocksdb/rocksdb/util/gflags_compat.h +3 -3
  327. package/deps/rocksdb/rocksdb/util/hash_test.cc +19 -7
  328. package/deps/rocksdb/rocksdb/util/io_dispatcher_imp.cc +1099 -0
  329. package/deps/rocksdb/rocksdb/util/io_dispatcher_imp.h +36 -0
  330. package/deps/rocksdb/rocksdb/util/io_dispatcher_test.cc +1919 -0
  331. package/deps/rocksdb/rocksdb/util/math.h +3 -1
  332. package/deps/rocksdb/rocksdb/util/mutexlock.h +19 -19
  333. package/deps/rocksdb/rocksdb/util/ribbon_alg.h +25 -25
  334. package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.cc +5 -7
  335. package/deps/rocksdb/rocksdb/util/simple_mixed_compressor.h +4 -5
  336. package/deps/rocksdb/rocksdb/util/slice.cc +0 -10
  337. package/deps/rocksdb/rocksdb/util/slice_test.cc +35 -1
  338. package/deps/rocksdb/rocksdb/util/slice_transform_test.cc +5 -7
  339. package/deps/rocksdb/rocksdb/util/status.cc +3 -1
  340. package/deps/rocksdb/rocksdb/util/stop_watch.h +2 -0
  341. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +4 -1
  342. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_test.cc +123 -78
  343. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.cc +12 -93
  344. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.h +1 -4
  345. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.cc +0 -21
  346. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.h +6 -48
  347. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.cc +94 -307
  348. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.h +12 -58
  349. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl_filesnapshot.cc +2 -8
  350. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_listener.h +2 -3
  351. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_test.cc +205 -811
  352. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_dump_tool.cc +18 -9
  353. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.cc +2 -7
  354. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.h +1 -9
  355. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_functional_test.cc +17 -11
  356. package/deps/rocksdb/rocksdb/utilities/cassandra/test_utils.cc +1 -1
  357. package/deps/rocksdb/rocksdb/utilities/cassandra/test_utils.h +1 -1
  358. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.cc +1 -1
  359. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +68 -61
  360. package/deps/rocksdb/rocksdb/utilities/debug.cc +2 -1
  361. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.cc +105 -59
  362. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.h +274 -7
  363. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs_test.cc +94 -0
  364. package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +13 -17
  365. package/deps/rocksdb/rocksdb/utilities/memory/memory_util.cc +16 -3
  366. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend_test.cc +25 -25
  367. package/deps/rocksdb/rocksdb/utilities/object_registry.cc +40 -40
  368. package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration.cc +2 -5
  369. package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +17 -19
  370. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.cc +2 -2
  371. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.h +2 -2
  372. package/deps/rocksdb/rocksdb/utilities/persistent_cache/volatile_tier_impl.cc +1 -1
  373. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_db_impl.cc +2 -2
  374. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_db_impl.h +4 -13
  375. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +3 -3
  376. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.h +6 -0
  377. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_seqno_test.cc +431 -0
  378. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +1 -2
  379. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.h +91 -0
  380. package/deps/rocksdb/rocksdb/utilities/trie_index/bitvector.cc +562 -0
  381. package/deps/rocksdb/rocksdb/utilities/trie_index/bitvector.h +615 -0
  382. package/deps/rocksdb/rocksdb/utilities/trie_index/louds_trie.cc +2575 -0
  383. package/deps/rocksdb/rocksdb/utilities/trie_index/louds_trie.h +685 -0
  384. package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_db_test.cc +2843 -0
  385. package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_factory.cc +567 -0
  386. package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_factory.h +275 -0
  387. package/deps/rocksdb/rocksdb/utilities/trie_index/trie_index_test.cc +5183 -0
  388. package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.cc +4 -3
  389. package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.h +1 -1
  390. package/deps/rocksdb/rocksdb/utilities/ttl/ttl_test.cc +2 -2
  391. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +3 -3
  392. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +93 -88
  393. package/deps/rocksdb/rocksdb.gyp +7 -0
  394. package/index.js +70 -10
  395. package/iterator.js +25 -3
  396. package/max_rev_operator.h +9 -5
  397. package/package.json +1 -1
  398. package/prebuilds/darwin-arm64/@nxtedition+rocksdb.node +0 -0
  399. package/prebuilds/linux-x64/@nxtedition+rocksdb.node +0 -0
  400. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/lua/rocks_lua_custom_library.h +0 -43
  401. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/lua/rocks_lua_util.h +0 -55
@@ -38,13 +38,11 @@ namespace ROCKSDB_NAMESPACE {
38
38
  namespace clock_cache {
39
39
 
40
40
  namespace {
41
- inline uint64_t GetRefcount(uint64_t meta) {
42
- return ((meta >> ClockHandle::kAcquireCounterShift) -
43
- (meta >> ClockHandle::kReleaseCounterShift)) &
44
- ClockHandle::kCounterMask;
45
- }
41
+ using SlotMeta = ClockHandle::SlotMeta;
42
+ using AcquireCounter = SlotMeta::AcquireCounter;
43
+ using ReleaseCounter = SlotMeta::ReleaseCounter;
46
44
 
47
- inline uint64_t GetInitialCountdown(Cache::Priority priority) {
45
+ inline uint32_t GetInitialCountdown(Cache::Priority priority) {
48
46
  // Set initial clock data from priority
49
47
  // TODO: configuration parameters for priority handling and clock cycle
50
48
  // count?
@@ -65,11 +63,11 @@ inline uint64_t GetInitialCountdown(Cache::Priority priority) {
65
63
  inline void MarkEmpty(ClockHandle& h) {
66
64
  #ifndef NDEBUG
67
65
  // Mark slot as empty, with assertion
68
- uint64_t meta = h.meta.Exchange(0);
69
- assert(meta >> ClockHandle::kStateShift == ClockHandle::kStateConstruction);
66
+ auto old_meta = h.meta.Exchange({});
67
+ assert(old_meta.IsUnderConstruction());
70
68
  #else
71
69
  // Mark slot as empty
72
- h.meta.Store(0);
70
+ h.meta.Store({});
73
71
  #endif
74
72
  }
75
73
 
@@ -85,18 +83,20 @@ inline void FreeDataMarkEmpty(ClockHandle& h, MemoryAllocator* allocator) {
85
83
 
86
84
  // Called to undo the effect of referencing an entry for internal purposes,
87
85
  // so it should not be marked as having been used.
88
- inline void Unref(const ClockHandle& h, uint64_t count = 1) {
86
+ inline void Unref(const ClockHandle& h, uint32_t count = 1) {
89
87
  // Pretend we never took the reference
90
88
  // WART: there's a tiny chance we release last ref to invisible
91
89
  // entry here. If that happens, we let eviction take care of it.
92
- uint64_t old_meta = h.meta.FetchSub(ClockHandle::kAcquireIncrement * count);
93
- assert(GetRefcount(old_meta) != 0);
90
+ SlotMeta old_meta;
91
+ h.meta.Apply(AcquireCounter::MinusTransformPromiseNoUnderflow(count),
92
+ &old_meta);
93
+ assert(old_meta.GetRefcount() != 0);
94
94
  (void)old_meta;
95
95
  }
96
96
 
97
97
  inline bool ClockUpdate(ClockHandle& h, BaseClockTable::EvictionData* data,
98
98
  bool* purgeable = nullptr) {
99
- uint64_t meta;
99
+ SlotMeta meta;
100
100
  if (purgeable) {
101
101
  assert(*purgeable == false);
102
102
  // In AutoHCC, our eviction process follows the chain structure, so we
@@ -110,46 +110,40 @@ inline bool ClockUpdate(ClockHandle& h, BaseClockTable::EvictionData* data,
110
110
  meta = h.meta.LoadRelaxed();
111
111
  }
112
112
 
113
- if (((meta >> ClockHandle::kStateShift) & ClockHandle::kStateShareableBit) ==
114
- 0) {
113
+ if (!meta.IsShareable()) {
115
114
  // Only clock update Shareable entries
116
115
  if (purgeable) {
117
116
  *purgeable = true;
118
117
  // AutoHCC only: make sure we only attempt to update non-empty slots
119
- assert((meta >> ClockHandle::kStateShift) &
120
- ClockHandle::kStateOccupiedBit);
118
+ assert(!meta.IsEmpty());
121
119
  }
122
120
  return false;
123
121
  }
124
- uint64_t acquire_count =
125
- (meta >> ClockHandle::kAcquireCounterShift) & ClockHandle::kCounterMask;
126
- uint64_t release_count =
127
- (meta >> ClockHandle::kReleaseCounterShift) & ClockHandle::kCounterMask;
122
+ uint32_t acquire_count = meta.GetAcquireCounter();
123
+ uint32_t release_count = meta.GetReleaseCounter();
128
124
  if (acquire_count != release_count) {
129
125
  // Only clock update entries with no outstanding refs
130
126
  data->seen_pinned_count++;
131
127
  return false;
132
128
  }
133
- if ((meta >> ClockHandle::kStateShift == ClockHandle::kStateVisible) &&
134
- acquire_count > 0) {
129
+ if (meta.IsVisible() && acquire_count > 0) {
135
130
  // Decrement clock
136
- uint64_t new_count =
137
- std::min(acquire_count - 1, uint64_t{ClockHandle::kMaxCountdown} - 1);
131
+ uint32_t new_count =
132
+ std::min(acquire_count - 1, uint32_t{ClockHandle::kMaxCountdown} - 1);
138
133
  // Compare-exchange in the decremented clock info, but
139
134
  // not aggressively
140
- uint64_t new_meta =
141
- (uint64_t{ClockHandle::kStateVisible} << ClockHandle::kStateShift) |
142
- (meta & ClockHandle::kHitBitMask) |
143
- (new_count << ClockHandle::kReleaseCounterShift) |
144
- (new_count << ClockHandle::kAcquireCounterShift);
135
+ SlotMeta new_meta = meta;
136
+ new_meta.SetReleaseCounter(new_count);
137
+ new_meta.SetAcquireCounter(new_count);
145
138
  h.meta.CasStrongRelaxed(meta, new_meta);
146
139
  return false;
147
140
  }
148
141
  // Otherwise, remove entry (either unreferenced invisible or
149
142
  // unreferenced and expired visible).
150
- if (h.meta.CasStrong(meta, (uint64_t{ClockHandle::kStateConstruction}
151
- << ClockHandle::kStateShift) |
152
- (meta & ClockHandle::kHitBitMask))) {
143
+ SlotMeta construction_meta;
144
+ construction_meta.SetUnderConstruction();
145
+ construction_meta.SetHit(meta.GetHit());
146
+ if (h.meta.CasStrong(meta, construction_meta)) {
153
147
  // Took ownership.
154
148
  data->freed_charge += h.GetTotalCharge();
155
149
  data->freed_count += 1;
@@ -215,39 +209,39 @@ inline bool ClockUpdate(ClockHandle& h, BaseClockTable::EvictionData* data,
215
209
  // counter to reach "high" state again and bumped back to "medium." (This
216
210
  // motivates only checking for release counter in high state, not both in high
217
211
  // state.)
218
- inline void CorrectNearOverflow(uint64_t old_meta,
219
- AcqRelAtomic<uint64_t>& meta) {
212
+ inline void CorrectNearOverflow(SlotMeta old_meta,
213
+ BitFieldsAtomic<SlotMeta>& meta) {
220
214
  // We clear both top-most counter bits at the same time.
221
- constexpr uint64_t kCounterTopBit = uint64_t{1}
222
- << (ClockHandle::kCounterNumBits - 1);
223
- constexpr uint64_t kClearBits =
224
- (kCounterTopBit << ClockHandle::kAcquireCounterShift) |
225
- (kCounterTopBit << ClockHandle::kReleaseCounterShift);
226
- // A simple check that allows us to initiate clearing the top bits for
227
- // a large portion of the "high" state space on release counter.
228
- constexpr uint64_t kCheckBits =
229
- (kCounterTopBit | (ClockHandle::kMaxCountdown + 1))
230
- << ClockHandle::kReleaseCounterShift;
215
+ constexpr uint32_t kCounterTopBit = uint32_t{1}
216
+ << (SlotMeta::kCounterNumBits - 1);
217
+ // The threshold for correcting "near overflow" is to ensure
218
+ // (a) the value has a top bit set that can be cleared
219
+ // (b) when we clear the top bit, the eviction state will be preserved
220
+ // (everything >= kMaxCountdown is treated equivalently)
221
+ // As mentioned above, we only check the release count.
222
+ constexpr uint32_t kThreshold = kCounterTopBit + ClockHandle::kMaxCountdown;
231
223
 
232
- if (UNLIKELY(old_meta & kCheckBits)) {
233
- meta.FetchAndRelaxed(~kClearBits);
224
+ if (UNLIKELY(old_meta.GetReleaseCounter() > kThreshold)) {
225
+ auto clear_transform = AcquireCounter::AndTransform(kCounterTopBit - 1) +
226
+ ReleaseCounter::AndTransform(kCounterTopBit - 1);
227
+ meta.ApplyRelaxed(clear_transform);
234
228
  }
235
229
  }
236
230
 
237
231
  inline bool BeginSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
238
- uint64_t initial_countdown, bool* already_matches) {
232
+ uint32_t initial_countdown, bool* already_matches) {
239
233
  assert(*already_matches == false);
240
234
  // Optimistically transition the slot from "empty" to
241
235
  // "under construction" (no effect on other states)
242
- uint64_t old_meta = h.meta.FetchOr(uint64_t{ClockHandle::kStateOccupiedBit}
243
- << ClockHandle::kStateShift);
244
- uint64_t old_state = old_meta >> ClockHandle::kStateShift;
236
+ auto set_occupied = SlotMeta::OccupiedFlag::SetTransform();
237
+ SlotMeta old_meta;
238
+ h.meta.Apply(set_occupied, &old_meta);
245
239
 
246
- if (old_state == ClockHandle::kStateEmpty) {
240
+ if (old_meta.IsEmpty()) {
247
241
  // We've started inserting into an available slot, and taken
248
242
  // ownership.
249
243
  return true;
250
- } else if (old_state != ClockHandle::kStateVisible) {
244
+ } else if (!old_meta.IsVisible()) {
251
245
  // Slot not usable / touchable now
252
246
  return false;
253
247
  }
@@ -255,15 +249,17 @@ inline bool BeginSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
255
249
  // But first, we need to acquire a ref to read it. In fact, number of
256
250
  // refs for initial countdown, so that we boost the clock state if
257
251
  // this is a match.
258
- old_meta =
259
- h.meta.FetchAdd(ClockHandle::kAcquireIncrement * initial_countdown);
252
+ auto add_acquire =
253
+ AcquireCounter::PlusTransformPromiseNoOverflow(initial_countdown);
254
+ h.meta.Apply(add_acquire, &old_meta);
260
255
  // Like Lookup
261
- if ((old_meta >> ClockHandle::kStateShift) == ClockHandle::kStateVisible) {
256
+ if (old_meta.IsVisible()) {
262
257
  // Acquired a read reference
263
258
  if (h.hashed_key == proto.hashed_key) {
264
259
  // Match. Release in a way that boosts the clock state
265
- old_meta =
266
- h.meta.FetchAdd(ClockHandle::kReleaseIncrement * initial_countdown);
260
+ auto add_release =
261
+ ReleaseCounter::PlusTransformPromiseNoOverflow(initial_countdown);
262
+ h.meta.Apply(add_release, &old_meta);
267
263
  // Correct for possible (but rare) overflow
268
264
  CorrectNearOverflow(old_meta, h.meta);
269
265
  // Insert detached instead (only if return handle needed)
@@ -273,8 +269,7 @@ inline bool BeginSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
273
269
  // Mismatch.
274
270
  Unref(h, initial_countdown);
275
271
  }
276
- } else if (UNLIKELY((old_meta >> ClockHandle::kStateShift) ==
277
- ClockHandle::kStateInvisible)) {
272
+ } else if (UNLIKELY(old_meta.IsInvisible())) {
278
273
  // Pretend we never took the reference
279
274
  Unref(h, initial_countdown);
280
275
  } else {
@@ -286,25 +281,23 @@ inline bool BeginSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
286
281
  }
287
282
 
288
283
  inline void FinishSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
289
- uint64_t initial_countdown, bool keep_ref) {
284
+ uint32_t initial_countdown, bool keep_ref) {
290
285
  // Save data fields
291
286
  ClockHandleBasicData* h_alias = &h;
292
287
  *h_alias = proto;
293
288
 
294
289
  // Transition from "under construction" state to "visible" state
295
- uint64_t new_meta = uint64_t{ClockHandle::kStateVisible}
296
- << ClockHandle::kStateShift;
290
+ SlotMeta new_meta;
291
+ new_meta.SetVisible();
297
292
 
298
293
  // Maybe with an outstanding reference
299
- new_meta |= initial_countdown << ClockHandle::kAcquireCounterShift;
300
- new_meta |= (initial_countdown - keep_ref)
301
- << ClockHandle::kReleaseCounterShift;
294
+ new_meta.SetAcquireCounter(initial_countdown);
295
+ new_meta.SetReleaseCounter(initial_countdown - (keep_ref ? 1 : 0));
302
296
 
303
297
  #ifndef NDEBUG
304
298
  // Save the state transition, with assertion
305
- uint64_t old_meta = h.meta.Exchange(new_meta);
306
- assert(old_meta >> ClockHandle::kStateShift ==
307
- ClockHandle::kStateConstruction);
299
+ auto old_meta = h.meta.Exchange(new_meta);
300
+ assert(old_meta.IsUnderConstruction());
308
301
  #else
309
302
  // Save the state transition
310
303
  h.meta.Store(new_meta);
@@ -312,7 +305,7 @@ inline void FinishSlotInsert(const ClockHandleBasicData& proto, ClockHandle& h,
312
305
  }
313
306
 
314
307
  bool TryInsert(const ClockHandleBasicData& proto, ClockHandle& h,
315
- uint64_t initial_countdown, bool keep_ref,
308
+ uint32_t initial_countdown, bool keep_ref,
316
309
  bool* already_matches) {
317
310
  bool b = BeginSlotInsert(proto, h, initial_countdown, already_matches);
318
311
  if (b) {
@@ -326,35 +319,32 @@ template <class HandleImpl, class Func>
326
319
  void ConstApplyToEntriesRange(const Func& func, const HandleImpl* begin,
327
320
  const HandleImpl* end,
328
321
  bool apply_if_will_be_deleted) {
329
- uint64_t check_state_mask = ClockHandle::kStateShareableBit;
330
- if (!apply_if_will_be_deleted) {
331
- check_state_mask |= ClockHandle::kStateVisibleBit;
332
- }
333
-
334
322
  for (const HandleImpl* h = begin; h < end; ++h) {
335
323
  // Note: to avoid using compare_exchange, we have to be extra careful.
336
- uint64_t old_meta = h->meta.LoadRelaxed();
324
+ SlotMeta old_meta = h->meta.LoadRelaxed();
337
325
  // Check if it's an entry visible to lookups
338
- if ((old_meta >> ClockHandle::kStateShift) & check_state_mask) {
339
- // Increment acquire counter. Note: it's possible that the entry has
340
- // completely changed since we loaded old_meta, but incrementing acquire
341
- // count is always safe. (Similar to optimistic Lookup here.)
342
- old_meta = h->meta.FetchAdd(ClockHandle::kAcquireIncrement);
343
- // Check whether we actually acquired a reference.
344
- if ((old_meta >> ClockHandle::kStateShift) &
345
- ClockHandle::kStateShareableBit) {
346
- // Apply func if appropriate
347
- if ((old_meta >> ClockHandle::kStateShift) & check_state_mask) {
348
- func(*h);
326
+ if (apply_if_will_be_deleted || old_meta.IsVisible()) {
327
+ if (old_meta.IsShareable()) {
328
+ // Increment acquire counter. Note: it's possible that the entry has
329
+ // completely changed since we loaded old_meta, but incrementing acquire
330
+ // count is always safe. (Similar to optimistic Lookup here.)
331
+ auto add_acquire = AcquireCounter::PlusTransformPromiseNoOverflow(1);
332
+ h->meta.Apply(add_acquire, &old_meta);
333
+ // Check whether we actually acquired a reference.
334
+ if (old_meta.IsShareable()) {
335
+ // Apply func if appropriate
336
+ if (apply_if_will_be_deleted || old_meta.IsVisible()) {
337
+ func(*h);
338
+ }
339
+ // Pretend we never took the reference
340
+ Unref(*h);
341
+ // No net change, so don't need to check for overflow
342
+ } else {
343
+ // For other states, incrementing the acquire counter has no effect
344
+ // so we don't need to undo it. Furthermore, we cannot safely undo
345
+ // it because we did not acquire a read reference to lock the
346
+ // entry in a Shareable state.
349
347
  }
350
- // Pretend we never took the reference
351
- Unref(*h);
352
- // No net change, so don't need to check for overflow
353
- } else {
354
- // For other states, incrementing the acquire counter has no effect
355
- // so we don't need to undo it. Furthermore, we cannot safely undo
356
- // it because we did not acquire a read reference to lock the
357
- // entry in a Shareable state.
358
348
  }
359
349
  }
360
350
  }
@@ -399,9 +389,9 @@ HandleImpl* BaseClockTable::StandaloneInsert(
399
389
  h->SetStandalone();
400
390
  // Single reference (standalone entries only created if returning a refed
401
391
  // Handle back to user)
402
- uint64_t meta = uint64_t{ClockHandle::kStateInvisible}
403
- << ClockHandle::kStateShift;
404
- meta |= uint64_t{1} << ClockHandle::kAcquireCounterShift;
392
+ SlotMeta meta;
393
+ meta.SetInvisible();
394
+ meta.SetAcquireCounter(1);
405
395
  h->meta.Store(meta);
406
396
  // Keep track of how much of usage is standalone
407
397
  standalone_usage_.FetchAddRelaxed(proto.GetTotalCharge());
@@ -564,11 +554,10 @@ void BaseClockTable::TrackAndReleaseEvictedEntry(ClockHandle* h) {
564
554
  if (eviction_callback_) {
565
555
  // For key reconstructed from hash
566
556
  UniqueId64x2 unhashed;
567
- took_value_ownership =
568
- eviction_callback_(ClockCacheShard<FixedHyperClockTable>::ReverseHash(
569
- h->GetHash(), &unhashed, hash_seed_),
570
- static_cast<Cache::Handle*>(h),
571
- h->meta.LoadRelaxed() & ClockHandle::kHitBitMask);
557
+ took_value_ownership = eviction_callback_(
558
+ ClockCacheShard<FixedHyperClockTable>::ReverseHash(
559
+ h->GetHash(), &unhashed, hash_seed_),
560
+ static_cast<Cache::Handle*>(h), h->meta.LoadRelaxed().GetHit());
572
561
  }
573
562
  if (!took_value_ownership) {
574
563
  h->FreeData(allocator_);
@@ -648,7 +637,7 @@ Status BaseClockTable::Insert(const ClockHandleBasicData& proto,
648
637
  // * Have to insert into a suboptimal location (more probes) so that the
649
638
  // old entry can be kept around as well.
650
639
 
651
- uint64_t initial_countdown = GetInitialCountdown(priority);
640
+ uint32_t initial_countdown = GetInitialCountdown(priority);
652
641
  assert(initial_countdown > 0);
653
642
 
654
643
  HandleImpl* e =
@@ -693,34 +682,34 @@ Status BaseClockTable::Insert(const ClockHandleBasicData& proto,
693
682
 
694
683
  void BaseClockTable::Ref(ClockHandle& h) {
695
684
  // Increment acquire counter
696
- uint64_t old_meta = h.meta.FetchAdd(ClockHandle::kAcquireIncrement);
685
+ SlotMeta old_meta;
686
+ h.meta.Apply(AcquireCounter::PlusTransformPromiseNoOverflow(1), &old_meta);
697
687
 
698
- assert((old_meta >> ClockHandle::kStateShift) &
699
- ClockHandle::kStateShareableBit);
688
+ assert(old_meta.IsShareable());
700
689
  // Must have already had a reference
701
- assert(GetRefcount(old_meta) > 0);
690
+ assert(old_meta.GetRefcount() > 0);
702
691
  (void)old_meta;
703
692
  }
704
693
 
705
694
  #ifndef NDEBUG
706
- void BaseClockTable::TEST_RefN(ClockHandle& h, size_t n) {
695
+ void BaseClockTable::TEST_RefN(ClockHandle& h, uint32_t n) {
707
696
  // Increment acquire counter
708
- uint64_t old_meta = h.meta.FetchAdd(n * ClockHandle::kAcquireIncrement);
697
+ SlotMeta old_meta;
698
+ h.meta.Apply(AcquireCounter::PlusTransformPromiseNoOverflow(n), &old_meta);
709
699
 
710
- assert((old_meta >> ClockHandle::kStateShift) &
711
- ClockHandle::kStateShareableBit);
700
+ assert(old_meta.IsShareable());
712
701
  (void)old_meta;
713
702
  }
714
703
 
715
- void BaseClockTable::TEST_ReleaseNMinus1(ClockHandle* h, size_t n) {
704
+ void BaseClockTable::TEST_ReleaseNMinus1(ClockHandle* h, uint32_t n) {
716
705
  assert(n > 0);
717
706
 
718
707
  // Like n-1 Releases, but assumes one more will happen in the caller to take
719
708
  // care of anything like erasing an unreferenced, invisible entry.
720
- uint64_t old_meta =
721
- h->meta.FetchAdd((n - 1) * ClockHandle::kReleaseIncrement);
722
- assert((old_meta >> ClockHandle::kStateShift) &
723
- ClockHandle::kStateShareableBit);
709
+ SlotMeta old_meta;
710
+ h->meta.Apply(ReleaseCounter::PlusTransformPromiseNoOverflow(n - 1),
711
+ &old_meta);
712
+ assert(old_meta.IsShareable());
724
713
  (void)old_meta;
725
714
  }
726
715
  #endif
@@ -754,23 +743,20 @@ FixedHyperClockTable::~FixedHyperClockTable() {
754
743
  // in the table.
755
744
  for (size_t i = 0; i < GetTableSize(); i++) {
756
745
  HandleImpl& h = array_[i];
757
- switch (h.meta.LoadRelaxed() >> ClockHandle::kStateShift) {
758
- case ClockHandle::kStateEmpty:
759
- // noop
760
- break;
761
- case ClockHandle::kStateInvisible: // rare but possible
762
- case ClockHandle::kStateVisible:
763
- assert(GetRefcount(h.meta.LoadRelaxed()) == 0);
764
- h.FreeData(allocator_);
746
+ SlotMeta meta = h.meta.LoadRelaxed();
747
+ if (meta.IsShareable()) {
748
+ // NOTE: Reaching here invisible is rare but possible
749
+ assert(meta.GetRefcount() == 0);
750
+ h.FreeData(allocator_);
765
751
  #ifndef NDEBUG
766
- Rollback(h.hashed_key, &h);
767
- ReclaimEntryUsage(h.GetTotalCharge());
752
+ Rollback(h.hashed_key, &h);
753
+ ReclaimEntryUsage(h.GetTotalCharge());
768
754
  #endif
769
- break;
770
- // otherwise
771
- default:
772
- assert(false);
773
- break;
755
+ } else {
756
+ // Should be no transient "under construction" states unless a thread
757
+ // was killed or we are being destructed while another thread is still
758
+ // operating on the structure
759
+ assert(meta.IsEmpty());
774
760
  }
775
761
  }
776
762
 
@@ -792,7 +778,7 @@ bool FixedHyperClockTable::GrowIfNeeded(size_t new_occupancy, InsertState&) {
792
778
  }
793
779
 
794
780
  FixedHyperClockTable::HandleImpl* FixedHyperClockTable::DoInsert(
795
- const ClockHandleBasicData& proto, uint64_t initial_countdown,
781
+ const ClockHandleBasicData& proto, uint32_t initial_countdown,
796
782
  bool keep_ref, InsertState&) {
797
783
  bool already_matches = false;
798
784
  HandleImpl* e = FindSlot(
@@ -843,47 +829,46 @@ FixedHyperClockTable::HandleImpl* FixedHyperClockTable::Lookup(
843
829
  HandleImpl* e = FindSlot(
844
830
  hashed_key,
845
831
  [&](HandleImpl* h) {
832
+ SlotMeta old_meta;
846
833
  // Mostly branch-free version (similar performance)
847
834
  /*
848
- uint64_t old_meta = h->meta.FetchAdd(ClockHandle::kAcquireIncrement,
849
- std::memory_order_acquire);
850
- bool Shareable = (old_meta >> (ClockHandle::kStateShift + 1)) & 1U;
851
- bool visible = (old_meta >> ClockHandle::kStateShift) & 1U;
852
- bool match = (h->key == key) & visible;
853
- h->meta.FetchSub(static_cast<uint64_t>(Shareable & !match) <<
854
- ClockHandle::kAcquireCounterShift); return
855
- match;
835
+ h->meta.Apply(AcquireCounter::PlusTransformPromiseNoOverflow(1),
836
+ &old_meta);
837
+ bool shareable = old_meta.IsShareable();
838
+ bool visible = old_meta.IsVisible();
839
+ bool match = (h->hashed_key == hashed_key) & visible;
840
+ h->meta.Apply(AcquireCounter::MinusTransformPromiseNoUnderflow(
841
+ uint32_t{shareable} & uint32_t{!match}));
842
+ h->meta.Apply(SlotMeta::HitFlag::Or(match));
843
+ return match;
856
844
  */
857
845
  // Optimistic lookup should pay off when the table is relatively
858
846
  // sparse.
859
847
  constexpr bool kOptimisticLookup = true;
860
- uint64_t old_meta;
861
848
  if (!kOptimisticLookup) {
862
849
  old_meta = h->meta.Load();
863
- if ((old_meta >> ClockHandle::kStateShift) !=
864
- ClockHandle::kStateVisible) {
850
+ if (!old_meta.IsVisible()) {
865
851
  return false;
866
852
  }
867
853
  }
868
854
  // (Optimistically) increment acquire counter
869
- old_meta = h->meta.FetchAdd(ClockHandle::kAcquireIncrement);
855
+ h->meta.Apply(AcquireCounter::PlusTransformPromiseNoOverflow(1),
856
+ &old_meta);
870
857
  // Check if it's an entry visible to lookups
871
- if ((old_meta >> ClockHandle::kStateShift) ==
872
- ClockHandle::kStateVisible) {
858
+ if (old_meta.IsVisible()) {
873
859
  // Acquired a read reference
874
860
  if (h->hashed_key == hashed_key) {
875
861
  // Match
876
862
  // Update the hit bit
877
863
  if (eviction_callback_) {
878
- h->meta.FetchOrRelaxed(uint64_t{1} << ClockHandle::kHitBitShift);
864
+ h->meta.ApplyRelaxed(SlotMeta::HitFlag::SetTransform());
879
865
  }
880
866
  return true;
881
867
  } else {
882
868
  // Mismatch. Pretend we never took the reference
883
869
  Unref(*h);
884
870
  }
885
- } else if (UNLIKELY((old_meta >> ClockHandle::kStateShift) ==
886
- ClockHandle::kStateInvisible)) {
871
+ } else if (UNLIKELY(old_meta.IsInvisible())) {
887
872
  // Pretend we never took the reference
888
873
  Unref(*h);
889
874
  } else {
@@ -907,53 +892,49 @@ bool FixedHyperClockTable::Release(HandleImpl* h, bool useful,
907
892
  // is only freed up by EvictFromClock (called by Insert when space is needed)
908
893
  // and Erase. We do this to avoid an extra atomic read of the variable usage_.
909
894
 
910
- uint64_t old_meta;
895
+ SlotMeta old_meta;
911
896
  if (useful) {
912
897
  // Increment release counter to indicate was used
913
- old_meta = h->meta.FetchAdd(ClockHandle::kReleaseIncrement);
898
+ auto add_release = ReleaseCounter::PlusTransformPromiseNoOverflow(1);
899
+ h->meta.Apply(add_release, &old_meta);
914
900
  } else {
915
901
  // Decrement acquire counter to pretend it never happened
916
- old_meta = h->meta.FetchSub(ClockHandle::kAcquireIncrement);
902
+ auto sub_acquire = AcquireCounter::MinusTransformPromiseNoUnderflow(1);
903
+ h->meta.Apply(sub_acquire, &old_meta);
917
904
  }
918
905
 
919
- assert((old_meta >> ClockHandle::kStateShift) &
920
- ClockHandle::kStateShareableBit);
906
+ assert(old_meta.IsShareable());
921
907
  // No underflow
922
- assert(((old_meta >> ClockHandle::kAcquireCounterShift) &
923
- ClockHandle::kCounterMask) !=
924
- ((old_meta >> ClockHandle::kReleaseCounterShift) &
925
- ClockHandle::kCounterMask));
908
+ assert(old_meta.GetAcquireCounter() != old_meta.GetReleaseCounter());
926
909
 
927
- if (erase_if_last_ref || UNLIKELY(old_meta >> ClockHandle::kStateShift ==
928
- ClockHandle::kStateInvisible)) {
910
+ if (erase_if_last_ref || UNLIKELY(old_meta.IsInvisible())) {
929
911
  // FIXME: There's a chance here that another thread could replace this
930
912
  // entry and we end up erasing the wrong one.
931
913
 
932
- // Update for last FetchAdd op
914
+ // Update for last Apply op
933
915
  if (useful) {
934
- old_meta += ClockHandle::kReleaseIncrement;
916
+ old_meta.SetReleaseCounter(old_meta.GetReleaseCounter() + 1);
935
917
  } else {
936
- old_meta -= ClockHandle::kAcquireIncrement;
918
+ old_meta.SetAcquireCounter(old_meta.GetAcquireCounter() - 1);
937
919
  }
938
920
  // Take ownership if no refs
921
+ SlotMeta construction_meta;
922
+ construction_meta.SetUnderConstruction();
939
923
  do {
940
- if (GetRefcount(old_meta) != 0) {
924
+ if (old_meta.GetRefcount() != 0) {
941
925
  // Not last ref at some point in time during this Release call
942
926
  // Correct for possible (but rare) overflow
943
927
  CorrectNearOverflow(old_meta, h->meta);
944
928
  return false;
945
929
  }
946
- if ((old_meta & (uint64_t{ClockHandle::kStateShareableBit}
947
- << ClockHandle::kStateShift)) == 0) {
930
+ if (!old_meta.IsShareable()) {
948
931
  // Someone else took ownership
949
932
  return false;
950
933
  }
951
934
  // Note that there's a small chance that we release, another thread
952
935
  // replaces this entry with another, reaches zero refs, and then we end
953
936
  // up erasing that other entry. That's an acceptable risk / imprecision.
954
- } while (
955
- !h->meta.CasWeak(old_meta, uint64_t{ClockHandle::kStateConstruction}
956
- << ClockHandle::kStateShift));
937
+ } while (!h->meta.CasWeak(old_meta, construction_meta));
957
938
  // Took ownership
958
939
  size_t total_charge = h->GetTotalCharge();
959
940
  if (UNLIKELY(h->IsStandalone())) {
@@ -976,7 +957,7 @@ bool FixedHyperClockTable::Release(HandleImpl* h, bool useful,
976
957
  }
977
958
 
978
959
  #ifndef NDEBUG
979
- void FixedHyperClockTable::TEST_ReleaseN(HandleImpl* h, size_t n) {
960
+ void FixedHyperClockTable::TEST_ReleaseN(HandleImpl* h, uint32_t n) {
980
961
  if (n > 0) {
981
962
  // Do n-1 simple releases first
982
963
  TEST_ReleaseNMinus1(h, n);
@@ -993,30 +974,29 @@ void FixedHyperClockTable::Erase(const UniqueId64x2& hashed_key) {
993
974
  [&](HandleImpl* h) {
994
975
  // Could be multiple entries in rare cases. Erase them all.
995
976
  // Optimistically increment acquire counter
996
- uint64_t old_meta = h->meta.FetchAdd(ClockHandle::kAcquireIncrement);
977
+ auto add_acquire = AcquireCounter::PlusTransformPromiseNoOverflow(1);
978
+ SlotMeta old_meta, meta;
979
+ h->meta.Apply(add_acquire, &old_meta, &meta);
997
980
  // Check if it's an entry visible to lookups
998
- if ((old_meta >> ClockHandle::kStateShift) ==
999
- ClockHandle::kStateVisible) {
981
+ if (meta.IsVisible()) {
1000
982
  // Acquired a read reference
1001
983
  if (h->hashed_key == hashed_key) {
1002
- // Match. Set invisible.
1003
- old_meta =
1004
- h->meta.FetchAnd(~(uint64_t{ClockHandle::kStateVisibleBit}
1005
- << ClockHandle::kStateShift));
1006
- // Apply update to local copy
1007
- old_meta &= ~(uint64_t{ClockHandle::kStateVisibleBit}
1008
- << ClockHandle::kStateShift);
984
+ // Match. Take ownership if no other refs, or set invisible other
985
+ // refs exist.
1009
986
  for (;;) {
1010
- uint64_t refcount = GetRefcount(old_meta);
987
+ uint32_t refcount = meta.GetRefcount();
1011
988
  assert(refcount > 0);
1012
989
  if (refcount > 1) {
1013
990
  // Not last ref at some point in time during this Erase call
1014
- // Pretend we never took the reference
991
+ // Set invisible
992
+ h->meta.Apply(SlotMeta::VisibleFlag::ClearTransform());
993
+ // And pretend we never took the reference
1015
994
  Unref(*h);
1016
995
  break;
1017
- } else if (h->meta.CasWeak(
1018
- old_meta, uint64_t{ClockHandle::kStateConstruction}
1019
- << ClockHandle::kStateShift)) {
996
+ }
997
+ SlotMeta construction_meta;
998
+ construction_meta.SetUnderConstruction();
999
+ if (h->meta.CasWeak(meta, construction_meta)) {
1020
1000
  // Took ownership
1021
1001
  assert(hashed_key == h->hashed_key);
1022
1002
  size_t total_charge = h->GetTotalCharge();
@@ -1032,8 +1012,7 @@ void FixedHyperClockTable::Erase(const UniqueId64x2& hashed_key) {
1032
1012
  // Mismatch. Pretend we never took the reference
1033
1013
  Unref(*h);
1034
1014
  }
1035
- } else if (UNLIKELY((old_meta >> ClockHandle::kStateShift) ==
1036
- ClockHandle::kStateInvisible)) {
1015
+ } else if (UNLIKELY(old_meta.IsInvisible())) {
1037
1016
  // Pretend we never took the reference
1038
1017
  Unref(*h);
1039
1018
  } else {
@@ -1050,17 +1029,17 @@ void FixedHyperClockTable::EraseUnRefEntries() {
1050
1029
  for (size_t i = 0; i <= this->length_bits_mask_; i++) {
1051
1030
  HandleImpl& h = array_[i];
1052
1031
 
1053
- uint64_t old_meta = h.meta.LoadRelaxed();
1054
- if (old_meta & (uint64_t{ClockHandle::kStateShareableBit}
1055
- << ClockHandle::kStateShift) &&
1056
- GetRefcount(old_meta) == 0 &&
1057
- h.meta.CasStrong(old_meta, uint64_t{ClockHandle::kStateConstruction}
1058
- << ClockHandle::kStateShift)) {
1059
- // Took ownership
1060
- size_t total_charge = h.GetTotalCharge();
1061
- Rollback(h.hashed_key, &h);
1062
- FreeDataMarkEmpty(h, allocator_);
1063
- ReclaimEntryUsage(total_charge);
1032
+ SlotMeta old_meta = h.meta.LoadRelaxed();
1033
+ if (old_meta.IsShareable() && old_meta.GetRefcount() == 0) {
1034
+ SlotMeta construction_meta;
1035
+ construction_meta.SetUnderConstruction();
1036
+ if (h.meta.CasStrong(old_meta, construction_meta)) {
1037
+ // Took ownership
1038
+ size_t total_charge = h.GetTotalCharge();
1039
+ Rollback(h.hashed_key, &h);
1040
+ FreeDataMarkEmpty(h, allocator_);
1041
+ ReclaimEntryUsage(total_charge);
1042
+ }
1064
1043
  }
1065
1044
  }
1066
1045
  }
@@ -1320,12 +1299,12 @@ bool ClockCacheShard<Table>::Release(HandleImpl* handle, bool useful,
1320
1299
 
1321
1300
  #ifndef NDEBUG
1322
1301
  template <class Table>
1323
- void ClockCacheShard<Table>::TEST_RefN(HandleImpl* h, size_t n) {
1302
+ void ClockCacheShard<Table>::TEST_RefN(HandleImpl* h, uint32_t n) {
1324
1303
  table_.TEST_RefN(*h, n);
1325
1304
  }
1326
1305
 
1327
1306
  template <class Table>
1328
- void ClockCacheShard<Table>::TEST_ReleaseN(HandleImpl* h, size_t n) {
1307
+ void ClockCacheShard<Table>::TEST_ReleaseN(HandleImpl* h, uint32_t n) {
1329
1308
  table_.TEST_ReleaseN(h, n);
1330
1309
  }
1331
1310
  #endif
@@ -1373,8 +1352,8 @@ size_t ClockCacheShard<Table>::GetPinnedUsage() const {
1373
1352
  metadata_charge_policy_ == kFullChargeCacheMetadata;
1374
1353
  ConstApplyToEntriesRange(
1375
1354
  [&table_pinned_usage, charge_metadata](const HandleImpl& h) {
1376
- uint64_t meta = h.meta.LoadRelaxed();
1377
- uint64_t refcount = GetRefcount(meta);
1355
+ SlotMeta meta = h.meta.LoadRelaxed();
1356
+ uint32_t refcount = meta.GetRefcount();
1378
1357
  // Holding one ref for ConstApplyToEntriesRange
1379
1358
  assert(refcount > 0);
1380
1359
  if (refcount > 1) {
@@ -1494,7 +1473,7 @@ void AddShardEvaluation(const FixedHyperClockCache::Shard& shard,
1494
1473
  }
1495
1474
 
1496
1475
  bool IsSlotOccupied(const ClockHandle& h) {
1497
- return (h.meta.LoadRelaxed() >> ClockHandle::kStateShift) != 0;
1476
+ return !h.meta.LoadRelaxed().IsEmpty();
1498
1477
  }
1499
1478
  } // namespace
1500
1479
 
@@ -1759,12 +1738,12 @@ inline bool MatchAndRef(const UniqueId64x2* hashed_key, const ClockHandle& h,
1759
1738
  // Must be at least something to match
1760
1739
  assert(hashed_key || shift > 0);
1761
1740
 
1762
- uint64_t old_meta;
1741
+ SlotMeta old_meta, new_meta;
1763
1742
  // (Optimistically) increment acquire counter.
1764
- old_meta = h.meta.FetchAdd(ClockHandle::kAcquireIncrement);
1743
+ auto add_acquire = AcquireCounter::PlusTransformPromiseNoOverflow(1);
1744
+ h.meta.Apply(add_acquire, &old_meta, &new_meta);
1765
1745
  // Check if it's a referencable (sharable) entry
1766
- if ((old_meta & (uint64_t{ClockHandle::kStateShareableBit}
1767
- << ClockHandle::kStateShift)) == 0) {
1746
+ if (!old_meta.IsShareable()) {
1768
1747
  // For non-sharable states, incrementing the acquire counter has no effect
1769
1748
  // so we don't need to undo it. Furthermore, we cannot safely undo
1770
1749
  // it because we did not acquire a read reference to lock the
@@ -1775,10 +1754,9 @@ inline bool MatchAndRef(const UniqueId64x2* hashed_key, const ClockHandle& h,
1775
1754
  return false;
1776
1755
  }
1777
1756
  // Else acquired a read reference
1778
- assert(GetRefcount(old_meta + ClockHandle::kAcquireIncrement) > 0);
1757
+ assert(new_meta.GetRefcount() > 0);
1779
1758
  if (hashed_key && h.hashed_key == *hashed_key &&
1780
- LIKELY(old_meta & (uint64_t{ClockHandle::kStateVisibleBit}
1781
- << ClockHandle::kStateShift))) {
1759
+ LIKELY(old_meta.IsVisible())) {
1782
1760
  // Match on full key, visible
1783
1761
  if (full_match_or_unknown) {
1784
1762
  *full_match_or_unknown = true;
@@ -1946,7 +1924,7 @@ class AutoHyperClockTable::ChainRewriteLock {
1946
1924
  }
1947
1925
  }
1948
1926
 
1949
- AcqRelBitFieldsAtomic<NextWithShift>* head_ptr_;
1927
+ BitFieldsAtomic<NextWithShift>* head_ptr_;
1950
1928
  NextWithShift saved_head_;
1951
1929
  };
1952
1930
 
@@ -2051,7 +2029,7 @@ AutoHyperClockTable::~AutoHyperClockTable() {
2051
2029
  HandleImpl::kUnusedMarker);
2052
2030
  assert(array_[i].chain_next_with_shift.LoadRelaxed() ==
2053
2031
  HandleImpl::kUnusedMarker);
2054
- assert(array_[i].meta.LoadRelaxed() == 0);
2032
+ assert(array_[i].meta.LoadRelaxed() == SlotMeta{});
2055
2033
  }
2056
2034
  #endif // MUST_FREE_HEAP_ALLOCATIONS
2057
2035
  #ifndef NDEBUG // Extra invariant checking
@@ -2060,30 +2038,27 @@ AutoHyperClockTable::~AutoHyperClockTable() {
2060
2038
  #endif // !NDEBUG
2061
2039
  for (size_t i = 0; i < used_end; i++) {
2062
2040
  HandleImpl& h = array_[i];
2063
- switch (h.meta.LoadRelaxed() >> ClockHandle::kStateShift) {
2064
- case ClockHandle::kStateEmpty:
2065
- // noop
2066
- break;
2067
- case ClockHandle::kStateInvisible: // rare but possible
2068
- case ClockHandle::kStateVisible:
2069
- assert(GetRefcount(h.meta.LoadRelaxed()) == 0);
2070
- h.FreeData(allocator_);
2041
+ SlotMeta meta = h.meta.LoadRelaxed();
2042
+ if (meta.IsShareable()) {
2043
+ // NOTE: Reaching here invisible is rare but possible
2044
+ assert(meta.GetRefcount() == 0);
2045
+ h.FreeData(allocator_);
2071
2046
  #ifndef NDEBUG // Extra invariant checking
2072
- usage_.FetchSubRelaxed(h.total_charge);
2073
- occupancy_.FetchSubRelaxed(1U);
2074
- was_populated[i] = true;
2075
- if (!h.chain_next_with_shift.LoadRelaxed().IsEnd()) {
2076
- assert(!h.chain_next_with_shift.LoadRelaxed().IsLocked());
2077
- size_t next = h.chain_next_with_shift.LoadRelaxed().GetNext();
2078
- assert(!was_pointed_to[next]);
2079
- was_pointed_to[next] = true;
2080
- }
2047
+ usage_.FetchSubRelaxed(h.total_charge);
2048
+ occupancy_.FetchSubRelaxed(1U);
2049
+ was_populated[i] = true;
2050
+ if (!h.chain_next_with_shift.LoadRelaxed().IsEnd()) {
2051
+ assert(!h.chain_next_with_shift.LoadRelaxed().IsLocked());
2052
+ size_t next = h.chain_next_with_shift.LoadRelaxed().GetNext();
2053
+ assert(!was_pointed_to[next]);
2054
+ was_pointed_to[next] = true;
2055
+ }
2081
2056
  #endif // !NDEBUG
2082
- break;
2083
- // otherwise
2084
- default:
2085
- assert(false);
2086
- break;
2057
+ } else {
2058
+ // Should be no transient "under construction" states unless a thread
2059
+ // was killed or we are being destructed while another thread is still
2060
+ // operating on the structure
2061
+ assert(meta.IsEmpty());
2087
2062
  }
2088
2063
  #ifndef NDEBUG // Extra invariant checking
2089
2064
  if (!h.head_next_with_shift.LoadRelaxed().IsEnd()) {
@@ -2691,20 +2666,17 @@ void AutoHyperClockTable::PurgeImplLocked(OpData* op_data,
2691
2666
  op_data->push_back(h);
2692
2667
  // Entries for eviction become purgeable
2693
2668
  purgeable = true;
2694
- assert((h->meta.Load() >> ClockHandle::kStateShift) ==
2695
- ClockHandle::kStateConstruction);
2669
+ assert(h->meta.Load().IsUnderConstruction());
2696
2670
  }
2697
2671
  } else {
2698
2672
  (void)op_data;
2699
2673
  (void)data;
2700
- purgeable = ((h->meta.Load() >> ClockHandle::kStateShift) &
2701
- ClockHandle::kStateShareableBit) == 0;
2674
+ purgeable = !h->meta.Load().IsShareable();
2702
2675
  }
2703
2676
  }
2704
2677
 
2705
2678
  if (purgeable) {
2706
- assert((h->meta.Load() >> ClockHandle::kStateShift) ==
2707
- ClockHandle::kStateConstruction);
2679
+ assert(h->meta.Load().IsUnderConstruction());
2708
2680
  pending_purge = true;
2709
2681
  } else if (pending_purge) {
2710
2682
  if (prev_to_keep) {
@@ -2864,7 +2836,7 @@ void AutoHyperClockTable::PurgeImpl(OpData* op_data, size_t home,
2864
2836
  }
2865
2837
 
2866
2838
  AutoHyperClockTable::HandleImpl* AutoHyperClockTable::DoInsert(
2867
- const ClockHandleBasicData& proto, uint64_t initial_countdown,
2839
+ const ClockHandleBasicData& proto, uint32_t initial_countdown,
2868
2840
  bool take_ref, InsertState& state) {
2869
2841
  size_t home;
2870
2842
  int orig_home_shift;
@@ -3149,14 +3121,14 @@ AutoHyperClockTable::HandleImpl* AutoHyperClockTable::Lookup(
3149
3121
  #endif
3150
3122
  if (probably_equal) {
3151
3123
  // Increment acquire counter for definitive check
3152
- uint64_t old_meta = h->meta.FetchAdd(ClockHandle::kAcquireIncrement);
3124
+ auto add_acquire = AcquireCounter::PlusTransformPromiseNoOverflow(1);
3125
+ SlotMeta old_meta, new_meta;
3126
+ h->meta.Apply(add_acquire, &old_meta, &new_meta);
3153
3127
  // Check if it's a referencable (sharable) entry
3154
- if (LIKELY(old_meta & (uint64_t{ClockHandle::kStateShareableBit}
3155
- << ClockHandle::kStateShift))) {
3156
- assert(GetRefcount(old_meta + ClockHandle::kAcquireIncrement) > 0);
3128
+ if (LIKELY(old_meta.IsShareable())) {
3129
+ assert(new_meta.GetRefcount() > 0);
3157
3130
  if (LIKELY(h->hashed_key == hashed_key) &&
3158
- LIKELY(old_meta & (uint64_t{ClockHandle::kStateVisibleBit}
3159
- << ClockHandle::kStateShift))) {
3131
+ LIKELY(old_meta.IsVisible())) {
3160
3132
  return h;
3161
3133
  } else {
3162
3134
  Unref(*h);
@@ -3277,7 +3249,7 @@ AutoHyperClockTable::HandleImpl* AutoHyperClockTable::Lookup(
3277
3249
  }
3278
3250
  // Update the hit bit
3279
3251
  if (eviction_callback_) {
3280
- h->meta.FetchOrRelaxed(uint64_t{1} << ClockHandle::kHitBitShift);
3252
+ h->meta.ApplyRelaxed(SlotMeta::HitFlag::SetTransform());
3281
3253
  }
3282
3254
  // All done.
3283
3255
  return h;
@@ -3317,8 +3289,7 @@ AutoHyperClockTable::HandleImpl* AutoHyperClockTable::Lookup(
3317
3289
  }
3318
3290
 
3319
3291
  void AutoHyperClockTable::Remove(HandleImpl* h) {
3320
- assert((h->meta.Load() >> ClockHandle::kStateShift) ==
3321
- ClockHandle::kStateConstruction);
3292
+ assert(h->meta.Load().IsUnderConstruction());
3322
3293
 
3323
3294
  const HandleImpl& c_h = *h;
3324
3295
  PurgeImpl(&c_h.hashed_key);
@@ -3326,26 +3297,23 @@ void AutoHyperClockTable::Remove(HandleImpl* h) {
3326
3297
 
3327
3298
  bool AutoHyperClockTable::TryEraseHandle(HandleImpl* h, bool holding_ref,
3328
3299
  bool mark_invisible) {
3329
- uint64_t meta;
3330
- if (mark_invisible) {
3331
- // Set invisible
3332
- meta = h->meta.FetchAnd(
3333
- ~(uint64_t{ClockHandle::kStateVisibleBit} << ClockHandle::kStateShift));
3334
- // To local variable also
3335
- meta &=
3336
- ~(uint64_t{ClockHandle::kStateVisibleBit} << ClockHandle::kStateShift);
3337
- } else {
3338
- meta = h->meta.Load();
3339
- }
3300
+ SlotMeta meta = h->meta.Load();
3301
+ assert(!holding_ref || meta.IsShareable());
3340
3302
 
3341
- // Take ownership if no other refs
3303
+ // Take ownership if no other refs, or set invisible if other refs exist (and
3304
+ // mark_invisible is set).
3305
+ SlotMeta construction_meta;
3306
+ construction_meta.SetUnderConstruction();
3342
3307
  do {
3343
- if (GetRefcount(meta) != uint64_t{holding_ref}) {
3308
+ if (meta.GetRefcount() != uint32_t{holding_ref}) {
3344
3309
  // Not last ref at some point in time during this call
3310
+ if (mark_invisible) {
3311
+ // Set invisible
3312
+ h->meta.Apply(SlotMeta::VisibleFlag::ClearTransform());
3313
+ }
3345
3314
  return false;
3346
3315
  }
3347
- if ((meta & (uint64_t{ClockHandle::kStateShareableBit}
3348
- << ClockHandle::kStateShift)) == 0) {
3316
+ if (!meta.IsShareable()) {
3349
3317
  // Someone else took ownership
3350
3318
  return false;
3351
3319
  }
@@ -3353,8 +3321,7 @@ bool AutoHyperClockTable::TryEraseHandle(HandleImpl* h, bool holding_ref,
3353
3321
  // another thread replaces this entry with another, reaches zero refs, and
3354
3322
  // then we end up erasing that other entry. That's an acceptable risk /
3355
3323
  // imprecision.
3356
- } while (!h->meta.CasWeak(meta, uint64_t{ClockHandle::kStateConstruction}
3357
- << ClockHandle::kStateShift));
3324
+ } while (!h->meta.CasWeak(meta, construction_meta));
3358
3325
  // Took ownership
3359
3326
  // TODO? Delay freeing?
3360
3327
  h->FreeData(allocator_);
@@ -3381,27 +3348,24 @@ bool AutoHyperClockTable::Release(HandleImpl* h, bool useful,
3381
3348
  // is needed) and Erase. We do this to avoid an extra atomic read of the
3382
3349
  // variable usage_.
3383
3350
 
3384
- uint64_t old_meta;
3351
+ SlotMeta old_meta;
3385
3352
  if (useful) {
3386
3353
  // Increment release counter to indicate was used
3387
- old_meta = h->meta.FetchAdd(ClockHandle::kReleaseIncrement);
3354
+ auto add_release = ReleaseCounter::PlusTransformPromiseNoOverflow(1);
3355
+ h->meta.Apply(add_release, &old_meta);
3388
3356
  // Correct for possible (but rare) overflow
3389
3357
  CorrectNearOverflow(old_meta, h->meta);
3390
3358
  } else {
3391
3359
  // Decrement acquire counter to pretend it never happened
3392
- old_meta = h->meta.FetchSub(ClockHandle::kAcquireIncrement);
3360
+ auto sub_acquire = AcquireCounter::MinusTransformPromiseNoUnderflow(1);
3361
+ h->meta.Apply(sub_acquire, &old_meta);
3393
3362
  }
3394
3363
 
3395
- assert((old_meta >> ClockHandle::kStateShift) &
3396
- ClockHandle::kStateShareableBit);
3364
+ assert(old_meta.IsShareable());
3397
3365
  // No underflow
3398
- assert(((old_meta >> ClockHandle::kAcquireCounterShift) &
3399
- ClockHandle::kCounterMask) !=
3400
- ((old_meta >> ClockHandle::kReleaseCounterShift) &
3401
- ClockHandle::kCounterMask));
3366
+ assert(old_meta.GetAcquireCounter() != old_meta.GetReleaseCounter());
3402
3367
 
3403
- if ((erase_if_last_ref || UNLIKELY(old_meta >> ClockHandle::kStateShift ==
3404
- ClockHandle::kStateInvisible))) {
3368
+ if ((erase_if_last_ref || UNLIKELY(old_meta.IsInvisible()))) {
3405
3369
  // FIXME: There's a chance here that another thread could replace this
3406
3370
  // entry and we end up erasing the wrong one.
3407
3371
  return TryEraseHandle(h, /*holding_ref=*/false, /*mark_invisible=*/false);
@@ -3411,7 +3375,7 @@ bool AutoHyperClockTable::Release(HandleImpl* h, bool useful,
3411
3375
  }
3412
3376
 
3413
3377
  #ifndef NDEBUG
3414
- void AutoHyperClockTable::TEST_ReleaseN(HandleImpl* h, size_t n) {
3378
+ void AutoHyperClockTable::TEST_ReleaseN(HandleImpl* h, uint32_t n) {
3415
3379
  if (n > 0) {
3416
3380
  // Do n-1 simple releases first
3417
3381
  TEST_ReleaseNMinus1(h, n);
@@ -3441,20 +3405,20 @@ void AutoHyperClockTable::EraseUnRefEntries() {
3441
3405
  for (size_t i = 0; i < usable_size; i++) {
3442
3406
  HandleImpl& h = array_[i];
3443
3407
 
3444
- uint64_t old_meta = h.meta.LoadRelaxed();
3445
- if (old_meta & (uint64_t{ClockHandle::kStateShareableBit}
3446
- << ClockHandle::kStateShift) &&
3447
- GetRefcount(old_meta) == 0 &&
3448
- h.meta.CasStrong(old_meta, uint64_t{ClockHandle::kStateConstruction}
3449
- << ClockHandle::kStateShift)) {
3450
- // Took ownership
3451
- h.FreeData(allocator_);
3452
- usage_.FetchSubRelaxed(h.total_charge);
3453
- // NOTE: could be more efficient with a dedicated variant of
3454
- // PurgeImpl, but this is not a common operation
3455
- Remove(&h);
3456
- MarkEmpty(h);
3457
- occupancy_.FetchSub(1U);
3408
+ SlotMeta old_meta = h.meta.LoadRelaxed();
3409
+ if (old_meta.IsShareable() && old_meta.GetRefcount() == 0) {
3410
+ SlotMeta construction_meta;
3411
+ construction_meta.SetUnderConstruction();
3412
+ if (h.meta.CasStrong(old_meta, construction_meta)) {
3413
+ // Took ownership
3414
+ h.FreeData(allocator_);
3415
+ usage_.FetchSubRelaxed(h.total_charge);
3416
+ // NOTE: could be more efficient with a dedicated variant of
3417
+ // PurgeImpl, but this is not a common operation
3418
+ Remove(&h);
3419
+ MarkEmpty(h);
3420
+ occupancy_.FetchSub(1U);
3421
+ }
3458
3422
  }
3459
3423
  }
3460
3424
  }