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,1034 +0,0 @@
1
- const std = @import("std");
2
- const assert = std.debug.assert;
3
-
4
- const vsr = @import("vsr.zig");
5
- const stdx = vsr.stdx;
6
- const constants = vsr.constants;
7
- const IO = vsr.io.IO;
8
- const Time = vsr.time.Time;
9
- const StaticAllocator = @import("static_allocator.zig");
10
- const MessagePool = vsr.message_pool.MessagePool;
11
- const RingBufferType = stdx.RingBufferType;
12
- const tb = vsr.tigerbeetle;
13
-
14
- const Terminal = @import("repl/terminal.zig").Terminal;
15
- const Completion = @import("repl/completion.zig").Completion;
16
- const Parser = @import("repl/parser.zig").Parser;
17
-
18
- const repl_history_entries = 256;
19
- const repl_history_entry_bytes_with_nul = 512;
20
- const repl_history_entry_bytes_without_nul = 511;
21
-
22
- const ReplBufferBoundedArray = stdx.BoundedArrayType(u8, repl_history_entry_bytes_without_nul);
23
-
24
- pub fn ReplType(comptime MessageBus: type) type {
25
- const Client = vsr.ClientType(tb.Operation, MessageBus);
26
-
27
- // Requires 512 * 256 == 128KiB of stack space.
28
- const HistoryBuffer = RingBufferType(
29
- [repl_history_entry_bytes_with_nul]u8,
30
- .{ .array = repl_history_entries },
31
- );
32
-
33
- return struct {
34
- event_loop_done: bool,
35
- request_done: bool,
36
-
37
- interactive: bool,
38
- debug_logs: bool,
39
-
40
- client: Client,
41
- terminal: Terminal,
42
- completion: Completion,
43
- history: HistoryBuffer,
44
-
45
- /// Fixed-capacity buffer for reading input strings.
46
- buffer: ReplBufferBoundedArray,
47
- /// Saved input string while navigating through history.
48
- buffer_outside_history: ReplBufferBoundedArray,
49
-
50
- arguments: std.ArrayListUnmanaged(u8),
51
- message_pool: *MessagePool,
52
- io: *IO,
53
-
54
- static_allocator: StaticAllocator,
55
-
56
- const Repl = @This();
57
-
58
- fn fail(repl: *const Repl, comptime format: []const u8, arguments: anytype) !void {
59
- if (!repl.interactive) {
60
- try repl.terminal.print_error(format, arguments);
61
- std.process.exit(1);
62
- }
63
-
64
- try repl.terminal.print(format, arguments);
65
- }
66
-
67
- fn debug(repl: *const Repl, comptime format: []const u8, arguments: anytype) !void {
68
- if (repl.debug_logs) {
69
- try repl.terminal.print("[Debug] " ++ format, arguments);
70
- }
71
- }
72
-
73
- fn do_statement(
74
- repl: *Repl,
75
- statement: Parser.Statement,
76
- ) !void {
77
- try repl.debug("Running command: {}.\n", .{statement.operation});
78
- switch (statement.operation) {
79
- .none => {
80
- // No input was parsed.
81
- try repl.debug("No command was parsed, continuing.\n", .{});
82
- },
83
- .help => {
84
- try repl.display_help();
85
- },
86
-
87
- .create_accounts,
88
- .create_transfers,
89
- .lookup_accounts,
90
- .lookup_transfers,
91
- .get_account_transfers,
92
- .get_account_balances,
93
- .query_accounts,
94
- .query_transfers,
95
- => |operation| {
96
- const state_machine_operation = operation.state_machine_op();
97
- try repl.send(
98
- state_machine_operation,
99
- statement.arguments,
100
- );
101
- },
102
- }
103
- }
104
-
105
- const prompt = "> ";
106
-
107
- fn read_until_newline_or_eof(
108
- repl: *Repl,
109
- ) !?[]const u8 {
110
- repl.buffer.clear();
111
- repl.buffer_outside_history.clear();
112
-
113
- try repl.terminal.prompt_mode_set();
114
- defer repl.terminal.prompt_mode_unset() catch {};
115
-
116
- var terminal_screen = try repl.terminal.get_screen();
117
-
118
- var buffer_index: usize = 0;
119
- var history_index = repl.history.count;
120
-
121
- var current_completion: []const u8 = "";
122
-
123
- while (true) {
124
- const user_input = try repl.terminal.read_user_input() orelse return null;
125
-
126
- // Clear the completion menu when a match is selected or another key is pressed.
127
- if (user_input != .tab and repl.completion.count() > 0) {
128
- repl.completion.clear();
129
- try repl.terminal.print("\x1b[{};1H\x1b[J\x1b[{};{}H", .{
130
- terminal_screen.cursor_row + 1,
131
- terminal_screen.cursor_row,
132
- terminal_screen.cursor_column,
133
- });
134
- }
135
-
136
- switch (user_input) {
137
- .ctrld => {
138
- if (repl.buffer.count() == 0 and buffer_index == 0) {
139
- return null;
140
- }
141
- if (buffer_index < repl.buffer.count()) {
142
- try repl.terminal.print("\x1b[{};{}H{s}\x20\x1b[{};{}H", .{
143
- terminal_screen.cursor_row,
144
- terminal_screen.cursor_column,
145
- repl.buffer.const_slice()[buffer_index + 1 ..],
146
- terminal_screen.cursor_row,
147
- terminal_screen.cursor_column,
148
- });
149
- _ = repl.buffer.ordered_remove(buffer_index);
150
- }
151
- },
152
- .ctrlc => {
153
- // Move to end of line, print "^C" and abort the command.
154
- const position_end_diff = @as(
155
- isize,
156
- @intCast(repl.buffer.count() - buffer_index),
157
- );
158
- terminal_screen.update_cursor_position(position_end_diff);
159
- try repl.terminal.print("\x1b[{};{}H", .{
160
- terminal_screen.cursor_row,
161
- terminal_screen.cursor_column,
162
- });
163
- try repl.terminal.print("^C\n", .{});
164
- repl.buffer.clear();
165
- return &.{};
166
- },
167
- .newline => {
168
- // Move to end of buffer, then return.
169
- const position_end_diff = @as(
170
- isize,
171
- @intCast(repl.buffer.count() - buffer_index),
172
- );
173
- terminal_screen.update_cursor_position(position_end_diff);
174
- try repl.terminal.print("\x1b[{};{}H", .{
175
- terminal_screen.cursor_row,
176
- terminal_screen.cursor_column,
177
- });
178
- try repl.terminal.print("\n", .{});
179
- return repl.buffer.const_slice();
180
- },
181
- .printable => |character| {
182
- if (repl.buffer.count() == repl_history_entry_bytes_without_nul) {
183
- continue;
184
- }
185
-
186
- const is_append = buffer_index == repl.buffer.count();
187
- if (is_append) {
188
- terminal_screen.update_cursor_position(1);
189
- try repl.terminal.print("{c}", .{character});
190
- // Some terminals may not automatically move/scroll us down to the next
191
- // row after appending a character at the last column. This can cause us
192
- // to incorrectly report the cursor's position, so we force the terminal
193
- // to do so by moving the cursor forward and backward one space.
194
- if (terminal_screen.cursor_column == terminal_screen.columns) {
195
- try repl.terminal.print("\x20\x1b[{};{}H", .{
196
- terminal_screen.cursor_row,
197
- terminal_screen.cursor_column,
198
- });
199
- }
200
- } else {
201
- // If we're inserting mid-buffer, we need to redraw everything that
202
- // comes after as well. We'll track as if the cursor moved to the end of
203
- // the buffer after redrawing, and move it back to one position after
204
- // the newly inserted character.
205
- const buffer_redraw_len: isize = @intCast(
206
- repl.buffer.count() - buffer_index,
207
- );
208
- // It's crucial to update in two steps because the terminal may have
209
- // scrolled down as part of the text redraw.
210
- terminal_screen.update_cursor_position(buffer_redraw_len);
211
- terminal_screen.update_cursor_position(1 - buffer_redraw_len);
212
- try repl.terminal.print("{c}{s}\x1b[{};{}H", .{
213
- character,
214
- repl.buffer.const_slice()[buffer_index..],
215
- terminal_screen.cursor_row,
216
- terminal_screen.cursor_column,
217
- });
218
- }
219
-
220
- repl.buffer.insert_at(buffer_index, character);
221
- buffer_index += 1;
222
- },
223
- .backspace => if (buffer_index > 0) {
224
- terminal_screen.update_cursor_position(-1);
225
- // Move to new position, write the remaining buffer,
226
- // write a space (\x20) to overwrite the last character,
227
- // then move back to the new position.
228
- try repl.terminal.print("\x1b[{};{}H{s}\x20\x1b[{};{}H", .{
229
- terminal_screen.cursor_row,
230
- terminal_screen.cursor_column,
231
- // If we're deleting mid-buffer, we need to redraw everything that
232
- // comes after as well.
233
- if (buffer_index < repl.buffer.count())
234
- repl.buffer.const_slice()[buffer_index..]
235
- else
236
- "",
237
- terminal_screen.cursor_row,
238
- terminal_screen.cursor_column,
239
- });
240
- buffer_index -= 1;
241
- _ = repl.buffer.ordered_remove(buffer_index);
242
- },
243
- .delete => if (buffer_index < repl.buffer.count()) {
244
- try repl.terminal.print("\x1b[{};{}H{s}\x20\x1b[{};{}H", .{
245
- terminal_screen.cursor_row,
246
- terminal_screen.cursor_column,
247
- repl.buffer.const_slice()[buffer_index + 1 ..],
248
- terminal_screen.cursor_row,
249
- terminal_screen.cursor_column,
250
- });
251
- _ = repl.buffer.ordered_remove(buffer_index);
252
- },
253
- .tab => {
254
- try repl.completion.split_and_complete(repl.buffer.slice(), buffer_index);
255
-
256
- current_completion = try repl.completion.get_next_completion();
257
-
258
- // Skip the current completion entry if adding it would overflow the buffer.
259
- if ((repl.completion.prefix.count() + repl.completion.suffix.count() +
260
- current_completion.len) >= repl_history_entry_bytes_without_nul)
261
- {
262
- continue;
263
- }
264
-
265
- // Move cursor to the start of the current row, clear the screen from start
266
- // to end. Then print the leading buffer, currently selected completion and
267
- // trailing buffer(if any).
268
- terminal_screen.update_cursor_position(-@as(isize, @intCast(buffer_index)));
269
-
270
- const buffer_row = terminal_screen.cursor_row;
271
-
272
- terminal_screen.update_cursor_position(
273
- @as(
274
- isize,
275
- @intCast(repl.completion.prefix.count() + current_completion.len),
276
- ),
277
- );
278
-
279
- // \x1b[n;mH - Moves the cursor to row n, column m.
280
- // \x1b[J - Clear the screen from current cursor position to end.
281
- try repl.terminal.print("\x1b[{};1H\x1b[J{s}{s}{s}{s}\x20\x08", .{
282
- buffer_row,
283
- prompt,
284
- repl.completion.prefix.const_slice(),
285
- current_completion,
286
- repl.completion.suffix.const_slice(),
287
- });
288
-
289
- // When cursor reaches the last row of terminal, scroll content upward
290
- // to create space for displaying completion menu.
291
- // \x1b[nS - Scroll whole page up by n lines; default 1 line.
292
- // \x1b[nA - Moves cursor up n cells; default 1 cell up.
293
- if (terminal_screen.cursor_row == terminal_screen.rows) {
294
- try repl.terminal.print("\x1b[S\x1b[A", .{});
295
- }
296
-
297
- // Position cursor for completion menu. If the current buffer overflows to
298
- // the next line after printing the prefix, selected completion and suffix,
299
- // the completion menu should effectively be placed `row_delta` lines below
300
- // the current buffer row.
301
- const buffer_width =
302
- repl.completion.prefix.count() +
303
- repl.completion.suffix.count() +
304
- current_completion.len + 1;
305
- const row_delta = @divFloor(buffer_width, terminal_screen.columns) + 1;
306
- try repl.terminal.print("\x1b[{};1H", .{buffer_row + row_delta});
307
-
308
- // Display completion menu in the next line and highlight the currently
309
- // selected completion.
310
- var menu_width: usize = 0;
311
- var match_itr = repl.completion.matches.iterator();
312
-
313
- while (match_itr.next()) |match| {
314
- const match_len = std.mem.indexOfScalar(u8, match[0..], '\x00').?;
315
- menu_width += match_len + 2;
316
-
317
- // \x1b[7m - Highlights the text by inverting the color. Inverts
318
- // the text and background color.
319
- // \x1b[0m - Reset the style property of text. In this case, resets
320
- // the effect of \x1b[7m - color inversion.
321
- if (std.mem.eql(u8, match[0..match_len], current_completion)) {
322
- try repl.terminal.print("\x20\x1b[7m{s}\x1b[0m\x20", .{
323
- match[0..match_len],
324
- });
325
- } else {
326
- try repl.terminal.print("\x20{s}\x20", .{match[0..match_len]});
327
- }
328
- }
329
-
330
- // If the completion menu overflows past the last row of terminal screen,
331
- // move the cursor up by number of rows that would be overflown.
332
- const menu_rows = @divFloor(menu_width, terminal_screen.columns) + 1;
333
- const required_rows = terminal_screen.cursor_row + menu_rows;
334
- const overflow_rows = @as(
335
- isize,
336
- @intCast(required_rows),
337
- ) - @as(
338
- isize,
339
- @intCast(terminal_screen.rows),
340
- );
341
- if (overflow_rows > 0) {
342
- terminal_screen.update_cursor_position(
343
- -@as(isize, @intCast(terminal_screen.columns)) * overflow_rows,
344
- );
345
- }
346
-
347
- try repl.terminal.print("\x1b[{};{}H", .{
348
- terminal_screen.cursor_row,
349
- terminal_screen.cursor_column,
350
- });
351
-
352
- // Re-fill the buffer with prefix, current match and suffix. Set the
353
- // buffer index where the current selected match ends.
354
- repl.buffer.clear();
355
- repl.buffer.push_slice(repl.completion.prefix.slice());
356
- repl.buffer.push_slice(current_completion);
357
- repl.buffer.push_slice(repl.completion.suffix.slice());
358
- buffer_index = repl.buffer.count() - repl.completion.suffix.count();
359
- },
360
- .left, .ctrlb => if (buffer_index > 0) {
361
- terminal_screen.update_cursor_position(-1);
362
- try repl.terminal.print("\x1b[{};{}H", .{
363
- terminal_screen.cursor_row,
364
- terminal_screen.cursor_column,
365
- });
366
- buffer_index -= 1;
367
- },
368
- .right, .ctrlf => if (buffer_index < repl.buffer.count()) {
369
- terminal_screen.update_cursor_position(1);
370
- try repl.terminal.print("\x1b[{};{}H", .{
371
- terminal_screen.cursor_row,
372
- terminal_screen.cursor_column,
373
- });
374
- buffer_index += 1;
375
- },
376
- .up, .ctrlp => if (history_index > 0) {
377
- const history_index_next = history_index - 1;
378
- const buffer_next_full = repl.history.get_ptr(history_index_next).?;
379
- const buffer_next = std.mem.sliceTo(buffer_next_full, '\x00');
380
- assert(buffer_next.len < repl_history_entry_bytes_with_nul);
381
-
382
- // Move to the beginning of the current buffer.
383
- terminal_screen.update_cursor_position(
384
- -@as(isize, @intCast(buffer_index)),
385
- );
386
- const row_current_buffer_start = terminal_screen.cursor_row;
387
-
388
- // Move to the end of the new buffer.
389
- terminal_screen.update_cursor_position(
390
- @as(isize, @intCast(buffer_next.len)),
391
- );
392
-
393
- try repl.terminal.print("\x1b[{};1H\x1b[J{s}{s}\x20\x1b[{};{}H", .{
394
- row_current_buffer_start,
395
- prompt,
396
- buffer_next,
397
- terminal_screen.cursor_row,
398
- terminal_screen.cursor_column,
399
- });
400
-
401
- if (history_index == repl.history.count) {
402
- repl.buffer_outside_history.clear();
403
- repl.buffer_outside_history.push_slice(repl.buffer.const_slice());
404
- }
405
- history_index = history_index_next;
406
-
407
- repl.buffer.clear();
408
- repl.buffer.push_slice(buffer_next);
409
- buffer_index = repl.buffer.count();
410
- },
411
- .down, .ctrln => if (history_index < repl.history.count) {
412
- const history_index_next = history_index + 1;
413
-
414
- const buffer_next = if (history_index_next == repl.history.count)
415
- repl.buffer_outside_history.const_slice()
416
- else brk: {
417
- const buffer_next_full = repl.history.get_ptr(history_index_next).?;
418
- const buffer_next = std.mem.sliceTo(buffer_next_full, '\x00');
419
- assert(buffer_next.len < repl_history_entry_bytes_with_nul);
420
- break :brk buffer_next;
421
- };
422
-
423
- history_index = history_index_next;
424
-
425
- // Move to the beginning of the current buffer.
426
- terminal_screen.update_cursor_position(
427
- -@as(isize, @intCast(buffer_index)),
428
- );
429
- const row_current_buffer_start = terminal_screen.cursor_row;
430
-
431
- // Move to the end of the new buffer.
432
- terminal_screen.update_cursor_position(
433
- @as(isize, @intCast(buffer_next.len)),
434
- );
435
-
436
- try repl.terminal.print("\x1b[{};1H\x1b[J{s}{s}\x20\x1b[{};{}H", .{
437
- row_current_buffer_start,
438
- prompt,
439
- buffer_next,
440
- terminal_screen.cursor_row,
441
- terminal_screen.cursor_column,
442
- });
443
-
444
- repl.buffer.clear();
445
- repl.buffer.push_slice(buffer_next);
446
- buffer_index = repl.buffer.count();
447
- },
448
- .altf, .ctrlright => {
449
- const forward = move_forward_by_word(repl.buffer.slice(), buffer_index);
450
- terminal_screen.update_cursor_position(
451
- @as(isize, @intCast(forward - buffer_index)),
452
- );
453
- try repl.terminal.print("\x1b[{};{}H", .{
454
- terminal_screen.cursor_row,
455
- terminal_screen.cursor_column,
456
- });
457
- buffer_index = forward;
458
- },
459
- .altb, .ctrlleft => {
460
- const backward = move_backward_by_word(repl.buffer.slice(), buffer_index);
461
- terminal_screen.update_cursor_position(
462
- -@as(isize, @intCast(buffer_index - backward)),
463
- );
464
- try repl.terminal.print("\x1b[{};{}H", .{
465
- terminal_screen.cursor_row,
466
- terminal_screen.cursor_column,
467
- });
468
- buffer_index = backward;
469
- },
470
- .ctrla, .home => {
471
- // Move to start of line.
472
- const position_start_diff = -@as(isize, @intCast(buffer_index));
473
- terminal_screen.update_cursor_position(position_start_diff);
474
- try repl.terminal.print("\x1b[{};{}H", .{
475
- terminal_screen.cursor_row,
476
- terminal_screen.cursor_column,
477
- });
478
- buffer_index = 0;
479
- },
480
- .ctrle, .end => {
481
- // Move to end of line.
482
- const position_end_diff = @as(
483
- isize,
484
- @intCast(repl.buffer.count() - buffer_index),
485
- );
486
- terminal_screen.update_cursor_position(position_end_diff);
487
- try repl.terminal.print("\x1b[{};{}H", .{
488
- terminal_screen.cursor_row,
489
- terminal_screen.cursor_column,
490
- });
491
- buffer_index = repl.buffer.count();
492
- },
493
- .ctrlk => {
494
- // Clear screen from cursor.
495
- try repl.terminal.print("\x1b[J", .{});
496
- repl.buffer.resize(buffer_index) catch unreachable;
497
- },
498
- .ctrll => {
499
- // Move to 0,0 and clear the screen from cursor, print the prompt, then ask
500
- // the terminal for the new position.
501
- try repl.terminal.print("\x1b[0;0H\x1b[J", .{});
502
- try repl.terminal.print(prompt, .{});
503
- terminal_screen = try repl.terminal.get_screen();
504
-
505
- // Print whatever is in the buffer and move the cursor back to buffer_index.
506
- terminal_screen.update_cursor_position(
507
- @as(isize, @intCast(buffer_index)),
508
- );
509
-
510
- try repl.terminal.print("{s}\x1b[{};{}H", .{
511
- repl.buffer.const_slice(),
512
- terminal_screen.cursor_row,
513
- terminal_screen.cursor_column,
514
- });
515
- },
516
- .unhandled => {},
517
- }
518
- }
519
- unreachable;
520
- }
521
-
522
- fn move_forward_by_word(buffer: []const u8, buffer_index: usize) usize {
523
- var cur_pos = buffer_index;
524
- while (cur_pos < buffer.len and std.ascii.isWhitespace(buffer[cur_pos])) {
525
- cur_pos += 1;
526
- }
527
- while (cur_pos < buffer.len and !std.ascii.isWhitespace(buffer[cur_pos])) {
528
- cur_pos += 1;
529
- }
530
- return cur_pos;
531
- }
532
-
533
- fn move_backward_by_word(buffer: []const u8, buffer_index: usize) usize {
534
- var cur_pos = buffer_index;
535
- while (cur_pos > 0 and std.ascii.isWhitespace(buffer[cur_pos - 1])) {
536
- cur_pos -= 1;
537
- }
538
- while (cur_pos > 0 and !std.ascii.isWhitespace(buffer[cur_pos - 1])) {
539
- cur_pos -= 1;
540
- }
541
- return cur_pos;
542
- }
543
-
544
- fn do_repl(
545
- repl: *Repl,
546
- arguments: *std.ArrayListUnmanaged(u8),
547
- ) !void {
548
- try repl.terminal.print(prompt, .{});
549
- const input = repl.read_until_newline_or_eof() catch |err| {
550
- repl.event_loop_done = true;
551
- return err;
552
- } orelse {
553
- // EOF.
554
- repl.event_loop_done = true;
555
- try repl.fail("\nExiting.\n", .{});
556
- return;
557
- };
558
-
559
- if (input.len > 0) {
560
- const add_to_history = brk: {
561
- const last_entry = repl.history.tail_ptr_const() orelse break :brk true;
562
- const last_entry_str = std.mem.sliceTo(last_entry, '\x00');
563
- break :brk !std.mem.eql(u8, last_entry_str, input);
564
- };
565
-
566
- if (add_to_history) {
567
- // NB: Avoiding big stack allocations below.
568
-
569
- assert(input.len < repl_history_entry_bytes_with_nul);
570
-
571
- if (repl.history.full()) {
572
- repl.history.advance_head();
573
- }
574
- const history_tail: *[repl_history_entry_bytes_with_nul]u8 =
575
- repl.history.next_tail_ptr().?;
576
- @memset(history_tail, '\x00');
577
- stdx.copy_left(.inexact, u8, history_tail, input);
578
- repl.history.advance_tail();
579
- }
580
- }
581
-
582
- const statement = Parser.parse_statement(
583
- input,
584
- &repl.terminal,
585
- arguments,
586
- ) catch |err| {
587
- switch (err) {
588
- // These are parsing errors, so the REPL should
589
- // not continue to execute this statement but can
590
- // still accept new statements.
591
- Parser.Error.IdentifierBad,
592
- Parser.Error.OperationBad,
593
- Parser.Error.ValueBad,
594
- Parser.Error.KeyValuePairBad,
595
- Parser.Error.KeyValuePairEqualMissing,
596
- Parser.Error.SyntaxMatchNone,
597
- Parser.Error.SliceOperationUnsupported,
598
- // TODO(zig): This will be more convenient to express
599
- // once https://github.com/ziglang/zig/issues/2473 is
600
- // in.
601
- => return,
602
-
603
- // An unexpected error for which we do
604
- // want the stacktrace.
605
- error.AccessDenied,
606
- error.BrokenPipe,
607
- error.ConnectionResetByPeer,
608
- error.DeviceBusy,
609
- error.DiskQuota,
610
- error.FileTooBig,
611
- error.InputOutput,
612
- error.InvalidArgument,
613
- error.LockViolation,
614
- error.NoSpaceLeft,
615
- error.NotOpenForWriting,
616
- error.OperationAborted,
617
- error.OutOfMemory,
618
- error.SystemResources,
619
- error.Unexpected,
620
- error.WouldBlock,
621
- error.NoDevice,
622
- error.ProcessNotFound,
623
- => return err,
624
- }
625
- };
626
- try repl.do_statement(statement);
627
- }
628
-
629
- fn display_help(repl: *Repl) !void {
630
- try repl.terminal.print("TigerBeetle CLI Client {}\n" ++
631
- \\ Hit enter after a semicolon to run a command.
632
- \\ Ctrl+D to exit.
633
- \\
634
- \\Examples:
635
- \\ create_accounts id=1 code=10 ledger=700 flags=linked|history, id=2 code=10 ledger=700;
636
- \\ create_transfers id=1 debit_account_id=1 credit_account_id=2 amount=10 ledger=700 code=10;
637
- \\ lookup_accounts id=1;
638
- \\ lookup_accounts id=1, id=2;
639
- \\ get_account_transfers account_id=1 flags=debits|credits;
640
- \\ get_account_balances account_id=1 flags=debits|credits;
641
- \\
642
- \\
643
- , .{constants.semver});
644
- }
645
-
646
- pub fn init(
647
- parent_allocator: std.mem.Allocator,
648
- io: *IO,
649
- time: Time,
650
- options: struct {
651
- addresses: []const std.net.Address,
652
- cluster_id: u128,
653
- verbose: bool,
654
- },
655
- ) !Repl {
656
- var static_allocator = StaticAllocator.init(parent_allocator);
657
- const allocator = static_allocator.allocator();
658
-
659
- var arguments = try std.ArrayListUnmanaged(u8).initCapacity(
660
- allocator,
661
- constants.message_body_size_max,
662
- );
663
- errdefer arguments.deinit(allocator);
664
-
665
- var message_pool = try allocator.create(MessagePool);
666
- errdefer allocator.destroy(message_pool);
667
-
668
- message_pool.* = try MessagePool.init(allocator, .client);
669
- errdefer message_pool.deinit(allocator);
670
-
671
- const client_id = stdx.unique_u128();
672
- const client = try Client.init(
673
- allocator,
674
- time,
675
- message_pool,
676
- .{
677
- .id = client_id,
678
- .cluster = options.cluster_id,
679
- .replica_count = @intCast(options.addresses.len),
680
- .aof_recovery = false,
681
- .message_bus_options = .{
682
- .configuration = options.addresses,
683
- .io = io,
684
- .trace = null,
685
- },
686
- },
687
- );
688
- errdefer client.deinit(allocator);
689
-
690
- // Disable all dynamic allocation from this point onwards.
691
- static_allocator.transition_from_init_to_static();
692
-
693
- return .{
694
- .client = client,
695
- .debug_logs = options.verbose,
696
- .request_done = true,
697
- .event_loop_done = false,
698
- .interactive = false,
699
- .terminal = undefined, // Init on run.
700
- .completion = undefined, // Init on run.
701
- .history = HistoryBuffer.init(), // No corresponding deinit.
702
- .buffer = .{},
703
- .buffer_outside_history = .{},
704
- .arguments = arguments,
705
- .message_pool = message_pool,
706
- .io = io,
707
- .static_allocator = static_allocator,
708
- };
709
- }
710
-
711
- pub fn deinit(repl: *Repl, allocator: std.mem.Allocator) void {
712
- repl.static_allocator.transition_from_static_to_deinit();
713
-
714
- repl.client.deinit(allocator);
715
- repl.message_pool.deinit(allocator);
716
- allocator.destroy(repl.message_pool);
717
- repl.arguments.deinit(allocator);
718
- }
719
-
720
- pub fn run(repl: *Repl, statements: []const u8) !void {
721
- repl.interactive = statements.len == 0;
722
- try Terminal.init(&repl.terminal, repl.interactive); // No corresponding deinit.
723
-
724
- try Completion.init(&repl.completion);
725
-
726
- repl.client.register(register_callback, @intCast(@intFromPtr(repl)));
727
- while (!repl.event_loop_done) {
728
- repl.client.tick();
729
- try repl.io.run_for_ns(constants.tick_ms * std.time.ns_per_ms);
730
- }
731
- repl.event_loop_done = false;
732
-
733
- if (repl.interactive) {
734
- try repl.display_help();
735
- }
736
-
737
- var statements_iterator = if (statements.len > 0)
738
- std.mem.splitScalar(u8, statements, ';')
739
- else
740
- null;
741
-
742
- while (!repl.event_loop_done) {
743
- if (repl.request_done) {
744
- repl.arguments.clearRetainingCapacity();
745
- if (repl.interactive) {
746
- try repl.do_repl(&repl.arguments);
747
- } else blk: {
748
- const statement_string = statements_iterator.?.next() orelse break :blk;
749
-
750
- const statement = Parser.parse_statement(
751
- statement_string,
752
- &repl.terminal,
753
- &repl.arguments,
754
- ) catch |err| {
755
- switch (err) {
756
- // These are parsing errors and since this
757
- // is not an interactive command, we should
758
- // exit immediately. Parsing error info
759
- // has already been emitted to stderr.
760
- Parser.Error.IdentifierBad,
761
- Parser.Error.OperationBad,
762
- Parser.Error.ValueBad,
763
- Parser.Error.KeyValuePairBad,
764
- Parser.Error.KeyValuePairEqualMissing,
765
- Parser.Error.SyntaxMatchNone,
766
- Parser.Error.SliceOperationUnsupported,
767
- // TODO: This will be more convenient to express
768
- // once https://github.com/ziglang/zig/issues/2473 is
769
- // in.
770
- => std.posix.exit(1),
771
-
772
- // An unexpected error for which we do
773
- // want the stacktrace.
774
- error.AccessDenied,
775
- error.BrokenPipe,
776
- error.ConnectionResetByPeer,
777
- error.DeviceBusy,
778
- error.DiskQuota,
779
- error.FileTooBig,
780
- error.InputOutput,
781
- error.InvalidArgument,
782
- error.LockViolation,
783
- error.NoSpaceLeft,
784
- error.NotOpenForWriting,
785
- error.OperationAborted,
786
- error.OutOfMemory,
787
- error.SystemResources,
788
- error.Unexpected,
789
- error.WouldBlock,
790
- error.NoDevice,
791
- error.ProcessNotFound,
792
- => return err,
793
- }
794
- };
795
-
796
- try repl.do_statement(statement);
797
- }
798
- }
799
-
800
- repl.client.tick();
801
- try repl.io.run_for_ns(constants.tick_ms * std.time.ns_per_ms);
802
- }
803
- }
804
-
805
- fn register_callback(
806
- user_data: u128,
807
- result: *const vsr.RegisterResult,
808
- ) void {
809
- _ = result;
810
-
811
- const repl: *Repl = @ptrFromInt(@as(usize, @intCast(user_data)));
812
- assert(!repl.event_loop_done);
813
-
814
- repl.event_loop_done = true;
815
- }
816
-
817
- fn send(
818
- repl: *Repl,
819
- operation: tb.Operation,
820
- arguments: *std.ArrayListUnmanaged(u8),
821
- ) !void {
822
- const operation_type = switch (operation) {
823
- .create_accounts, .create_transfers => "create",
824
- .get_account_transfers, .get_account_balances => "get",
825
- .lookup_accounts, .lookup_transfers => "lookup",
826
- .query_accounts, .query_transfers => "query",
827
- else => unreachable,
828
- };
829
- const object_type = switch (operation) {
830
- .create_accounts, .lookup_accounts, .query_accounts => "accounts",
831
- .create_transfers, .lookup_transfers, .query_transfers => "transfers",
832
- .get_account_transfers => "account transfers",
833
- .get_account_balances => "account balances",
834
- else => unreachable,
835
- };
836
-
837
- if (arguments.items.len == 0) {
838
- try repl.fail(
839
- "No {s} to {s}.\n",
840
- .{ object_type, operation_type },
841
- );
842
- return;
843
- }
844
-
845
- repl.request_done = false;
846
- try repl.debug("Sending command: {}.\n", .{operation});
847
-
848
- const payload_size: u32 = @intCast(arguments.items.len);
849
- const buffer: []u8 = buffer: {
850
- arguments.expandToCapacity();
851
- assert(arguments.items.len == constants.message_body_size_max);
852
- break :buffer arguments.items;
853
- };
854
- var body_encoder = vsr.multi_batch.MultiBatchEncoder.init(buffer, .{
855
- .element_size = operation.event_size(),
856
- });
857
- body_encoder.add(payload_size);
858
- const bytes_written = body_encoder.finish();
859
- assert(bytes_written > 0);
860
-
861
- repl.client.request(
862
- client_request_callback,
863
- @intCast(@intFromPtr(repl)),
864
- operation,
865
- buffer[0..bytes_written],
866
- );
867
- }
868
-
869
- fn display_object(repl: *Repl, object: anytype) !void {
870
- assert(@TypeOf(object.*) == tb.Account or
871
- @TypeOf(object.*) == tb.Transfer or
872
- @TypeOf(object.*) == tb.AccountBalance);
873
-
874
- try repl.terminal.print("{{\n", .{});
875
- inline for (@typeInfo(@TypeOf(object.*)).@"struct".fields, 0..) |object_field, i| {
876
- if (comptime std.mem.eql(u8, object_field.name, "reserved")) {
877
- continue;
878
- // No need to print out reserved.
879
- }
880
-
881
- if (i > 0) {
882
- try repl.terminal.print(",\n", .{});
883
- }
884
-
885
- if (comptime std.mem.eql(u8, object_field.name, "flags")) {
886
- try repl.terminal.print(" \"" ++ object_field.name ++ "\": [", .{});
887
- var needs_comma = false;
888
-
889
- inline for (@typeInfo(object_field.type).@"struct".fields) |flag_field| {
890
- if (comptime !std.mem.eql(u8, flag_field.name, "padding")) {
891
- if (@field(@field(object, "flags"), flag_field.name)) {
892
- if (needs_comma) {
893
- try repl.terminal.print(",", .{});
894
- needs_comma = false;
895
- }
896
-
897
- try repl.terminal.print("\"{s}\"", .{flag_field.name});
898
- needs_comma = true;
899
- }
900
- }
901
- }
902
-
903
- try repl.terminal.print("]", .{});
904
- } else {
905
- try repl.terminal.print(
906
- " \"{s}\": \"{}\"",
907
- .{ object_field.name, @field(object, object_field.name) },
908
- );
909
- }
910
- }
911
- try repl.terminal.print("\n}}\n", .{});
912
- }
913
-
914
- fn client_request_completed(
915
- user_data: u128,
916
- operation: tb.Operation,
917
- timestamp: u64,
918
- result: []const u8,
919
- ) !void {
920
- const repl: *Repl = @ptrFromInt(@as(usize, @intCast(user_data)));
921
- assert(repl.request_done == false);
922
- try repl.debug("Operation completed: {} timestamp={}.\n", .{ operation, timestamp });
923
-
924
- defer {
925
- repl.request_done = true;
926
-
927
- if (!repl.interactive) {
928
- repl.event_loop_done = true;
929
- }
930
- }
931
-
932
- switch (operation) {
933
- .create_accounts => {
934
- const create_account_results = stdx.bytes_as_slice(
935
- .exact,
936
- tb.CreateAccountsResult,
937
- result,
938
- );
939
- if (create_account_results.len > 0) {
940
- for (create_account_results) |*reason| {
941
- try repl.terminal.print(
942
- "Failed to create account ({}): {any}.\n",
943
- .{ reason.index, reason.result },
944
- );
945
- }
946
- }
947
- },
948
- .lookup_accounts, .query_accounts => {
949
- const account_results = stdx.bytes_as_slice(
950
- .exact,
951
- tb.Account,
952
- result,
953
- );
954
- if (account_results.len == 0) {
955
- try repl.fail("No accounts were found.\n", .{});
956
- } else {
957
- for (account_results) |*account| {
958
- try repl.display_object(account);
959
- }
960
- }
961
- },
962
- .create_transfers => {
963
- const create_transfer_results = stdx.bytes_as_slice(
964
- .exact,
965
- tb.CreateTransfersResult,
966
- result,
967
- );
968
- if (create_transfer_results.len > 0) {
969
- for (create_transfer_results) |*reason| {
970
- try repl.terminal.print(
971
- "Failed to create transfer ({}): {any}.\n",
972
- .{ reason.index, reason.result },
973
- );
974
- }
975
- }
976
- },
977
- .lookup_transfers,
978
- .get_account_transfers,
979
- .query_transfers,
980
- => {
981
- const transfer_results = stdx.bytes_as_slice(
982
- .exact,
983
- tb.Transfer,
984
- result,
985
- );
986
- if (transfer_results.len == 0) {
987
- try repl.fail("No transfers were found.\n", .{});
988
- } else {
989
- for (transfer_results) |*transfer| {
990
- try repl.display_object(transfer);
991
- }
992
- }
993
- },
994
- .get_account_balances => {
995
- const get_account_balances_results = stdx.bytes_as_slice(
996
- .exact,
997
- tb.AccountBalance,
998
- result,
999
- );
1000
- if (get_account_balances_results.len == 0) {
1001
- try repl.fail("No balances were found.\n", .{});
1002
- } else {
1003
- for (get_account_balances_results) |*balance| {
1004
- try repl.display_object(balance);
1005
- }
1006
- }
1007
- },
1008
- else => unreachable,
1009
- }
1010
- }
1011
-
1012
- fn client_request_callback(
1013
- user_data: u128,
1014
- operation_vsr: vsr.Operation,
1015
- timestamp: u64,
1016
- result: []u8,
1017
- ) void {
1018
- const operation = operation_vsr.cast(tb.Operation);
1019
- const reply_decoder = vsr.multi_batch.MultiBatchDecoder.init(result, .{
1020
- .element_size = operation.result_size(),
1021
- }) catch unreachable;
1022
- assert(reply_decoder.batch_count() == 1);
1023
- client_request_completed(
1024
- user_data,
1025
- operation,
1026
- timestamp,
1027
- reply_decoder.peek(),
1028
- ) catch |err| {
1029
- const repl: *Repl = @ptrFromInt(@as(usize, @intCast(user_data)));
1030
- repl.fail("Error in callback: {any}", .{err}) catch return;
1031
- };
1032
- }
1033
- };
1034
- }