tigerbeetle 0.0.40 → 0.17.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +0 -25
  3. data/README.md +670 -80
  4. data/docs/migration.md +201 -0
  5. data/sig/tigerbeetle.rbs +271 -0
  6. data/src/ext/tigerbeetle/extconf.rb +47 -0
  7. data/src/ext/tigerbeetle/lib/aarch64-linux-gnu.2.27/libtb_client.so +0 -0
  8. data/src/ext/tigerbeetle/lib/aarch64-linux-musl/libtb_client.so +0 -0
  9. data/src/ext/tigerbeetle/lib/aarch64-macos/libtb_client.dylib +0 -0
  10. data/src/ext/tigerbeetle/lib/x86_64-linux-gnu.2.27/libtb_client.so +0 -0
  11. data/src/ext/tigerbeetle/lib/x86_64-linux-musl/libtb_client.so +0 -0
  12. data/src/ext/tigerbeetle/lib/x86_64-macos/libtb_client.dylib +0 -0
  13. data/src/ext/tigerbeetle/lib/x86_64-windows/tb_client.dll +0 -0
  14. data/src/ext/tigerbeetle/rb_tb_gen.h +458 -0
  15. data/{ext/tb_client/tigerbeetle/src/clients/rust/assets → src/ext/tigerbeetle}/tb_client.h +18 -16
  16. data/src/ext/tigerbeetle/tigerbeetle.c +310 -0
  17. data/src/tigerbeetle/bindings.rb +347 -0
  18. data/src/tigerbeetle/client.rb +129 -0
  19. data/src/tigerbeetle/completion_dispatcher.rb +108 -0
  20. data/src/tigerbeetle/id.rb +40 -0
  21. data/src/tigerbeetle/tb.rb +3 -0
  22. data/src/tigerbeetle/version.rb +3 -0
  23. data/src/tigerbeetle.rb +39 -0
  24. metadata +33 -350
  25. data/CHANGELOG.md +0 -162
  26. data/ext/tb_client/extconf.rb +0 -41
  27. data/ext/tb_client/tigerbeetle/LICENSE +0 -177
  28. data/ext/tb_client/tigerbeetle/build.zig +0 -2296
  29. data/ext/tb_client/tigerbeetle/src/aof.zig +0 -1000
  30. data/ext/tb_client/tigerbeetle/src/build/fetch.zig +0 -112
  31. data/ext/tb_client/tigerbeetle/src/build_multiversion.zig +0 -808
  32. data/ext/tb_client/tigerbeetle/src/cdc/amqp/protocol.zig +0 -1283
  33. data/ext/tb_client/tigerbeetle/src/cdc/amqp/spec.zig +0 -1704
  34. data/ext/tb_client/tigerbeetle/src/cdc/amqp/types.zig +0 -341
  35. data/ext/tb_client/tigerbeetle/src/cdc/amqp.zig +0 -1450
  36. data/ext/tb_client/tigerbeetle/src/cdc/runner.zig +0 -1659
  37. data/ext/tb_client/tigerbeetle/src/clients/c/samples/main.c +0 -406
  38. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/context.zig +0 -1092
  39. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/echo_client.zig +0 -286
  40. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/packet.zig +0 -158
  41. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/signal.zig +0 -229
  42. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/signal_fuzz.zig +0 -110
  43. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client.h +0 -386
  44. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client.zig +0 -34
  45. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client_exports.zig +0 -281
  46. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client_header.zig +0 -312
  47. data/ext/tb_client/tigerbeetle/src/clients/c/tb_client_header_test.zig +0 -138
  48. data/ext/tb_client/tigerbeetle/src/clients/c/test.zig +0 -466
  49. data/ext/tb_client/tigerbeetle/src/clients/docs_samples.zig +0 -157
  50. data/ext/tb_client/tigerbeetle/src/clients/docs_types.zig +0 -90
  51. data/ext/tb_client/tigerbeetle/src/clients/dotnet/ci.zig +0 -203
  52. data/ext/tb_client/tigerbeetle/src/clients/dotnet/docs.zig +0 -79
  53. data/ext/tb_client/tigerbeetle/src/clients/dotnet/dotnet_bindings.zig +0 -542
  54. data/ext/tb_client/tigerbeetle/src/clients/go/ci.zig +0 -109
  55. data/ext/tb_client/tigerbeetle/src/clients/go/docs.zig +0 -86
  56. data/ext/tb_client/tigerbeetle/src/clients/go/go_bindings.zig +0 -370
  57. data/ext/tb_client/tigerbeetle/src/clients/go/pkg/native/tb_client.h +0 -386
  58. data/ext/tb_client/tigerbeetle/src/clients/java/ci.zig +0 -167
  59. data/ext/tb_client/tigerbeetle/src/clients/java/docs.zig +0 -126
  60. data/ext/tb_client/tigerbeetle/src/clients/java/java_bindings.zig +0 -996
  61. data/ext/tb_client/tigerbeetle/src/clients/java/src/client.zig +0 -748
  62. data/ext/tb_client/tigerbeetle/src/clients/java/src/jni.zig +0 -3238
  63. data/ext/tb_client/tigerbeetle/src/clients/java/src/jni_tests.zig +0 -1718
  64. data/ext/tb_client/tigerbeetle/src/clients/java/src/jni_thread_cleaner.zig +0 -190
  65. data/ext/tb_client/tigerbeetle/src/clients/node/ci.zig +0 -104
  66. data/ext/tb_client/tigerbeetle/src/clients/node/docs.zig +0 -75
  67. data/ext/tb_client/tigerbeetle/src/clients/node/node.zig +0 -522
  68. data/ext/tb_client/tigerbeetle/src/clients/node/node_bindings.zig +0 -267
  69. data/ext/tb_client/tigerbeetle/src/clients/node/src/c.zig +0 -3
  70. data/ext/tb_client/tigerbeetle/src/clients/node/src/translate.zig +0 -379
  71. data/ext/tb_client/tigerbeetle/src/clients/python/ci.zig +0 -131
  72. data/ext/tb_client/tigerbeetle/src/clients/python/docs.zig +0 -63
  73. data/ext/tb_client/tigerbeetle/src/clients/python/python_bindings.zig +0 -588
  74. data/ext/tb_client/tigerbeetle/src/clients/rust/ci.zig +0 -73
  75. data/ext/tb_client/tigerbeetle/src/clients/rust/docs.zig +0 -106
  76. data/ext/tb_client/tigerbeetle/src/clients/rust/rust_bindings.zig +0 -305
  77. data/ext/tb_client/tigerbeetle/src/config.zig +0 -296
  78. data/ext/tb_client/tigerbeetle/src/constants.zig +0 -790
  79. data/ext/tb_client/tigerbeetle/src/copyhound.zig +0 -202
  80. data/ext/tb_client/tigerbeetle/src/counting_allocator.zig +0 -72
  81. data/ext/tb_client/tigerbeetle/src/direction.zig +0 -120
  82. data/ext/tb_client/tigerbeetle/src/docs_website/build.zig +0 -158
  83. data/ext/tb_client/tigerbeetle/src/docs_website/src/content.zig +0 -156
  84. data/ext/tb_client/tigerbeetle/src/docs_website/src/docs.zig +0 -252
  85. data/ext/tb_client/tigerbeetle/src/docs_website/src/file_checker.zig +0 -313
  86. data/ext/tb_client/tigerbeetle/src/docs_website/src/html.zig +0 -87
  87. data/ext/tb_client/tigerbeetle/src/docs_website/src/page_writer.zig +0 -63
  88. data/ext/tb_client/tigerbeetle/src/docs_website/src/redirects.zig +0 -47
  89. data/ext/tb_client/tigerbeetle/src/docs_website/src/search_index_writer.zig +0 -28
  90. data/ext/tb_client/tigerbeetle/src/docs_website/src/service_worker_writer.zig +0 -61
  91. data/ext/tb_client/tigerbeetle/src/docs_website/src/single_page_writer.zig +0 -169
  92. data/ext/tb_client/tigerbeetle/src/docs_website/src/website.zig +0 -46
  93. data/ext/tb_client/tigerbeetle/src/ewah.zig +0 -445
  94. data/ext/tb_client/tigerbeetle/src/ewah_benchmark.zig +0 -128
  95. data/ext/tb_client/tigerbeetle/src/ewah_fuzz.zig +0 -171
  96. data/ext/tb_client/tigerbeetle/src/fuzz_tests.zig +0 -179
  97. data/ext/tb_client/tigerbeetle/src/integration_tests.zig +0 -662
  98. data/ext/tb_client/tigerbeetle/src/io/common.zig +0 -155
  99. data/ext/tb_client/tigerbeetle/src/io/darwin.zig +0 -1093
  100. data/ext/tb_client/tigerbeetle/src/io/linux.zig +0 -1880
  101. data/ext/tb_client/tigerbeetle/src/io/test.zig +0 -1005
  102. data/ext/tb_client/tigerbeetle/src/io/windows.zig +0 -1598
  103. data/ext/tb_client/tigerbeetle/src/io.zig +0 -34
  104. data/ext/tb_client/tigerbeetle/src/iops.zig +0 -134
  105. data/ext/tb_client/tigerbeetle/src/list.zig +0 -236
  106. data/ext/tb_client/tigerbeetle/src/lsm/binary_search.zig +0 -848
  107. data/ext/tb_client/tigerbeetle/src/lsm/binary_search_benchmark.zig +0 -179
  108. data/ext/tb_client/tigerbeetle/src/lsm/cache_map.zig +0 -424
  109. data/ext/tb_client/tigerbeetle/src/lsm/cache_map_fuzz.zig +0 -420
  110. data/ext/tb_client/tigerbeetle/src/lsm/compaction.zig +0 -2114
  111. data/ext/tb_client/tigerbeetle/src/lsm/composite_key.zig +0 -185
  112. data/ext/tb_client/tigerbeetle/src/lsm/forest.zig +0 -1146
  113. data/ext/tb_client/tigerbeetle/src/lsm/forest_fuzz.zig +0 -1102
  114. data/ext/tb_client/tigerbeetle/src/lsm/forest_table_iterator.zig +0 -200
  115. data/ext/tb_client/tigerbeetle/src/lsm/groove.zig +0 -1495
  116. data/ext/tb_client/tigerbeetle/src/lsm/k_way_merge.zig +0 -739
  117. data/ext/tb_client/tigerbeetle/src/lsm/k_way_merge_benchmark.zig +0 -166
  118. data/ext/tb_client/tigerbeetle/src/lsm/manifest.zig +0 -754
  119. data/ext/tb_client/tigerbeetle/src/lsm/manifest_level.zig +0 -1294
  120. data/ext/tb_client/tigerbeetle/src/lsm/manifest_level_fuzz.zig +0 -510
  121. data/ext/tb_client/tigerbeetle/src/lsm/manifest_log.zig +0 -1241
  122. data/ext/tb_client/tigerbeetle/src/lsm/manifest_log_fuzz.zig +0 -628
  123. data/ext/tb_client/tigerbeetle/src/lsm/node_pool.zig +0 -247
  124. data/ext/tb_client/tigerbeetle/src/lsm/scan_buffer.zig +0 -116
  125. data/ext/tb_client/tigerbeetle/src/lsm/scan_builder.zig +0 -543
  126. data/ext/tb_client/tigerbeetle/src/lsm/scan_fuzz.zig +0 -938
  127. data/ext/tb_client/tigerbeetle/src/lsm/scan_lookup.zig +0 -293
  128. data/ext/tb_client/tigerbeetle/src/lsm/scan_merge.zig +0 -359
  129. data/ext/tb_client/tigerbeetle/src/lsm/scan_range.zig +0 -99
  130. data/ext/tb_client/tigerbeetle/src/lsm/scan_state.zig +0 -17
  131. data/ext/tb_client/tigerbeetle/src/lsm/scan_tree.zig +0 -962
  132. data/ext/tb_client/tigerbeetle/src/lsm/schema.zig +0 -617
  133. data/ext/tb_client/tigerbeetle/src/lsm/scratch_memory.zig +0 -84
  134. data/ext/tb_client/tigerbeetle/src/lsm/segmented_array.zig +0 -1500
  135. data/ext/tb_client/tigerbeetle/src/lsm/segmented_array_benchmark.zig +0 -149
  136. data/ext/tb_client/tigerbeetle/src/lsm/segmented_array_fuzz.zig +0 -7
  137. data/ext/tb_client/tigerbeetle/src/lsm/set_associative_cache.zig +0 -865
  138. data/ext/tb_client/tigerbeetle/src/lsm/table.zig +0 -607
  139. data/ext/tb_client/tigerbeetle/src/lsm/table_memory.zig +0 -843
  140. data/ext/tb_client/tigerbeetle/src/lsm/table_value_iterator.zig +0 -90
  141. data/ext/tb_client/tigerbeetle/src/lsm/timestamp_range.zig +0 -40
  142. data/ext/tb_client/tigerbeetle/src/lsm/tree.zig +0 -629
  143. data/ext/tb_client/tigerbeetle/src/lsm/tree_fuzz.zig +0 -933
  144. data/ext/tb_client/tigerbeetle/src/lsm/zig_zag_merge.zig +0 -534
  145. data/ext/tb_client/tigerbeetle/src/message_buffer.zig +0 -469
  146. data/ext/tb_client/tigerbeetle/src/message_bus.zig +0 -1219
  147. data/ext/tb_client/tigerbeetle/src/message_bus_fuzz.zig +0 -936
  148. data/ext/tb_client/tigerbeetle/src/message_pool.zig +0 -343
  149. data/ext/tb_client/tigerbeetle/src/multiversion.zig +0 -2195
  150. data/ext/tb_client/tigerbeetle/src/queue.zig +0 -390
  151. data/ext/tb_client/tigerbeetle/src/repl/completion.zig +0 -201
  152. data/ext/tb_client/tigerbeetle/src/repl/parser.zig +0 -1356
  153. data/ext/tb_client/tigerbeetle/src/repl/terminal.zig +0 -496
  154. data/ext/tb_client/tigerbeetle/src/repl.zig +0 -1034
  155. data/ext/tb_client/tigerbeetle/src/scripts/amqp.zig +0 -973
  156. data/ext/tb_client/tigerbeetle/src/scripts/cfo.zig +0 -1866
  157. data/ext/tb_client/tigerbeetle/src/scripts/changelog.zig +0 -304
  158. data/ext/tb_client/tigerbeetle/src/scripts/ci.zig +0 -227
  159. data/ext/tb_client/tigerbeetle/src/scripts/client_readmes.zig +0 -658
  160. data/ext/tb_client/tigerbeetle/src/scripts/devhub.zig +0 -466
  161. data/ext/tb_client/tigerbeetle/src/scripts/release.zig +0 -1058
  162. data/ext/tb_client/tigerbeetle/src/scripts.zig +0 -105
  163. data/ext/tb_client/tigerbeetle/src/shell.zig +0 -1195
  164. data/ext/tb_client/tigerbeetle/src/stack.zig +0 -260
  165. data/ext/tb_client/tigerbeetle/src/state_machine/auditor.zig +0 -911
  166. data/ext/tb_client/tigerbeetle/src/state_machine/workload.zig +0 -2079
  167. data/ext/tb_client/tigerbeetle/src/state_machine.zig +0 -4872
  168. data/ext/tb_client/tigerbeetle/src/state_machine_fuzz.zig +0 -288
  169. data/ext/tb_client/tigerbeetle/src/state_machine_tests.zig +0 -3128
  170. data/ext/tb_client/tigerbeetle/src/static_allocator.zig +0 -82
  171. data/ext/tb_client/tigerbeetle/src/stdx/bit_set.zig +0 -157
  172. data/ext/tb_client/tigerbeetle/src/stdx/bounded_array.zig +0 -292
  173. data/ext/tb_client/tigerbeetle/src/stdx/debug.zig +0 -65
  174. data/ext/tb_client/tigerbeetle/src/stdx/flags.zig +0 -1414
  175. data/ext/tb_client/tigerbeetle/src/stdx/huge_page_allocator.zig +0 -115
  176. data/ext/tb_client/tigerbeetle/src/stdx/mlock.zig +0 -92
  177. data/ext/tb_client/tigerbeetle/src/stdx/prng.zig +0 -677
  178. data/ext/tb_client/tigerbeetle/src/stdx/radix.zig +0 -336
  179. data/ext/tb_client/tigerbeetle/src/stdx/ring_buffer.zig +0 -511
  180. data/ext/tb_client/tigerbeetle/src/stdx/sort_test.zig +0 -112
  181. data/ext/tb_client/tigerbeetle/src/stdx/stdx.zig +0 -1163
  182. data/ext/tb_client/tigerbeetle/src/stdx/testing/low_level_hash_vectors.zig +0 -142
  183. data/ext/tb_client/tigerbeetle/src/stdx/testing/snaptest.zig +0 -361
  184. data/ext/tb_client/tigerbeetle/src/stdx/time_units.zig +0 -275
  185. data/ext/tb_client/tigerbeetle/src/stdx/unshare.zig +0 -295
  186. data/ext/tb_client/tigerbeetle/src/stdx/vendored/aegis.zig +0 -436
  187. data/ext/tb_client/tigerbeetle/src/stdx/windows.zig +0 -48
  188. data/ext/tb_client/tigerbeetle/src/stdx/zipfian.zig +0 -402
  189. data/ext/tb_client/tigerbeetle/src/storage.zig +0 -489
  190. data/ext/tb_client/tigerbeetle/src/storage_fuzz.zig +0 -180
  191. data/ext/tb_client/tigerbeetle/src/testing/bench.zig +0 -146
  192. data/ext/tb_client/tigerbeetle/src/testing/cluster/grid_checker.zig +0 -53
  193. data/ext/tb_client/tigerbeetle/src/testing/cluster/journal_checker.zig +0 -61
  194. data/ext/tb_client/tigerbeetle/src/testing/cluster/manifest_checker.zig +0 -76
  195. data/ext/tb_client/tigerbeetle/src/testing/cluster/message_bus.zig +0 -110
  196. data/ext/tb_client/tigerbeetle/src/testing/cluster/network.zig +0 -412
  197. data/ext/tb_client/tigerbeetle/src/testing/cluster/state_checker.zig +0 -331
  198. data/ext/tb_client/tigerbeetle/src/testing/cluster/storage_checker.zig +0 -458
  199. data/ext/tb_client/tigerbeetle/src/testing/cluster.zig +0 -1198
  200. data/ext/tb_client/tigerbeetle/src/testing/exhaustigen.zig +0 -128
  201. data/ext/tb_client/tigerbeetle/src/testing/fixtures.zig +0 -181
  202. data/ext/tb_client/tigerbeetle/src/testing/fuzz.zig +0 -144
  203. data/ext/tb_client/tigerbeetle/src/testing/id.zig +0 -97
  204. data/ext/tb_client/tigerbeetle/src/testing/io.zig +0 -317
  205. data/ext/tb_client/tigerbeetle/src/testing/marks.zig +0 -126
  206. data/ext/tb_client/tigerbeetle/src/testing/packet_simulator.zig +0 -533
  207. data/ext/tb_client/tigerbeetle/src/testing/reply_sequence.zig +0 -154
  208. data/ext/tb_client/tigerbeetle/src/testing/state_machine.zig +0 -389
  209. data/ext/tb_client/tigerbeetle/src/testing/storage.zig +0 -1247
  210. data/ext/tb_client/tigerbeetle/src/testing/table.zig +0 -249
  211. data/ext/tb_client/tigerbeetle/src/testing/time.zig +0 -98
  212. data/ext/tb_client/tigerbeetle/src/testing/tmp_tigerbeetle.zig +0 -212
  213. data/ext/tb_client/tigerbeetle/src/testing/vortex/constants.zig +0 -26
  214. data/ext/tb_client/tigerbeetle/src/testing/vortex/faulty_network.zig +0 -579
  215. data/ext/tb_client/tigerbeetle/src/testing/vortex/java_driver/ci.zig +0 -39
  216. data/ext/tb_client/tigerbeetle/src/testing/vortex/logged_process.zig +0 -214
  217. data/ext/tb_client/tigerbeetle/src/testing/vortex/rust_driver/ci.zig +0 -34
  218. data/ext/tb_client/tigerbeetle/src/testing/vortex/supervisor.zig +0 -785
  219. data/ext/tb_client/tigerbeetle/src/testing/vortex/workload.zig +0 -543
  220. data/ext/tb_client/tigerbeetle/src/testing/vortex/zig_driver.zig +0 -181
  221. data/ext/tb_client/tigerbeetle/src/tidy.zig +0 -1449
  222. data/ext/tb_client/tigerbeetle/src/tigerbeetle/benchmark_driver.zig +0 -227
  223. data/ext/tb_client/tigerbeetle/src/tigerbeetle/benchmark_load.zig +0 -1069
  224. data/ext/tb_client/tigerbeetle/src/tigerbeetle/cli.zig +0 -1422
  225. data/ext/tb_client/tigerbeetle/src/tigerbeetle/inspect.zig +0 -1658
  226. data/ext/tb_client/tigerbeetle/src/tigerbeetle/inspect_integrity.zig +0 -518
  227. data/ext/tb_client/tigerbeetle/src/tigerbeetle/libtb_client.zig +0 -36
  228. data/ext/tb_client/tigerbeetle/src/tigerbeetle/main.zig +0 -646
  229. data/ext/tb_client/tigerbeetle/src/tigerbeetle.zig +0 -958
  230. data/ext/tb_client/tigerbeetle/src/time.zig +0 -236
  231. data/ext/tb_client/tigerbeetle/src/trace/event.zig +0 -745
  232. data/ext/tb_client/tigerbeetle/src/trace/statsd.zig +0 -462
  233. data/ext/tb_client/tigerbeetle/src/trace.zig +0 -556
  234. data/ext/tb_client/tigerbeetle/src/unit_tests.zig +0 -321
  235. data/ext/tb_client/tigerbeetle/src/vopr.zig +0 -1785
  236. data/ext/tb_client/tigerbeetle/src/vortex.zig +0 -101
  237. data/ext/tb_client/tigerbeetle/src/vsr/checkpoint_trailer.zig +0 -473
  238. data/ext/tb_client/tigerbeetle/src/vsr/checksum.zig +0 -208
  239. data/ext/tb_client/tigerbeetle/src/vsr/checksum_benchmark.zig +0 -43
  240. data/ext/tb_client/tigerbeetle/src/vsr/client.zig +0 -768
  241. data/ext/tb_client/tigerbeetle/src/vsr/client_replies.zig +0 -532
  242. data/ext/tb_client/tigerbeetle/src/vsr/client_sessions.zig +0 -338
  243. data/ext/tb_client/tigerbeetle/src/vsr/clock.zig +0 -1019
  244. data/ext/tb_client/tigerbeetle/src/vsr/fault_detector.zig +0 -279
  245. data/ext/tb_client/tigerbeetle/src/vsr/free_set.zig +0 -1381
  246. data/ext/tb_client/tigerbeetle/src/vsr/free_set_fuzz.zig +0 -315
  247. data/ext/tb_client/tigerbeetle/src/vsr/grid.zig +0 -1460
  248. data/ext/tb_client/tigerbeetle/src/vsr/grid_blocks_missing.zig +0 -757
  249. data/ext/tb_client/tigerbeetle/src/vsr/grid_scrubber.zig +0 -797
  250. data/ext/tb_client/tigerbeetle/src/vsr/journal.zig +0 -2586
  251. data/ext/tb_client/tigerbeetle/src/vsr/marzullo.zig +0 -308
  252. data/ext/tb_client/tigerbeetle/src/vsr/message_header.zig +0 -1777
  253. data/ext/tb_client/tigerbeetle/src/vsr/multi_batch.zig +0 -715
  254. data/ext/tb_client/tigerbeetle/src/vsr/multi_batch_fuzz.zig +0 -185
  255. data/ext/tb_client/tigerbeetle/src/vsr/repair_budget.zig +0 -333
  256. data/ext/tb_client/tigerbeetle/src/vsr/replica.zig +0 -12356
  257. data/ext/tb_client/tigerbeetle/src/vsr/replica_format.zig +0 -416
  258. data/ext/tb_client/tigerbeetle/src/vsr/replica_reformat.zig +0 -165
  259. data/ext/tb_client/tigerbeetle/src/vsr/replica_test.zig +0 -2928
  260. data/ext/tb_client/tigerbeetle/src/vsr/routing.zig +0 -1075
  261. data/ext/tb_client/tigerbeetle/src/vsr/superblock.zig +0 -1603
  262. data/ext/tb_client/tigerbeetle/src/vsr/superblock_fuzz.zig +0 -484
  263. data/ext/tb_client/tigerbeetle/src/vsr/superblock_quorums.zig +0 -405
  264. data/ext/tb_client/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +0 -355
  265. data/ext/tb_client/tigerbeetle/src/vsr/sync.zig +0 -29
  266. data/ext/tb_client/tigerbeetle/src/vsr.zig +0 -1727
  267. data/lib/tb_client/shared_lib.rb +0 -66
  268. data/lib/tb_client.rb +0 -282
  269. data/lib/tigerbeetle/account.rb +0 -38
  270. data/lib/tigerbeetle/account_balance.rb +0 -23
  271. data/lib/tigerbeetle/account_filter.rb +0 -31
  272. data/lib/tigerbeetle/atomic_counter.rb +0 -14
  273. data/lib/tigerbeetle/client.rb +0 -214
  274. data/lib/tigerbeetle/converters/account.rb +0 -63
  275. data/lib/tigerbeetle/converters/account_balance.rb +0 -31
  276. data/lib/tigerbeetle/converters/account_filter.rb +0 -32
  277. data/lib/tigerbeetle/converters/base.rb +0 -35
  278. data/lib/tigerbeetle/converters/create_accounts_result.rb +0 -21
  279. data/lib/tigerbeetle/converters/create_transfers_result.rb +0 -21
  280. data/lib/tigerbeetle/converters/query_filter.rb +0 -33
  281. data/lib/tigerbeetle/converters/time.rb +0 -23
  282. data/lib/tigerbeetle/converters/transfer.rb +0 -64
  283. data/lib/tigerbeetle/converters/uint_128.rb +0 -24
  284. data/lib/tigerbeetle/converters.rb +0 -12
  285. data/lib/tigerbeetle/error.rb +0 -4
  286. data/lib/tigerbeetle/id.rb +0 -30
  287. data/lib/tigerbeetle/platforms.rb +0 -9
  288. data/lib/tigerbeetle/query_filter.rb +0 -31
  289. data/lib/tigerbeetle/request.rb +0 -7
  290. data/lib/tigerbeetle/transfer.rb +0 -40
  291. data/lib/tigerbeetle/version.rb +0 -4
  292. data/lib/tigerbeetle.rb +0 -13
  293. data/tigerbeetle.gemspec +0 -60
@@ -1,1163 +0,0 @@
1
- //! Extensions to the standard library -- things which could have been in std, but aren't.
2
- //!
3
- //! Unlike std, the namespacing is relatively flat: `stdx.PRNG` rather than `stdx.random.PRNG`.
4
- //! We don't care about backwards compatibility and prefer directness to scalability. Hierarchy can
5
- //! always be introduced later, when/if stdx grows too large.
6
-
7
- const std = @import("std");
8
- const builtin = @import("builtin");
9
- const assert = std.debug.assert;
10
-
11
- pub const BitSetType = @import("bit_set.zig").BitSetType;
12
- pub const BoundedArrayType = @import("bounded_array.zig").BoundedArrayType;
13
- pub const PRNG = @import("prng.zig");
14
- pub const RingBufferType = @import("ring_buffer.zig").RingBufferType;
15
- pub const Snap = @import("testing/snaptest.zig").Snap;
16
- pub const ZipfianGenerator = @import("zipfian.zig").ZipfianGenerator;
17
- pub const ZipfianShuffled = @import("zipfian.zig").ZipfianShuffled;
18
-
19
- pub const huge_page_allocator = @import("huge_page_allocator.zig").huge_page_allocator;
20
-
21
- pub const aegis = @import("vendored/aegis.zig");
22
- pub const dbg = @import("debug.zig").dbg;
23
- pub const flags = @import("flags.zig").parse;
24
- pub const parse_flag_value_fuzz = @import("flags.zig").parse_flag_value_fuzz;
25
- pub const memory_lock_allocated = @import("mlock.zig").memory_lock_allocated;
26
- pub const timeit = @import("debug.zig").timeit;
27
- pub const unshare = @import("unshare.zig");
28
- pub const windows = @import("windows.zig");
29
- pub const radix_sort = @import("radix.zig").sort;
30
-
31
- pub const Instant = @import("time_units.zig").Instant;
32
- pub const Duration = @import("time_units.zig").Duration;
33
- pub const InstantUnix = @import("time_units.zig").InstantUnix;
34
-
35
- // Import these as `const GiB = stdx.GiB;`
36
- pub const KiB = 1 << 10;
37
- pub const MiB = 1 << 20;
38
- pub const GiB = 1 << 30;
39
- pub const TiB = 1 << 40;
40
- pub const PiB = 1 << 50;
41
- // pub const NiB = "Some people say my love cannot be true";
42
-
43
- comptime {
44
- assert(KiB == 1024);
45
- assert(MiB == 1024 * KiB);
46
- assert(GiB == 1024 * MiB);
47
- assert(TiB == 1024 * GiB);
48
- assert(PiB == 1024 * TiB);
49
- }
50
-
51
- pub inline fn div_ceil(numerator: anytype, denominator: anytype) @TypeOf(numerator, denominator) {
52
- comptime {
53
- switch (@typeInfo(@TypeOf(numerator))) {
54
- .int => |int| assert(int.signedness == .unsigned),
55
- .comptime_int => assert(numerator >= 0),
56
- else => @compileError("div_ceil: invalid numerator type"),
57
- }
58
-
59
- switch (@typeInfo(@TypeOf(denominator))) {
60
- .int => |int| assert(int.signedness == .unsigned),
61
- .comptime_int => assert(denominator > 0),
62
- else => @compileError("div_ceil: invalid denominator type"),
63
- }
64
- }
65
-
66
- assert(denominator > 0);
67
-
68
- if (numerator == 0) return 0;
69
- return @divFloor(numerator - 1, denominator) + 1;
70
- }
71
-
72
- test "div_ceil" {
73
- // Comptime ints.
74
- try std.testing.expectEqual(div_ceil(0, 8), 0);
75
- try std.testing.expectEqual(div_ceil(1, 8), 1);
76
- try std.testing.expectEqual(div_ceil(7, 8), 1);
77
- try std.testing.expectEqual(div_ceil(8, 8), 1);
78
- try std.testing.expectEqual(div_ceil(9, 8), 2);
79
-
80
- // Unsized ints
81
- const max = std.math.maxInt(u64);
82
- try std.testing.expectEqual(div_ceil(@as(u64, 0), 8), 0);
83
- try std.testing.expectEqual(div_ceil(@as(u64, 1), 8), 1);
84
- try std.testing.expectEqual(div_ceil(@as(u64, max), 2), max / 2 + 1);
85
- try std.testing.expectEqual(div_ceil(@as(u64, max) - 1, 2), max / 2);
86
- try std.testing.expectEqual(div_ceil(@as(u64, max) - 2, 2), max / 2);
87
- }
88
-
89
- pub const SizePrecision = enum { exact, inexact };
90
-
91
- pub inline fn copy_left(
92
- comptime precision: SizePrecision,
93
- comptime T: type,
94
- target: []T,
95
- source: []const T,
96
- ) void {
97
- switch (precision) {
98
- .exact => assert(target.len == source.len),
99
- .inexact => assert(target.len >= source.len),
100
- }
101
-
102
- if (!disjoint_slices(T, T, target, source)) {
103
- assert(@intFromPtr(target.ptr) < @intFromPtr(source.ptr));
104
- }
105
-
106
- // (Bypass tidy's ban.)
107
- const copyForwards = std.mem.copyForwards;
108
- copyForwards(T, target, source);
109
- }
110
-
111
- test "copy_left" {
112
- const a = try std.testing.allocator.alloc(usize, 8);
113
- defer std.testing.allocator.free(a);
114
-
115
- for (a, 0..) |*v, i| v.* = i;
116
- copy_left(.exact, usize, a[0..6], a[2..]);
117
- try std.testing.expect(std.mem.eql(usize, a, &.{ 2, 3, 4, 5, 6, 7, 6, 7 }));
118
- }
119
-
120
- pub inline fn copy_right(
121
- comptime precision: SizePrecision,
122
- comptime T: type,
123
- target: []T,
124
- source: []const T,
125
- ) void {
126
- switch (precision) {
127
- .exact => assert(target.len == source.len),
128
- .inexact => assert(target.len >= source.len),
129
- }
130
-
131
- if (!disjoint_slices(T, T, target, source)) {
132
- assert(@intFromPtr(target.ptr) > @intFromPtr(source.ptr));
133
- }
134
-
135
- // (Bypass tidy's ban.)
136
- const copyBackwards = std.mem.copyBackwards;
137
- copyBackwards(T, target, source);
138
- }
139
-
140
- test "copy_right" {
141
- const a = try std.testing.allocator.alloc(usize, 8);
142
- defer std.testing.allocator.free(a);
143
-
144
- for (a, 0..) |*v, i| v.* = i;
145
- copy_right(.exact, usize, a[2..], a[0..6]);
146
- try std.testing.expect(std.mem.eql(usize, a, &.{ 0, 1, 0, 1, 2, 3, 4, 5 }));
147
- }
148
-
149
- pub inline fn copy_disjoint(
150
- comptime precision: SizePrecision,
151
- comptime T: type,
152
- target: []T,
153
- source: []const T,
154
- ) void {
155
- switch (precision) {
156
- .exact => assert(target.len == source.len),
157
- .inexact => assert(target.len >= source.len),
158
- }
159
-
160
- // disjoint_slices() doesn't work in comptime, because of limitations with @intFromPtr:
161
- // https://github.com/ziglang/zig/issues/23072.
162
- //
163
- // It's also possible to construct slices into an array at comptime that are _not_ disjoint,
164
- // which would violate the intention of this function, so it can't just be skipped.
165
- assert(!@inComptime());
166
- assert(disjoint_slices(T, T, target, source));
167
-
168
- @memcpy // Bypass tidy ban.
169
- (target[0..source.len], source);
170
- }
171
-
172
- pub inline fn disjoint_slices(comptime A: type, comptime B: type, a: []const A, b: []const B) bool {
173
- return @intFromPtr(a.ptr) + a.len * @sizeOf(A) <= @intFromPtr(b.ptr) or
174
- @intFromPtr(b.ptr) + b.len * @sizeOf(B) <= @intFromPtr(a.ptr);
175
- }
176
-
177
- test "disjoint_slices" {
178
- const a = try std.testing.allocator.alignedAlloc(u8, @sizeOf(u32), 8 * @sizeOf(u32));
179
- defer std.testing.allocator.free(a);
180
-
181
- const b = try std.testing.allocator.alloc(u32, 8);
182
- defer std.testing.allocator.free(b);
183
-
184
- try std.testing.expectEqual(true, disjoint_slices(u8, u32, a, b));
185
- try std.testing.expectEqual(true, disjoint_slices(u32, u8, b, a));
186
-
187
- try std.testing.expectEqual(true, disjoint_slices(u8, u8, a, a[0..0]));
188
- try std.testing.expectEqual(true, disjoint_slices(u32, u32, b, b[0..0]));
189
-
190
- try std.testing.expectEqual(false, disjoint_slices(u8, u8, a, a[0..1]));
191
- try std.testing.expectEqual(false, disjoint_slices(u8, u8, a, a[a.len - 1 .. a.len]));
192
-
193
- try std.testing.expectEqual(false, disjoint_slices(u32, u32, b, b[0..1]));
194
- try std.testing.expectEqual(false, disjoint_slices(u32, u32, b, b[b.len - 1 .. b.len]));
195
-
196
- try std.testing.expectEqual(false, disjoint_slices(u8, u32, a, std.mem.bytesAsSlice(u32, a)));
197
- try std.testing.expectEqual(false, disjoint_slices(u32, u8, b, std.mem.sliceAsBytes(b)));
198
- }
199
-
200
- /// Checks that a byteslice is zeroed.
201
- pub fn zeroed(bytes: []const u8) bool {
202
- // This implementation already gets vectorized
203
- // https://godbolt.org/z/46cMsPKPc
204
- var byte_bits: u8 = 0;
205
- for (bytes) |byte| {
206
- byte_bits |= byte;
207
- }
208
- return byte_bits == 0;
209
- }
210
-
211
- /// Similar to `std.mem.bytesAsSlice`, but allows buffers with inexact sizes,
212
- /// returning the largest possible slice that is less than or equal to the buffer length.
213
- /// Differently from `std.mem.bytesAsSlice` that can return `[]align(1) T`, this function
214
- /// always `@alignCast` the result.
215
- pub fn bytes_as_slice(
216
- comptime precision: SizePrecision,
217
- comptime T: type,
218
- bytes: anytype,
219
- ) type: {
220
- const type_info = @typeInfo(@TypeOf(bytes));
221
- switch (type_info) {
222
- .pointer => |info| switch (info.size) {
223
- .one => switch (@typeInfo(info.child)) {
224
- .array => |array_info| assert(array_info.child == u8),
225
- else => unreachable,
226
- },
227
- .slice => assert(info.child == u8),
228
- else => unreachable,
229
- },
230
- else => unreachable,
231
- }
232
-
233
- break :type if (type_info.pointer.is_const) []const T else []T;
234
- } {
235
- switch (precision) {
236
- .exact => {
237
- assert(bytes.len % @sizeOf(T) == 0);
238
- return @alignCast(std.mem.bytesAsSlice(T, bytes));
239
- },
240
- .inexact => {
241
- const size = @divFloor(bytes.len, @sizeOf(T)) * @sizeOf(T);
242
- return @alignCast(std.mem.bytesAsSlice(T, bytes[0..size]));
243
- },
244
- }
245
- }
246
-
247
- test bytes_as_slice {
248
- var buffer: [64]u8 = undefined;
249
- const T10 = extern struct { content: [10]u8 };
250
- const T16 = extern struct { content: [16]u8 };
251
-
252
- try std.testing.expectEqual(
253
- @as(usize, 4),
254
- bytes_as_slice(.exact, T16, buffer[0..]).len,
255
- );
256
- try std.testing.expectEqual(
257
- @as(usize, 6),
258
- bytes_as_slice(.exact, T10, buffer[0..60]).len,
259
- );
260
-
261
- try std.testing.expectEqual(
262
- @as(usize, 6),
263
- bytes_as_slice(.inexact, T10, buffer[0..]).len,
264
- );
265
- try std.testing.expectEqual(
266
- @as(usize, 4),
267
- bytes_as_slice(.inexact, T16, buffer[0..]).len,
268
- );
269
- try std.testing.expectEqual(
270
- @as(usize, 6),
271
- bytes_as_slice(.inexact, T10, buffer[0 .. buffer.len - 1]).len,
272
- );
273
- try std.testing.expectEqual(
274
- @as(usize, 3),
275
- bytes_as_slice(.inexact, T16, buffer[0 .. buffer.len - 1]).len,
276
- );
277
- try std.testing.expectEqual(
278
- @as(usize, 5),
279
- bytes_as_slice(.inexact, T10, buffer[0 .. buffer.len - 10]).len,
280
- );
281
- try std.testing.expectEqual(
282
- @as(usize, 3),
283
- bytes_as_slice(.inexact, T16, buffer[0 .. buffer.len - 10]).len,
284
- );
285
- }
286
-
287
- /// Splits the `haystack` around the first occurrence of `needle`, returning parts before and after.
288
- ///
289
- /// This is a Zig version of Go's `string.Cut` / Rust's `str::split_once`. Cut turns out to be a
290
- /// surprisingly versatile primitive for ad-hoc string processing. Often `std.mem.indexOf` and
291
- /// `std.mem.split` can be replaced with a shorter and clearer code using `cut`.
292
- pub fn cut(haystack: []const u8, needle: []const u8) ?struct { []const u8, []const u8 } {
293
- const index = std.mem.indexOf(u8, haystack, needle) orelse return null;
294
-
295
- return .{ haystack[0..index], haystack[index + needle.len ..] };
296
- }
297
-
298
- test cut {
299
- try std.testing.expectEqualStrings("he", cut("hello world", "l").?[0]);
300
- try std.testing.expectEqualStrings("lo world", cut("hello world", "l").?[1]);
301
- assert(null == cut("hello world", "x"));
302
- }
303
-
304
- pub fn cut_prefix(haystack: []const u8, needle: []const u8) ?[]const u8 {
305
- if (std.mem.startsWith(u8, haystack, needle)) {
306
- return haystack[needle.len..];
307
- }
308
- return null;
309
- }
310
-
311
- test cut_prefix {
312
- try std.testing.expectEqualStrings(" world", cut_prefix("hello world", "hello").?);
313
- assert(null == cut_prefix("hello world", "hellnope"));
314
- }
315
-
316
- pub fn cut_suffix(haystack: []const u8, needle: []const u8) ?[]const u8 {
317
- if (std.mem.endsWith(u8, haystack, needle)) {
318
- return haystack[0 .. haystack.len - needle.len];
319
- }
320
- return null;
321
- }
322
-
323
- test cut_suffix {
324
- try std.testing.expectEqualStrings("hello ", cut_suffix("hello world", "world").?);
325
- assert(null == cut_suffix("hello world", "hello"));
326
- }
327
-
328
- /// `maybe` is the dual of `assert`: it signals that condition is sometimes true
329
- /// and sometimes false.
330
- ///
331
- /// Currently we use it for documentation, but maybe one day we plug it into
332
- /// coverage.
333
- pub fn maybe(ok: bool) void {
334
- assert(ok or !ok);
335
- }
336
-
337
- pub const log = if (builtin.is_test)
338
- // Downgrade `err` to `warn` for tests.
339
- // Zig fails any test that does `log.err`, but we want to test those code paths here.
340
- struct {
341
- pub fn scoped(comptime scope: @Type(.enum_literal)) type {
342
- const base = std.log.scoped(scope);
343
- return struct {
344
- pub const err = warn;
345
- pub const warn = base.warn;
346
- pub const info = base.info;
347
- pub const debug = base.debug;
348
- };
349
- }
350
- }
351
- else
352
- std.log;
353
-
354
- /// An alternative to the default logFn from `std.log`, which prepends a UTC timestamp.
355
- pub fn log_with_timestamp(
356
- comptime message_level: std.log.Level,
357
- comptime scope: @Type(.enum_literal),
358
- comptime format: []const u8,
359
- args: anytype,
360
- ) void {
361
- const level_text = comptime message_level.asText();
362
- const scope_prefix = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
363
- const instant_unix = InstantUnix.now();
364
-
365
- const stderr = std.io.getStdErr().writer();
366
- var buffered_writer = std.io.bufferedWriter(stderr);
367
- const writer = buffered_writer.writer();
368
-
369
- nosuspend {
370
- instant_unix.format("", .{}, writer) catch return;
371
- writer.print(" " ++ level_text ++ scope_prefix ++ format ++ "\n", args) catch return;
372
- buffered_writer.flush() catch return;
373
- }
374
- }
375
-
376
- /// Compare two values by directly comparing the underlying memory.
377
- ///
378
- /// Assert at compile time that this is a reasonable thing to do for a given `T`. That is, check
379
- /// that:
380
- /// - `T` doesn't have any non-deterministic padding,
381
- /// - `T` doesn't embed any pointers.
382
- pub fn equal_bytes(comptime T: type, a: *const T, b: *const T) bool {
383
- comptime assert(has_unique_representation(T));
384
- comptime assert(!has_pointers(T));
385
- comptime assert(@sizeOf(T) * 8 == @bitSizeOf(T));
386
-
387
- // Pick the biggest "word" for word-wise comparison, and don't try to early-return on the first
388
- // mismatch, so that a compiler can vectorize the loop.
389
-
390
- const Word = comptime for (.{ u64, u32, u16, u8 }) |Word| {
391
- if (@alignOf(T) >= @alignOf(Word) and @sizeOf(T) % @sizeOf(Word) == 0) break Word;
392
- } else unreachable;
393
-
394
- const a_words = std.mem.bytesAsSlice(Word, std.mem.asBytes(a));
395
- const b_words = std.mem.bytesAsSlice(Word, std.mem.asBytes(b));
396
- assert(a_words.len == b_words.len);
397
-
398
- var total: Word = 0;
399
- for (a_words, b_words) |a_word, b_word| {
400
- total |= a_word ^ b_word;
401
- }
402
-
403
- return total == 0;
404
- }
405
-
406
- fn has_pointers(comptime T: type) bool {
407
- switch (@typeInfo(T)) {
408
- .pointer => return true,
409
- // Be conservative.
410
- else => return true,
411
-
412
- .bool, .int, .@"enum" => return false,
413
-
414
- .array => |info| return comptime has_pointers(info.child),
415
- .@"struct" => |info| {
416
- inline for (info.fields) |field| {
417
- if (comptime has_pointers(field.type)) return true;
418
- }
419
- return false;
420
- },
421
- }
422
- }
423
-
424
- /// Checks that a type does not have implicit padding.
425
- pub fn no_padding(comptime T: type) bool {
426
- comptime switch (@typeInfo(T)) {
427
- .void => return true,
428
- .int => return @bitSizeOf(T) == 8 * @sizeOf(T),
429
- .array => |info| return no_padding(info.child),
430
- .@"struct" => |info| {
431
- switch (info.layout) {
432
- .auto => return false,
433
- .@"extern" => {
434
- for (info.fields) |field| {
435
- if (!no_padding(field.type)) return false;
436
- }
437
-
438
- // Check offsets of u128 and pseudo-u256 fields.
439
- for (info.fields) |field| {
440
- if (field.type == u128) {
441
- const offset = @offsetOf(T, field.name);
442
- if (offset % @sizeOf(u128) != 0) return false;
443
-
444
- if (@hasField(T, field.name ++ "_padding")) {
445
- if (offset % @sizeOf(u256) != 0) return false;
446
- if (offset + @sizeOf(u128) !=
447
- @offsetOf(T, field.name ++ "_padding"))
448
- {
449
- return false;
450
- }
451
- }
452
- }
453
- }
454
-
455
- var offset = 0;
456
- for (info.fields) |field| {
457
- const field_offset = @offsetOf(T, field.name);
458
- if (offset != field_offset) return false;
459
- offset += @sizeOf(field.type);
460
- }
461
- return offset == @sizeOf(T);
462
- },
463
- .@"packed" => return @bitSizeOf(T) == 8 * @sizeOf(T),
464
- }
465
- },
466
- .@"enum" => |info| {
467
- maybe(info.is_exhaustive);
468
- return no_padding(info.tag_type);
469
- },
470
- .pointer => return false,
471
- .@"union" => return false,
472
- else => return false,
473
- };
474
- }
475
-
476
- test no_padding {
477
- comptime for (.{
478
- u8,
479
- extern struct { x: u8 },
480
- packed struct { x: u7, y: u1 },
481
- extern struct { x: extern struct { y: u64, z: u64 } },
482
- enum(u8) { x },
483
- }) |T| {
484
- assert(no_padding(T));
485
- };
486
-
487
- comptime for (.{
488
- u7,
489
- struct { x: u7 },
490
- struct { x: u8 },
491
- struct { x: u64, y: u32 },
492
- extern struct { x: extern struct { y: u64, z: u32 } },
493
- packed struct { x: u7 },
494
- enum(u7) { x },
495
- }) |T| {
496
- assert(!no_padding(T));
497
- };
498
- }
499
-
500
- pub inline fn hash_inline(value: anytype) u64 {
501
- comptime {
502
- assert(no_padding(@TypeOf(value)));
503
- assert(has_unique_representation(@TypeOf(value)));
504
- }
505
- return low_level_hash(0, switch (@typeInfo(@TypeOf(value))) {
506
- .@"struct", .int => std.mem.asBytes(&value),
507
- else => @compileError("unsupported hashing for " ++ @typeName(@TypeOf(value))),
508
- });
509
- }
510
-
511
- /// Inline version of Google Abseil "LowLevelHash" (inspired by wyhash).
512
- /// https://github.com/abseil/abseil-cpp/blob/master/absl/hash/internal/low_level_hash.cc
513
- inline fn low_level_hash(seed: u64, input: anytype) u64 {
514
- const salt = [_]u64{
515
- 0xa0761d6478bd642f,
516
- 0xe7037ed1a0b428db,
517
- 0x8ebc6af09c88c6e3,
518
- 0x589965cc75374cc3,
519
- 0x1d8e4e27c47d124f,
520
- };
521
-
522
- var in: []const u8 = input;
523
- var state = seed ^ salt[0];
524
- const starting_len = input.len;
525
-
526
- if (in.len > 64) {
527
- var dup = [_]u64{ state, state };
528
- defer state = dup[0] ^ dup[1];
529
-
530
- while (in.len > 64) : (in = in[64..]) {
531
- for (@as([2][4]u64, @bitCast(in[0..64].*)), 0..) |chunk, i| {
532
- const mix1 = @as(u128, chunk[0] ^ salt[(i * 2) + 1]) *% (chunk[1] ^ dup[i]);
533
- const mix2 = @as(u128, chunk[2] ^ salt[(i * 2) + 2]) *% (chunk[3] ^ dup[i]);
534
- dup[i] = @as(u64, @truncate(mix1 ^ (mix1 >> 64)));
535
- dup[i] ^= @as(u64, @truncate(mix2 ^ (mix2 >> 64)));
536
- }
537
- }
538
- }
539
-
540
- while (in.len > 16) : (in = in[16..]) {
541
- const chunk = @as([2]u64, @bitCast(in[0..16].*));
542
- const mixed = @as(u128, chunk[0] ^ salt[1]) *% (chunk[1] ^ state);
543
- state = @as(u64, @truncate(mixed ^ (mixed >> 64)));
544
- }
545
-
546
- var chunk: [2]u64 = .{ 0, 0 };
547
- if (in.len > 8) {
548
- chunk[0] = @as(u64, @bitCast(in[0..8].*));
549
- chunk[1] = @as(u64, @bitCast(in[in.len - 8 ..][0..8].*));
550
- } else if (in.len > 3) {
551
- chunk[0] = @as(u32, @bitCast(in[0..4].*));
552
- chunk[1] = @as(u32, @bitCast(in[in.len - 4 ..][0..4].*));
553
- } else if (in.len > 0) {
554
- chunk[0] = (@as(u64, in[0]) << 16) | (@as(u64, in[in.len / 2]) << 8) | in[in.len - 1];
555
- }
556
-
557
- var mixed = @as(u128, chunk[0] ^ salt[1]) *% (chunk[1] ^ state);
558
- mixed = @as(u64, @truncate(mixed ^ (mixed >> 64)));
559
- mixed *%= (@as(u64, starting_len) ^ salt[1]);
560
- return @as(u64, @truncate(mixed ^ (mixed >> 64)));
561
- }
562
-
563
- test "hash_inline" {
564
- for (@import("testing/low_level_hash_vectors.zig").cases) |case| {
565
- var buffer: [0x100]u8 = undefined;
566
-
567
- const b64 = std.base64.standard;
568
- const input = buffer[0..try b64.Decoder.calcSizeForSlice(case.b64)];
569
- try b64.Decoder.decode(input, case.b64);
570
-
571
- const hash = low_level_hash(case.seed, input);
572
- try std.testing.expectEqual(case.hash, hash);
573
- }
574
- }
575
-
576
- /// Returns a copy of `base` with fields changed according to `diff`.
577
- ///
578
- /// Intended exclusively for table-driven prototype-based tests. Write
579
- /// updates explicitly in production code.
580
- pub fn update(base: anytype, diff: anytype) @TypeOf(base) {
581
- assert(builtin.is_test);
582
- assert(@typeInfo(@TypeOf(base)) == .@"struct");
583
-
584
- var updated = base;
585
- inline for (std.meta.fields(@TypeOf(diff))) |f| {
586
- @field(updated, f.name) = @field(diff, f.name);
587
- }
588
- return updated;
589
- }
590
-
591
- // std.SemanticVersion requires there be no extra characters after the
592
- // major/minor/patch numbers. But when we try to parse `uname
593
- // --kernel-release` (note: while Linux doesn't follow semantic
594
- // versioning, it doesn't violate it either), some distributions have
595
- // extra characters, such as this Fedora one: 6.3.8-100.fc37.x86_64, and
596
- // this WSL one has more than three dots:
597
- // 5.15.90.1-microsoft-standard-WSL2.
598
- pub fn parse_dirty_semver(dirty_release: []const u8) !std.SemanticVersion {
599
- const release = blk: {
600
- var last_valid_version_character_index: usize = 0;
601
- var dots_found: u8 = 0;
602
- for (dirty_release) |c| {
603
- if (c == '.') dots_found += 1;
604
- if (dots_found == 3) {
605
- break;
606
- }
607
-
608
- if (c == '.' or (c >= '0' and c <= '9')) {
609
- last_valid_version_character_index += 1;
610
- continue;
611
- }
612
-
613
- break;
614
- }
615
-
616
- break :blk dirty_release[0..last_valid_version_character_index];
617
- };
618
-
619
- return std.SemanticVersion.parse(release);
620
- }
621
-
622
- test "stdx.zig: parse_dirty_semver" {
623
- const SemverTestCase = struct {
624
- dirty_release: []const u8,
625
- expected_version: std.SemanticVersion,
626
- };
627
-
628
- const cases = &[_]SemverTestCase{
629
- .{
630
- .dirty_release = "1.2.3",
631
- .expected_version = std.SemanticVersion{ .major = 1, .minor = 2, .patch = 3 },
632
- },
633
- .{
634
- .dirty_release = "1001.843.909",
635
- .expected_version = std.SemanticVersion{ .major = 1001, .minor = 843, .patch = 909 },
636
- },
637
- .{
638
- .dirty_release = "6.3.8-100.fc37.x86_64",
639
- .expected_version = std.SemanticVersion{ .major = 6, .minor = 3, .patch = 8 },
640
- },
641
- .{
642
- .dirty_release = "5.15.90.1-microsoft-standard-WSL2",
643
- .expected_version = std.SemanticVersion{ .major = 5, .minor = 15, .patch = 90 },
644
- },
645
- };
646
- for (cases) |case| {
647
- const version = try parse_dirty_semver(case.dirty_release);
648
- try std.testing.expectEqual(case.expected_version, version);
649
- }
650
- }
651
-
652
- // TODO(zig): std doesn't have the statfs / fstatfs syscalls to get the type of a filesystem.
653
- // Once those are available, this can be removed.
654
- // The `statfs` definition used by the Linux kernel, and the magic number for tmpfs, from
655
- // `man 2 fstatfs`.
656
- const fsblkcnt64_t = u64;
657
- const fsfilcnt64_t = u64;
658
- const fsword_t = i64;
659
- const fsid_t = u64;
660
-
661
- pub const TmpfsMagic = 0x01021994;
662
- pub const StatFs = extern struct {
663
- f_type: fsword_t,
664
- f_bsize: fsword_t,
665
- f_blocks: fsblkcnt64_t,
666
- f_bfree: fsblkcnt64_t,
667
- f_bavail: fsblkcnt64_t,
668
- f_files: fsfilcnt64_t,
669
- f_ffree: fsfilcnt64_t,
670
- f_fsid: fsid_t,
671
- f_namelen: fsword_t,
672
- f_frsize: fsword_t,
673
- f_flags: fsword_t,
674
- f_spare: [4]fsword_t,
675
- };
676
-
677
- pub fn fstatfs(fd: i32, statfs_buf: *StatFs) usize {
678
- return std.os.linux.syscall2(
679
- if (@hasField(std.os.linux.SYS, "fstatfs64")) .fstatfs64 else .fstatfs,
680
- @as(usize, @bitCast(@as(isize, fd))),
681
- @intFromPtr(statfs_buf),
682
- );
683
- }
684
-
685
- /// True if every value of the type `T` has a unique bit pattern representing it.
686
- /// In other words, `T` has no unused bits and no padding.
687
- pub fn has_unique_representation(comptime T: type) bool {
688
- switch (@typeInfo(T)) {
689
- else => return false, // TODO can we know if it's true for some of these types ?
690
-
691
- .@"enum",
692
- .error_set,
693
- .@"fn",
694
- => return true,
695
-
696
- .bool => return false,
697
-
698
- .int => |info| return @sizeOf(T) * 8 == info.bits,
699
-
700
- .pointer => |info| return info.size != .slice,
701
-
702
- .array => |info| return comptime has_unique_representation(info.child),
703
-
704
- .@"struct" => |info| {
705
- // Only consider packed structs unique if they are byte aligned.
706
- if (info.backing_integer) |backing_integer| {
707
- return @sizeOf(T) * 8 == @bitSizeOf(backing_integer);
708
- }
709
-
710
- var sum_size = @as(usize, 0);
711
-
712
- inline for (info.fields) |field| {
713
- const FieldType = field.type;
714
- if (comptime !has_unique_representation(FieldType)) return false;
715
- sum_size += @sizeOf(FieldType);
716
- }
717
-
718
- return @sizeOf(T) == sum_size;
719
- },
720
-
721
- .vector => |info| return comptime has_unique_representation(info.child) and
722
- @sizeOf(T) == @sizeOf(info.child) * info.len,
723
- }
724
- }
725
-
726
- // Test vectors mostly from upstream, with some added to test the packed struct case.
727
- test "has_unique_representation" {
728
- const TestStruct1 = struct {
729
- a: u32,
730
- b: u32,
731
- };
732
-
733
- try std.testing.expect(has_unique_representation(TestStruct1));
734
-
735
- const TestStruct2 = struct {
736
- a: u32,
737
- b: u16,
738
- };
739
-
740
- try std.testing.expect(!has_unique_representation(TestStruct2));
741
-
742
- const TestStruct3 = struct {
743
- a: u32,
744
- b: u32,
745
- };
746
-
747
- try std.testing.expect(has_unique_representation(TestStruct3));
748
-
749
- const TestStruct4 = struct { a: []const u8 };
750
-
751
- try std.testing.expect(!has_unique_representation(TestStruct4));
752
-
753
- const TestStruct5 = struct { a: TestStruct4 };
754
-
755
- try std.testing.expect(!has_unique_representation(TestStruct5));
756
-
757
- const TestStruct6 = packed struct {
758
- a: u32,
759
- b: u31,
760
- };
761
-
762
- try std.testing.expect(!has_unique_representation(TestStruct6));
763
-
764
- const TestStruct7 = struct {
765
- a: u64,
766
- b: TestStruct6,
767
- };
768
-
769
- try std.testing.expect(!has_unique_representation(TestStruct7));
770
-
771
- const TestStruct8 = packed struct {
772
- a: u32,
773
- b: u32,
774
- };
775
-
776
- try std.testing.expect(has_unique_representation(TestStruct8));
777
-
778
- const TestStruct9 = struct {
779
- a: u64,
780
- b: TestStruct8,
781
- };
782
-
783
- try std.testing.expect(has_unique_representation(TestStruct9));
784
-
785
- const TestStruct10 = packed struct {
786
- a: TestStruct8,
787
- b: TestStruct8,
788
- };
789
-
790
- try std.testing.expect(has_unique_representation(TestStruct10));
791
-
792
- const TestUnion1 = packed union {
793
- a: u32,
794
- b: u16,
795
- };
796
-
797
- try std.testing.expect(!has_unique_representation(TestUnion1));
798
-
799
- const TestUnion2 = extern union {
800
- a: u32,
801
- b: u16,
802
- };
803
-
804
- try std.testing.expect(!has_unique_representation(TestUnion2));
805
-
806
- const TestUnion3 = union {
807
- a: u32,
808
- b: u16,
809
- };
810
-
811
- try std.testing.expect(!has_unique_representation(TestUnion3));
812
-
813
- const TestUnion4 = union(enum) {
814
- a: u32,
815
- b: u16,
816
- };
817
-
818
- try std.testing.expect(!has_unique_representation(TestUnion4));
819
-
820
- inline for ([_]type{ i0, u8, i16, u32, i64 }) |T| {
821
- try std.testing.expect(has_unique_representation(T));
822
- }
823
- inline for ([_]type{ i1, u9, i17, u33, i24 }) |T| {
824
- try std.testing.expect(!has_unique_representation(T));
825
- }
826
-
827
- try std.testing.expect(!has_unique_representation([]u8));
828
- try std.testing.expect(!has_unique_representation([]const u8));
829
-
830
- try std.testing.expect(has_unique_representation(@Vector(4, u16)));
831
- }
832
-
833
- /// Construct a `union(Enum)` type, where each union "value" type is defined in terms of the
834
- /// variant.
835
- ///
836
- /// That is, `EnumUnionType(Enum, TypeForVariant)` is equivalent to:
837
- ///
838
- /// union(Enum) {
839
- /// // For every `e` in `Enum`:
840
- /// e: TypeForVariant(e),
841
- /// }
842
- ///
843
- pub fn EnumUnionType(
844
- comptime Enum: type,
845
- comptime TypeForVariant: fn (comptime variant: Enum) type,
846
- ) type {
847
- const UnionField = std.builtin.Type.UnionField;
848
-
849
- var fields: [std.enums.values(Enum).len]UnionField = undefined;
850
- for (std.enums.values(Enum), 0..) |enum_variant, i| {
851
- fields[i] = .{
852
- .name = @tagName(enum_variant),
853
- .type = TypeForVariant(enum_variant),
854
- .alignment = @alignOf(TypeForVariant(enum_variant)),
855
- };
856
- }
857
-
858
- return @Type(.{ .@"union" = .{
859
- .layout = .auto,
860
- .fields = &fields,
861
- .decls = &.{},
862
- .tag_type = Enum,
863
- } });
864
- }
865
-
866
- /// Creates a slice to a comptime slice without triggering
867
- /// `error: runtime value contains reference to comptime var`
868
- pub fn comptime_slice(comptime slice: anytype, comptime len: usize) []const @TypeOf(slice[0]) {
869
- return &@as([len]@TypeOf(slice[0]), slice[0..len].*);
870
- }
871
-
872
- /// Return a Formatter for a u64 value representing a file size.
873
- /// This formatter statically checks that the number is a multiple of 1024,
874
- /// and represents it using the IEC measurement units (KiB, MiB, GiB, ...).
875
- pub fn fmt_int_size_bin_exact(comptime value: u64) std.fmt.Formatter(format_int_size_bin_exact) {
876
- comptime assert(value < 1024 or value % 1024 == 0);
877
- return .{ .data = value };
878
- }
879
-
880
- fn format_int_size_bin_exact(
881
- value: u64,
882
- comptime fmt: []const u8,
883
- options: std.fmt.FormatOptions,
884
- writer: anytype,
885
- ) !void {
886
- _ = fmt;
887
- if (value == 0) {
888
- return std.fmt.formatBuf("0B", options, writer);
889
- }
890
-
891
- // The worst case in terms of space needed is 20 bytes,
892
- // since `maxInt(u64)` is the highest number,
893
- // + 3 bytes for the measurement units suffix.
894
- comptime assert(std.fmt.comptimePrint("{}GiB", .{std.math.maxInt(u64)}).len == 23);
895
- var buf: [23]u8 = undefined;
896
-
897
- var magnitude: u8 = 0;
898
- var value_unit = value;
899
- while (value_unit % 1024 == 0) : (magnitude += 1) {
900
- value_unit = @divExact(value_unit, 1024);
901
- }
902
-
903
- const magnitudes_iec = "BKMGTPEZY";
904
- const suffix = magnitudes_iec[magnitude];
905
-
906
- const length: usize = length: {
907
- const i = std.fmt.formatIntBuf(&buf, value_unit, 10, .lower, .{});
908
- if (magnitude == 0) {
909
- buf[i] = suffix;
910
- break :length i + 1;
911
- } else {
912
- buf[i..][0..3].* = [_]u8{ suffix, 'i', 'B' };
913
- break :length i + 3;
914
- }
915
- };
916
-
917
- return std.fmt.formatBuf(buf[0..length], options, writer);
918
- }
919
-
920
- test fmt_int_size_bin_exact {
921
- try std.testing.expectFmt("0B", "{}", .{fmt_int_size_bin_exact(0)});
922
- try std.testing.expectFmt("128B", "{}", .{fmt_int_size_bin_exact(128)});
923
- try std.testing.expectFmt("8KiB", "{}", .{fmt_int_size_bin_exact(8 * 1024)});
924
- try std.testing.expectFmt("1025KiB", "{}", .{fmt_int_size_bin_exact(1025 * 1024)});
925
- try std.testing.expectFmt("12345KiB", "{}", .{fmt_int_size_bin_exact(12345 * 1024)});
926
- try std.testing.expectFmt("42MiB", "{}", .{fmt_int_size_bin_exact(42 * 1024 * 1024)});
927
- try std.testing.expectFmt("18014398509481983KiB", "{}", .{
928
- fmt_int_size_bin_exact(std.math.maxInt(u64) - 1023),
929
- });
930
- }
931
-
932
- /// Like std.fmt.bufPrint, but checks, at compile time, that the buffer is sufficiently large.
933
- pub fn array_print(
934
- comptime n: usize,
935
- buffer: *[n]u8,
936
- comptime fmt: []const u8,
937
- args: anytype,
938
- ) []const u8 {
939
- const Args = @TypeOf(args);
940
- const ArgsStruct = @typeInfo(Args).@"struct";
941
- comptime assert(ArgsStruct.is_tuple);
942
-
943
- comptime {
944
- var args_worst_case: Args = undefined;
945
- for (ArgsStruct.fields, 0..) |field, index| {
946
- const arg_worst_case = switch (field.type) {
947
- u8, u16, u32, u64, u128 => std.math.maxInt(field.type),
948
- else => @compileError("array_print: unsupported type: " ++ @typeName(field.type)),
949
- };
950
- args_worst_case[index] = arg_worst_case;
951
- }
952
- const buffer_size = std.fmt.count(fmt, args_worst_case);
953
- assert(n >= buffer_size); // array_print buffer too small
954
- }
955
-
956
- return std.fmt.bufPrint(buffer, fmt, args) catch |err| switch (err) {
957
- error.NoSpaceLeft => unreachable,
958
- };
959
- }
960
-
961
- /// Like std.posix version, but log unconditionally, not just when mode=Debug.
962
- /// The added `label` argument works around the absence of stack traces in ReleaseSafe builds.
963
- pub fn unexpected_errno(label: []const u8, err: std.posix.system.E) std.posix.UnexpectedError {
964
- log.scoped(.stdx).err("unexpected errno: {s}: code={d} name={?s}", .{
965
- label,
966
- @intFromEnum(err),
967
- std.enums.tagName(std.posix.system.E, err),
968
- });
969
-
970
- if (builtin.mode == .Debug) {
971
- std.debug.dumpCurrentStackTrace(null);
972
- }
973
- return error.Unexpected;
974
- }
975
-
976
- pub fn unique_u128() u128 {
977
- const value = std.crypto.random.int(u128);
978
-
979
- // Broken CSPRNG is the likeliest explanation for zero or all ones.
980
- assert(value != 0);
981
- assert(value != std.math.maxInt(u128));
982
-
983
- return value;
984
- }
985
-
986
- /// NB: intended for parsing CLI arguments where we care to preserve the user-specified unit.
987
- /// Use `size: u64` for all other use-cases.
988
- pub const ByteSize = struct {
989
- value: u64,
990
- unit: Unit = .bytes,
991
-
992
- const Unit = enum(u64) {
993
- bytes = 1,
994
- kib = KiB,
995
- mib = MiB,
996
- gib = GiB,
997
- tib = TiB,
998
- };
999
-
1000
- pub fn parse_flag_value(
1001
- string: []const u8,
1002
- static_diagnostic: *?[]const u8,
1003
- ) error{InvalidFlagValue}!ByteSize {
1004
- assert(string.len != 0);
1005
-
1006
- const split_index = for (string, 0..) |c, index| {
1007
- if (std.ascii.isDigit(c) or c == '_') {
1008
- // Numeric part continues.
1009
- } else break index;
1010
- } else string.len;
1011
-
1012
- const string_amount = string[0..split_index];
1013
- const string_unit = string[split_index..];
1014
- maybe(string_amount.len == 0);
1015
- maybe(string_unit.len == 0);
1016
-
1017
- const amount = std.fmt.parseUnsigned(u64, string_amount, 10) catch |err| switch (err) {
1018
- error.Overflow => {
1019
- static_diagnostic.* = "value exceeds 64-bit unsigned integer:";
1020
- return error.InvalidFlagValue;
1021
- },
1022
- error.InvalidCharacter => {
1023
- static_diagnostic.* = "expected a size, but found:";
1024
- return error.InvalidFlagValue;
1025
- },
1026
- };
1027
-
1028
- const unit = if (string_unit.len == 0)
1029
- .bytes
1030
- else inline for (comptime std.enums.values(Unit)) |tag| {
1031
- if (std.ascii.eqlIgnoreCase(string_unit, @tagName(tag))) break tag;
1032
- } else {
1033
- static_diagnostic.* = "invalid unit in size, needed KiB, MiB, GiB or TiB:";
1034
- return error.InvalidFlagValue;
1035
- };
1036
-
1037
- _ = std.math.mul(u64, amount, @intFromEnum(unit)) catch {
1038
- static_diagnostic.* = "size in bytes exceeds 64-bit unsigned integer:";
1039
- return error.InvalidFlagValue;
1040
- };
1041
-
1042
- return .{ .value = amount, .unit = unit };
1043
- }
1044
-
1045
- pub fn bytes(size: *const ByteSize) u64 {
1046
- return std.math.mul(
1047
- u64,
1048
- size.value,
1049
- @intFromEnum(size.unit),
1050
- ) catch unreachable;
1051
- }
1052
-
1053
- pub fn suffix(size: *const ByteSize) []const u8 {
1054
- return switch (size.unit) {
1055
- .bytes => "",
1056
- .kib => "KiB",
1057
- .mib => "MiB",
1058
- .gib => "GiB",
1059
- .tib => "TiB",
1060
- };
1061
- }
1062
- };
1063
-
1064
- test "ByteSize.parse_flag_value" {
1065
- try parse_flag_value_fuzz(ByteSize, ByteSize.parse_flag_value, .{
1066
- .ok = &.{
1067
- .{ "0", .{ .value = 0, .unit = .bytes } },
1068
- .{ "1", .{ .value = 1, .unit = .bytes } },
1069
-
1070
- .{ "140737488355328", .{ .value = 140737488355328, .unit = .bytes } },
1071
- .{ "128TiB", .{ .value = 128, .unit = .tib } },
1072
- .{ "1TiB", .{ .value = 1, .unit = .tib } },
1073
- .{ "10tib", .{ .value = 10, .unit = .tib } },
1074
- .{ "1GiB", .{ .value = 1, .unit = .gib } },
1075
- .{ "10gib", .{ .value = 10, .unit = .gib } },
1076
- .{ "1MiB", .{ .value = 1, .unit = .mib } },
1077
- .{ "10mib", .{ .value = 10, .unit = .mib } },
1078
- .{ "1KiB", .{ .value = 1, .unit = .kib } },
1079
- .{ "10kib", .{ .value = 10, .unit = .kib } },
1080
- .{ "1_0kib", .{ .value = 10, .unit = .kib } },
1081
- },
1082
- .err = &.{
1083
- .{ "18446744073709551616", "value exceeds 64-bit unsigned integer" },
1084
- .{ "MiB", "expected a size, but found" },
1085
- .{ "_MiB", "expected a size" },
1086
- .{ "10bananas", "invalid unit in size, needed KiB, MiB, GiB or TiB" },
1087
- .{ "10GB", "invalid unit in size" },
1088
- .{ "18446744073709551GiB", "size in bytes exceeds 64-bit unsigned integer" },
1089
- },
1090
- });
1091
- }
1092
-
1093
- // Fast alternative to modulo reduction (Note, it is not the same as modulo).
1094
- // See https://github.com/lemire/fastrange/ and
1095
- // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
1096
- pub inline fn fastrange(word: u64, p: u64) u64 {
1097
- const lword: u128 = @intCast(word);
1098
- const lp: u128 = @intCast(p);
1099
- const ln: u128 = lword *% lp;
1100
- return @truncate(ln >> 64);
1101
- }
1102
-
1103
- // For Zig 14.1 the compiler generates branchless code as is: https://godbolt.org/z/hc563WPKP
1104
- pub inline fn branchless_select(comptime T: type, flag: bool, a: T, b: T) T {
1105
- @branchHint(.unpredictable);
1106
- return if (flag) a else b;
1107
- }
1108
-
1109
- const snap = Snap.snap_fn("src/stdx");
1110
-
1111
- test fastrange {
1112
- var prng = PRNG.from_seed(42);
1113
- var distribution: [8]u32 = @splat(0);
1114
- for (0..10_000) |_| {
1115
- const key = prng.int(u64);
1116
- distribution[fastrange(key, 8)] += 1;
1117
- }
1118
- try snap(@src(),
1119
- \\{ 1263, 1273, 1244, 1226, 1228, 1276, 1169, 1321 }
1120
- ).diff_fmt("{d}", .{distribution});
1121
- }
1122
-
1123
- // This test shows that fastrange is not equivalent to modulo, but rather an alternative method.
1124
- // It is best used uniformly distributed hashes or random numbers across the full range.
1125
- test "fastrange not modulo" {
1126
- var distribution: [8]u32 = @splat(0);
1127
- for (0..10_000) |key| {
1128
- distribution[fastrange(key, 8)] += 1;
1129
- }
1130
- try snap(@src(),
1131
- \\{ 10000, 0, 0, 0, 0, 0, 0, 0 }
1132
- ).diff_fmt("{d}", .{distribution});
1133
- }
1134
-
1135
- /// `status` is a waitpid() status result.
1136
- pub fn term_from_status(status: u32) std.process.Child.Term {
1137
- const Term = std.process.Child.Term;
1138
- return if (std.posix.W.IFEXITED(status))
1139
- Term{ .Exited = std.posix.W.EXITSTATUS(status) }
1140
- else if (std.posix.W.IFSIGNALED(status))
1141
- Term{ .Signal = std.posix.W.TERMSIG(status) }
1142
- else if (std.posix.W.IFSTOPPED(status))
1143
- Term{ .Stopped = std.posix.W.STOPSIG(status) }
1144
- else
1145
- Term{ .Unknown = status };
1146
- }
1147
-
1148
- comptime {
1149
- _ = @import("huge_page_allocator.zig");
1150
- _ = @import("vendored/aegis.zig");
1151
- _ = @import("bit_set.zig");
1152
- _ = @import("bounded_array.zig");
1153
- _ = @import("flags.zig");
1154
- _ = @import("prng.zig");
1155
- _ = @import("radix.zig");
1156
- _ = @import("ring_buffer.zig");
1157
- _ = @import("sort_test.zig");
1158
- _ = @import("stdx.zig");
1159
- _ = @import("testing/snaptest.zig");
1160
- _ = @import("time_units.zig");
1161
- _ = @import("unshare.zig");
1162
- _ = @import("zipfian.zig");
1163
- }