tigerbeetle 0.0.36 → 0.0.38
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/ext/tb_client/extconf.rb +13 -13
- data/ext/tb_client/tigerbeetle/LICENSE +177 -0
- data/ext/tb_client/tigerbeetle/build.zig +2327 -0
- data/ext/tb_client/tigerbeetle/src/aof.zig +1000 -0
- data/ext/tb_client/tigerbeetle/src/build_multiversion.zig +808 -0
- data/ext/tb_client/tigerbeetle/src/cdc/amqp/protocol.zig +1283 -0
- data/ext/tb_client/tigerbeetle/src/cdc/amqp/spec.zig +1704 -0
- data/ext/tb_client/tigerbeetle/src/cdc/amqp/types.zig +341 -0
- data/ext/tb_client/tigerbeetle/src/cdc/amqp.zig +1450 -0
- data/ext/tb_client/tigerbeetle/src/cdc/runner.zig +1659 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/samples/main.c +406 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/context.zig +1092 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/echo_client.zig +286 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/packet.zig +158 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/signal.zig +229 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client/signal_fuzz.zig +110 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client.h +386 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client.zig +34 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client_exports.zig +281 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client_header.zig +312 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/tb_client_header_test.zig +138 -0
- data/ext/tb_client/tigerbeetle/src/clients/c/test.zig +466 -0
- data/ext/tb_client/tigerbeetle/src/clients/docs_samples.zig +157 -0
- data/ext/tb_client/tigerbeetle/src/clients/docs_types.zig +90 -0
- data/ext/tb_client/tigerbeetle/src/clients/dotnet/ci.zig +203 -0
- data/ext/tb_client/tigerbeetle/src/clients/dotnet/docs.zig +79 -0
- data/ext/tb_client/tigerbeetle/src/clients/dotnet/dotnet_bindings.zig +542 -0
- data/ext/tb_client/tigerbeetle/src/clients/go/ci.zig +109 -0
- data/ext/tb_client/tigerbeetle/src/clients/go/docs.zig +86 -0
- data/ext/tb_client/tigerbeetle/src/clients/go/go_bindings.zig +370 -0
- data/ext/tb_client/tigerbeetle/src/clients/go/pkg/native/tb_client.h +386 -0
- data/ext/tb_client/tigerbeetle/src/clients/java/ci.zig +167 -0
- data/ext/tb_client/tigerbeetle/src/clients/java/docs.zig +126 -0
- data/ext/tb_client/tigerbeetle/src/clients/java/java_bindings.zig +996 -0
- data/ext/tb_client/tigerbeetle/src/clients/java/src/client.zig +748 -0
- data/ext/tb_client/tigerbeetle/src/clients/java/src/jni.zig +3238 -0
- data/ext/tb_client/tigerbeetle/src/clients/java/src/jni_tests.zig +1718 -0
- data/ext/tb_client/tigerbeetle/src/clients/java/src/jni_thread_cleaner.zig +190 -0
- data/ext/tb_client/tigerbeetle/src/clients/node/ci.zig +104 -0
- data/ext/tb_client/tigerbeetle/src/clients/node/docs.zig +75 -0
- data/ext/tb_client/tigerbeetle/src/clients/node/node.zig +522 -0
- data/ext/tb_client/tigerbeetle/src/clients/node/node_bindings.zig +267 -0
- data/ext/tb_client/tigerbeetle/src/clients/node/src/c.zig +3 -0
- data/ext/tb_client/tigerbeetle/src/clients/node/src/translate.zig +379 -0
- data/ext/tb_client/tigerbeetle/src/clients/python/ci.zig +131 -0
- data/ext/tb_client/tigerbeetle/src/clients/python/docs.zig +63 -0
- data/ext/tb_client/tigerbeetle/src/clients/python/python_bindings.zig +588 -0
- data/ext/tb_client/tigerbeetle/src/clients/rust/assets/tb_client.h +386 -0
- data/ext/tb_client/tigerbeetle/src/clients/rust/ci.zig +73 -0
- data/ext/tb_client/tigerbeetle/src/clients/rust/docs.zig +106 -0
- data/ext/tb_client/tigerbeetle/src/clients/rust/rust_bindings.zig +305 -0
- data/ext/tb_client/tigerbeetle/src/config.zig +296 -0
- data/ext/tb_client/tigerbeetle/src/constants.zig +790 -0
- data/ext/tb_client/tigerbeetle/src/copyhound.zig +202 -0
- data/ext/tb_client/tigerbeetle/src/counting_allocator.zig +72 -0
- data/ext/tb_client/tigerbeetle/src/direction.zig +120 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/build.zig +158 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/content.zig +156 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/docs.zig +252 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/file_checker.zig +313 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/html.zig +87 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/page_writer.zig +63 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/redirects.zig +47 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/search_index_writer.zig +28 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/service_worker_writer.zig +61 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/single_page_writer.zig +169 -0
- data/ext/tb_client/tigerbeetle/src/docs_website/src/website.zig +46 -0
- data/ext/tb_client/tigerbeetle/src/ewah.zig +445 -0
- data/ext/tb_client/tigerbeetle/src/ewah_benchmark.zig +128 -0
- data/ext/tb_client/tigerbeetle/src/ewah_fuzz.zig +171 -0
- data/ext/tb_client/tigerbeetle/src/fuzz_tests.zig +179 -0
- data/ext/tb_client/tigerbeetle/src/integration_tests.zig +662 -0
- data/ext/tb_client/tigerbeetle/src/io/common.zig +155 -0
- data/ext/tb_client/tigerbeetle/src/io/darwin.zig +1093 -0
- data/ext/tb_client/tigerbeetle/src/io/linux.zig +1880 -0
- data/ext/tb_client/tigerbeetle/src/io/test.zig +1005 -0
- data/ext/tb_client/tigerbeetle/src/io/windows.zig +1598 -0
- data/ext/tb_client/tigerbeetle/src/io.zig +34 -0
- data/ext/tb_client/tigerbeetle/src/iops.zig +134 -0
- data/ext/tb_client/tigerbeetle/src/list.zig +236 -0
- data/ext/tb_client/tigerbeetle/src/lsm/binary_search.zig +848 -0
- data/ext/tb_client/tigerbeetle/src/lsm/binary_search_benchmark.zig +179 -0
- data/ext/tb_client/tigerbeetle/src/lsm/cache_map.zig +424 -0
- data/ext/tb_client/tigerbeetle/src/lsm/cache_map_fuzz.zig +420 -0
- data/ext/tb_client/tigerbeetle/src/lsm/compaction.zig +2117 -0
- data/ext/tb_client/tigerbeetle/src/lsm/composite_key.zig +182 -0
- data/ext/tb_client/tigerbeetle/src/lsm/forest.zig +1119 -0
- data/ext/tb_client/tigerbeetle/src/lsm/forest_fuzz.zig +1102 -0
- data/ext/tb_client/tigerbeetle/src/lsm/forest_table_iterator.zig +200 -0
- data/ext/tb_client/tigerbeetle/src/lsm/groove.zig +1495 -0
- data/ext/tb_client/tigerbeetle/src/lsm/k_way_merge.zig +739 -0
- data/ext/tb_client/tigerbeetle/src/lsm/k_way_merge_benchmark.zig +166 -0
- data/ext/tb_client/tigerbeetle/src/lsm/manifest.zig +754 -0
- data/ext/tb_client/tigerbeetle/src/lsm/manifest_level.zig +1294 -0
- data/ext/tb_client/tigerbeetle/src/lsm/manifest_level_fuzz.zig +510 -0
- data/ext/tb_client/tigerbeetle/src/lsm/manifest_log.zig +1263 -0
- data/ext/tb_client/tigerbeetle/src/lsm/manifest_log_fuzz.zig +628 -0
- data/ext/tb_client/tigerbeetle/src/lsm/node_pool.zig +247 -0
- data/ext/tb_client/tigerbeetle/src/lsm/scan_buffer.zig +116 -0
- data/ext/tb_client/tigerbeetle/src/lsm/scan_builder.zig +543 -0
- data/ext/tb_client/tigerbeetle/src/lsm/scan_fuzz.zig +938 -0
- data/ext/tb_client/tigerbeetle/src/lsm/scan_lookup.zig +293 -0
- data/ext/tb_client/tigerbeetle/src/lsm/scan_merge.zig +359 -0
- data/ext/tb_client/tigerbeetle/src/lsm/scan_range.zig +99 -0
- data/ext/tb_client/tigerbeetle/src/lsm/scan_state.zig +17 -0
- data/ext/tb_client/tigerbeetle/src/lsm/scan_tree.zig +962 -0
- data/ext/tb_client/tigerbeetle/src/lsm/schema.zig +617 -0
- data/ext/tb_client/tigerbeetle/src/lsm/scratch_memory.zig +84 -0
- data/ext/tb_client/tigerbeetle/src/lsm/segmented_array.zig +1500 -0
- data/ext/tb_client/tigerbeetle/src/lsm/segmented_array_benchmark.zig +149 -0
- data/ext/tb_client/tigerbeetle/src/lsm/segmented_array_fuzz.zig +7 -0
- data/ext/tb_client/tigerbeetle/src/lsm/set_associative_cache.zig +865 -0
- data/ext/tb_client/tigerbeetle/src/lsm/table.zig +607 -0
- data/ext/tb_client/tigerbeetle/src/lsm/table_memory.zig +843 -0
- data/ext/tb_client/tigerbeetle/src/lsm/table_value_iterator.zig +90 -0
- data/ext/tb_client/tigerbeetle/src/lsm/timestamp_range.zig +40 -0
- data/ext/tb_client/tigerbeetle/src/lsm/tree.zig +630 -0
- data/ext/tb_client/tigerbeetle/src/lsm/tree_fuzz.zig +933 -0
- data/ext/tb_client/tigerbeetle/src/lsm/zig_zag_merge.zig +534 -0
- data/ext/tb_client/tigerbeetle/src/message_buffer.zig +469 -0
- data/ext/tb_client/tigerbeetle/src/message_bus.zig +1214 -0
- data/ext/tb_client/tigerbeetle/src/message_bus_fuzz.zig +936 -0
- data/ext/tb_client/tigerbeetle/src/message_pool.zig +343 -0
- data/ext/tb_client/tigerbeetle/src/multiversion.zig +2195 -0
- data/ext/tb_client/tigerbeetle/src/queue.zig +390 -0
- data/ext/tb_client/tigerbeetle/src/repl/completion.zig +201 -0
- data/ext/tb_client/tigerbeetle/src/repl/parser.zig +1356 -0
- data/ext/tb_client/tigerbeetle/src/repl/terminal.zig +496 -0
- data/ext/tb_client/tigerbeetle/src/repl.zig +1034 -0
- data/ext/tb_client/tigerbeetle/src/scripts/amqp.zig +973 -0
- data/ext/tb_client/tigerbeetle/src/scripts/cfo.zig +1866 -0
- data/ext/tb_client/tigerbeetle/src/scripts/changelog.zig +304 -0
- data/ext/tb_client/tigerbeetle/src/scripts/ci.zig +227 -0
- data/ext/tb_client/tigerbeetle/src/scripts/client_readmes.zig +658 -0
- data/ext/tb_client/tigerbeetle/src/scripts/devhub.zig +466 -0
- data/ext/tb_client/tigerbeetle/src/scripts/release.zig +1058 -0
- data/ext/tb_client/tigerbeetle/src/scripts.zig +105 -0
- data/ext/tb_client/tigerbeetle/src/shell.zig +1195 -0
- data/ext/tb_client/tigerbeetle/src/stack.zig +260 -0
- data/ext/tb_client/tigerbeetle/src/state_machine/auditor.zig +911 -0
- data/ext/tb_client/tigerbeetle/src/state_machine/workload.zig +2079 -0
- data/ext/tb_client/tigerbeetle/src/state_machine.zig +4872 -0
- data/ext/tb_client/tigerbeetle/src/state_machine_fuzz.zig +288 -0
- data/ext/tb_client/tigerbeetle/src/state_machine_tests.zig +3128 -0
- data/ext/tb_client/tigerbeetle/src/static_allocator.zig +82 -0
- data/ext/tb_client/tigerbeetle/src/stdx/bit_set.zig +157 -0
- data/ext/tb_client/tigerbeetle/src/stdx/bounded_array.zig +292 -0
- data/ext/tb_client/tigerbeetle/src/stdx/debug.zig +65 -0
- data/ext/tb_client/tigerbeetle/src/stdx/flags.zig +1414 -0
- data/ext/tb_client/tigerbeetle/src/stdx/mlock.zig +92 -0
- data/ext/tb_client/tigerbeetle/src/stdx/prng.zig +677 -0
- data/ext/tb_client/tigerbeetle/src/stdx/radix.zig +336 -0
- data/ext/tb_client/tigerbeetle/src/stdx/ring_buffer.zig +511 -0
- data/ext/tb_client/tigerbeetle/src/stdx/sort_test.zig +112 -0
- data/ext/tb_client/tigerbeetle/src/stdx/stdx.zig +1160 -0
- data/ext/tb_client/tigerbeetle/src/stdx/testing/low_level_hash_vectors.zig +142 -0
- data/ext/tb_client/tigerbeetle/src/stdx/testing/snaptest.zig +361 -0
- data/ext/tb_client/tigerbeetle/src/stdx/time_units.zig +275 -0
- data/ext/tb_client/tigerbeetle/src/stdx/unshare.zig +295 -0
- data/ext/tb_client/tigerbeetle/src/stdx/vendored/aegis.zig +436 -0
- data/ext/tb_client/tigerbeetle/src/stdx/windows.zig +48 -0
- data/ext/tb_client/tigerbeetle/src/stdx/zipfian.zig +402 -0
- data/ext/tb_client/tigerbeetle/src/storage.zig +489 -0
- data/ext/tb_client/tigerbeetle/src/storage_fuzz.zig +180 -0
- data/ext/tb_client/tigerbeetle/src/testing/bench.zig +146 -0
- data/ext/tb_client/tigerbeetle/src/testing/cluster/grid_checker.zig +53 -0
- data/ext/tb_client/tigerbeetle/src/testing/cluster/journal_checker.zig +61 -0
- data/ext/tb_client/tigerbeetle/src/testing/cluster/manifest_checker.zig +76 -0
- data/ext/tb_client/tigerbeetle/src/testing/cluster/message_bus.zig +110 -0
- data/ext/tb_client/tigerbeetle/src/testing/cluster/network.zig +412 -0
- data/ext/tb_client/tigerbeetle/src/testing/cluster/state_checker.zig +331 -0
- data/ext/tb_client/tigerbeetle/src/testing/cluster/storage_checker.zig +458 -0
- data/ext/tb_client/tigerbeetle/src/testing/cluster.zig +1198 -0
- data/ext/tb_client/tigerbeetle/src/testing/exhaustigen.zig +128 -0
- data/ext/tb_client/tigerbeetle/src/testing/fixtures.zig +181 -0
- data/ext/tb_client/tigerbeetle/src/testing/fuzz.zig +144 -0
- data/ext/tb_client/tigerbeetle/src/testing/id.zig +97 -0
- data/ext/tb_client/tigerbeetle/src/testing/io.zig +317 -0
- data/ext/tb_client/tigerbeetle/src/testing/marks.zig +126 -0
- data/ext/tb_client/tigerbeetle/src/testing/packet_simulator.zig +533 -0
- data/ext/tb_client/tigerbeetle/src/testing/reply_sequence.zig +154 -0
- data/ext/tb_client/tigerbeetle/src/testing/state_machine.zig +389 -0
- data/ext/tb_client/tigerbeetle/src/testing/storage.zig +1247 -0
- data/ext/tb_client/tigerbeetle/src/testing/table.zig +249 -0
- data/ext/tb_client/tigerbeetle/src/testing/time.zig +98 -0
- data/ext/tb_client/tigerbeetle/src/testing/tmp_tigerbeetle.zig +212 -0
- data/ext/tb_client/tigerbeetle/src/testing/vortex/constants.zig +26 -0
- data/ext/tb_client/tigerbeetle/src/testing/vortex/faulty_network.zig +580 -0
- data/ext/tb_client/tigerbeetle/src/testing/vortex/java_driver/ci.zig +39 -0
- data/ext/tb_client/tigerbeetle/src/testing/vortex/logged_process.zig +214 -0
- data/ext/tb_client/tigerbeetle/src/testing/vortex/rust_driver/ci.zig +34 -0
- data/ext/tb_client/tigerbeetle/src/testing/vortex/supervisor.zig +766 -0
- data/ext/tb_client/tigerbeetle/src/testing/vortex/workload.zig +543 -0
- data/ext/tb_client/tigerbeetle/src/testing/vortex/zig_driver.zig +181 -0
- data/ext/tb_client/tigerbeetle/src/tidy.zig +1448 -0
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/benchmark_driver.zig +227 -0
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/benchmark_load.zig +1069 -0
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/cli.zig +1422 -0
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/inspect.zig +1658 -0
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/inspect_integrity.zig +518 -0
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/libtb_client.zig +36 -0
- data/ext/tb_client/tigerbeetle/src/tigerbeetle/main.zig +646 -0
- data/ext/tb_client/tigerbeetle/src/tigerbeetle.zig +958 -0
- data/ext/tb_client/tigerbeetle/src/time.zig +236 -0
- data/ext/tb_client/tigerbeetle/src/trace/event.zig +745 -0
- data/ext/tb_client/tigerbeetle/src/trace/statsd.zig +462 -0
- data/ext/tb_client/tigerbeetle/src/trace.zig +556 -0
- data/ext/tb_client/tigerbeetle/src/unit_tests.zig +321 -0
- data/ext/tb_client/tigerbeetle/src/vopr.zig +1785 -0
- data/ext/tb_client/tigerbeetle/src/vortex.zig +101 -0
- data/ext/tb_client/tigerbeetle/src/vsr/checkpoint_trailer.zig +473 -0
- data/ext/tb_client/tigerbeetle/src/vsr/checksum.zig +208 -0
- data/ext/tb_client/tigerbeetle/src/vsr/checksum_benchmark.zig +43 -0
- data/ext/tb_client/tigerbeetle/src/vsr/client.zig +768 -0
- data/ext/tb_client/tigerbeetle/src/vsr/client_replies.zig +532 -0
- data/ext/tb_client/tigerbeetle/src/vsr/client_sessions.zig +338 -0
- data/ext/tb_client/tigerbeetle/src/vsr/clock.zig +1019 -0
- data/ext/tb_client/tigerbeetle/src/vsr/fault_detector.zig +279 -0
- data/ext/tb_client/tigerbeetle/src/vsr/free_set.zig +1381 -0
- data/ext/tb_client/tigerbeetle/src/vsr/free_set_fuzz.zig +315 -0
- data/ext/tb_client/tigerbeetle/src/vsr/grid.zig +1460 -0
- data/ext/tb_client/tigerbeetle/src/vsr/grid_blocks_missing.zig +757 -0
- data/ext/tb_client/tigerbeetle/src/vsr/grid_scrubber.zig +797 -0
- data/ext/tb_client/tigerbeetle/src/vsr/journal.zig +2586 -0
- data/ext/tb_client/tigerbeetle/src/vsr/marzullo.zig +308 -0
- data/ext/tb_client/tigerbeetle/src/vsr/message_header.zig +1777 -0
- data/ext/tb_client/tigerbeetle/src/vsr/multi_batch.zig +715 -0
- data/ext/tb_client/tigerbeetle/src/vsr/multi_batch_fuzz.zig +185 -0
- data/ext/tb_client/tigerbeetle/src/vsr/repair_budget.zig +333 -0
- data/ext/tb_client/tigerbeetle/src/vsr/replica.zig +12355 -0
- data/ext/tb_client/tigerbeetle/src/vsr/replica_format.zig +416 -0
- data/ext/tb_client/tigerbeetle/src/vsr/replica_reformat.zig +165 -0
- data/ext/tb_client/tigerbeetle/src/vsr/replica_test.zig +2928 -0
- data/ext/tb_client/tigerbeetle/src/vsr/routing.zig +1075 -0
- data/ext/tb_client/tigerbeetle/src/vsr/superblock.zig +1603 -0
- data/ext/tb_client/tigerbeetle/src/vsr/superblock_fuzz.zig +484 -0
- data/ext/tb_client/tigerbeetle/src/vsr/superblock_quorums.zig +405 -0
- data/ext/tb_client/tigerbeetle/src/vsr/superblock_quorums_fuzz.zig +355 -0
- data/ext/tb_client/tigerbeetle/src/vsr/sync.zig +29 -0
- data/ext/tb_client/tigerbeetle/src/vsr.zig +1727 -0
- data/lib/tb_client/shared_lib.rb +12 -5
- data/lib/tigerbeetle/platforms.rb +9 -0
- data/lib/tigerbeetle/version.rb +2 -2
- data/tigerbeetle.gemspec +22 -5
- metadata +242 -3
- data/ext/tb_client/pkg.tar.gz +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
//! Micro benchmarking harness.
|
|
2
|
+
//!
|
|
3
|
+
//! Goals:
|
|
4
|
+
//! - relative (comparative) benchmarking,
|
|
5
|
+
//! - manual checks when refactoring/optimizing/upgrading compiler,
|
|
6
|
+
//! - no benchmark bitrot.
|
|
7
|
+
//!
|
|
8
|
+
//! Non-goals:
|
|
9
|
+
//! - absolute benchmarking,
|
|
10
|
+
//! - continuous benchmarking,
|
|
11
|
+
//! - automatic regression detection.
|
|
12
|
+
//!
|
|
13
|
+
//! If you run
|
|
14
|
+
//! $ ./zig/zig build test
|
|
15
|
+
//! the benchmarks are run in "test" mode which uses small inputs, finishes quickly, and doesn't
|
|
16
|
+
//! print anything to stdout.
|
|
17
|
+
//!
|
|
18
|
+
//! If you run
|
|
19
|
+
//! $ ./zig/zig build -Drelease test -- "benchmark: binary search"
|
|
20
|
+
//! the benchmark is run for real, with a large input, longer runtime, and results on stderr.
|
|
21
|
+
//! The `benchmark` in the test name is the secret code to unlock benchmarking code.
|
|
22
|
+
|
|
23
|
+
test "benchmark: API tutorial" { // `benchmark:` in the name is important!
|
|
24
|
+
var bench: Bench = .init();
|
|
25
|
+
defer bench.deinit();
|
|
26
|
+
|
|
27
|
+
// Parameters are named, and have two default values.
|
|
28
|
+
// The small value is used in tests, to prevent bitrot.
|
|
29
|
+
// The large value is the canonical when running benchmark "for real".
|
|
30
|
+
// You can pass custom values via env variables:
|
|
31
|
+
// $ a=92 ./zig/zig build test -- "benchmark: tutorial"
|
|
32
|
+
const a = bench.parameter("a", 1, 1_000);
|
|
33
|
+
const b = bench.parameter("b", 2, 2_000);
|
|
34
|
+
|
|
35
|
+
bench.start(); // Built-in timer.
|
|
36
|
+
const c = a + b;
|
|
37
|
+
const elapsed = bench.stop();
|
|
38
|
+
|
|
39
|
+
// Always print a "hash" of the run:
|
|
40
|
+
// - to prevent compiler from optimizing the code away,
|
|
41
|
+
// - to prevent YOU from "optimizing" the code by changing semantics.
|
|
42
|
+
bench.report("hash: {}", .{c});
|
|
43
|
+
// Print the time, and any other metrics you find important.
|
|
44
|
+
bench.report("elapsed: {}", .{elapsed});
|
|
45
|
+
|
|
46
|
+
// NB: print as little as possible, because humans read slowly.
|
|
47
|
+
// It's the job of benchmark author to optimize for conciseness.
|
|
48
|
+
|
|
49
|
+
// You can compile individual benchmark via
|
|
50
|
+
// ./zig/zig build test:unit:build -- "benchmark: binary search"
|
|
51
|
+
// and use the resulting binary with perf/hyperfine/poop.
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const std = @import("std");
|
|
55
|
+
const assert = std.debug.assert;
|
|
56
|
+
const stdx = @import("stdx");
|
|
57
|
+
const Duration = stdx.Duration;
|
|
58
|
+
const Instant = stdx.Instant;
|
|
59
|
+
const TimeOS = @import("../time.zig").TimeOS;
|
|
60
|
+
|
|
61
|
+
const seed_benchmark: u64 = 42;
|
|
62
|
+
|
|
63
|
+
const mode: enum { smoke, benchmark } =
|
|
64
|
+
// See build.zig for how this is ultimately determined.
|
|
65
|
+
if (@import("test_options").benchmark) .benchmark else .smoke;
|
|
66
|
+
|
|
67
|
+
seed: u64,
|
|
68
|
+
time: TimeOS = .{},
|
|
69
|
+
instant_start: ?Instant = null,
|
|
70
|
+
|
|
71
|
+
const Bench = @This();
|
|
72
|
+
|
|
73
|
+
pub fn init() Bench {
|
|
74
|
+
return .{
|
|
75
|
+
// Benchmarks require a fixed seed for reproducibility; smoke mode uses a random seed.
|
|
76
|
+
.seed = if (mode == .benchmark) seed_benchmark else std.testing.random_seed,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
pub fn deinit(bench: *Bench) void {
|
|
81
|
+
assert(bench.instant_start == null);
|
|
82
|
+
bench.* = undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
pub fn parameter(
|
|
86
|
+
b: *const Bench,
|
|
87
|
+
comptime name: []const u8,
|
|
88
|
+
value_smoke: u64,
|
|
89
|
+
value_benchmark: u64,
|
|
90
|
+
) u64 {
|
|
91
|
+
assert(value_smoke < value_benchmark);
|
|
92
|
+
const value = parameter_fallible(name, value_smoke, value_benchmark) catch |err| switch (err) {
|
|
93
|
+
error.InvalidCharacter, error.Overflow => @panic("invalid benchmark parameter value"),
|
|
94
|
+
};
|
|
95
|
+
b.report("{s}={}", .{ name, value });
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
fn parameter_fallible(
|
|
100
|
+
comptime name: []const u8,
|
|
101
|
+
value_smoke: u64,
|
|
102
|
+
value_benchmark: u64,
|
|
103
|
+
) std.fmt.ParseIntError!u64 {
|
|
104
|
+
assert(value_smoke < value_benchmark);
|
|
105
|
+
return switch (mode) {
|
|
106
|
+
.smoke => value_smoke,
|
|
107
|
+
.benchmark => std.process.parseEnvVarInt(name, u64, 10) catch |err| switch (err) {
|
|
108
|
+
error.EnvironmentVariableNotFound => return value_benchmark,
|
|
109
|
+
else => |e| return e,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
pub fn start(bench: *Bench) void {
|
|
115
|
+
assert(bench.instant_start == null);
|
|
116
|
+
defer assert(bench.instant_start != null);
|
|
117
|
+
|
|
118
|
+
bench.instant_start = bench.time.time().monotonic();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
pub fn stop(bench: *Bench) Duration {
|
|
122
|
+
assert(bench.instant_start != null);
|
|
123
|
+
defer assert(bench.instant_start == null);
|
|
124
|
+
|
|
125
|
+
const instant_stop = bench.time.time().monotonic();
|
|
126
|
+
const elapsed = instant_stop.duration_since(bench.instant_start.?);
|
|
127
|
+
bench.instant_start = null;
|
|
128
|
+
return elapsed;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Sort the durations and return the third-fastest sample (discarding the two fastest outliers)
|
|
132
|
+
// to get a more stable estimate, assuming benchmark timings are roughly log-normal.
|
|
133
|
+
// E.g. see https://lemire.me/blog/2018/01/16/microbenchmarking-calls-for-idealized-conditions/
|
|
134
|
+
pub fn estimate(bench: *const Bench, durations: []Duration) Duration {
|
|
135
|
+
assert(durations.len >= 8); // Ensure that we have enough samples to get a meaningful result.
|
|
136
|
+
_ = bench;
|
|
137
|
+
std.sort.block(stdx.Duration, durations, {}, stdx.Duration.sort.asc);
|
|
138
|
+
return durations[2];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
pub fn report(_: *const Bench, comptime fmt: []const u8, args: anytype) void {
|
|
142
|
+
switch (mode) {
|
|
143
|
+
.smoke => {},
|
|
144
|
+
.benchmark => std.debug.print(fmt ++ "\n", args),
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const assert = std.debug.assert;
|
|
3
|
+
const vsr = @import("../../vsr.zig");
|
|
4
|
+
|
|
5
|
+
pub const GridChecker = struct {
|
|
6
|
+
const Blocks = std.AutoHashMap(struct {
|
|
7
|
+
checkpoint_id: u128,
|
|
8
|
+
block_address: u64,
|
|
9
|
+
checkpoint_durable: bool,
|
|
10
|
+
}, u128);
|
|
11
|
+
|
|
12
|
+
blocks: Blocks,
|
|
13
|
+
|
|
14
|
+
pub fn init(allocator: std.mem.Allocator) GridChecker {
|
|
15
|
+
return .{ .blocks = Blocks.init(allocator) };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
pub fn deinit(checker: *GridChecker) void {
|
|
19
|
+
checker.blocks.deinit();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
pub fn assert_coherent(
|
|
23
|
+
checker: *GridChecker,
|
|
24
|
+
checkpoint: *vsr.CheckpointState,
|
|
25
|
+
checkpoint_durable: bool,
|
|
26
|
+
block_address: u64,
|
|
27
|
+
block_checksum: u128,
|
|
28
|
+
) void {
|
|
29
|
+
const result = checker.blocks.getOrPut(.{
|
|
30
|
+
.checkpoint_id = vsr.checksum(std.mem.asBytes(checkpoint)),
|
|
31
|
+
.block_address = block_address,
|
|
32
|
+
.checkpoint_durable = checkpoint_durable,
|
|
33
|
+
}) catch unreachable;
|
|
34
|
+
|
|
35
|
+
if (result.found_existing) {
|
|
36
|
+
assert(result.value_ptr.* == block_checksum);
|
|
37
|
+
} else {
|
|
38
|
+
result.value_ptr.* = block_checksum;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Assert that the same version of the block must exist while the current checkpoint is
|
|
42
|
+
// not durable and while the previous checkpoint is durable.
|
|
43
|
+
if (!checkpoint_durable) {
|
|
44
|
+
if (checker.blocks.get(.{
|
|
45
|
+
.checkpoint_id = checkpoint.parent_checkpoint_id,
|
|
46
|
+
.block_address = block_address,
|
|
47
|
+
.checkpoint_durable = true,
|
|
48
|
+
})) |checksum| {
|
|
49
|
+
assert(checksum == block_checksum);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//! Verify Journal/WAL properties.
|
|
2
|
+
const std = @import("std");
|
|
3
|
+
const assert = std.debug.assert;
|
|
4
|
+
const log = std.log.scoped(.journal_checker);
|
|
5
|
+
|
|
6
|
+
const constants = @import("../../constants.zig");
|
|
7
|
+
const stdx = @import("stdx");
|
|
8
|
+
const vsr = @import("../../vsr.zig");
|
|
9
|
+
const TestStorage = @import("../storage.zig").Storage;
|
|
10
|
+
|
|
11
|
+
pub fn JournalCheckerType(comptime Replica: type) type {
|
|
12
|
+
return struct {
|
|
13
|
+
pub fn check(replica: *const Replica) void {
|
|
14
|
+
const replica_index = replica.replica;
|
|
15
|
+
const replica_storage = replica.superblock.storage;
|
|
16
|
+
comptime assert(@TypeOf(replica_storage) == *TestStorage);
|
|
17
|
+
|
|
18
|
+
if (replica.journal.writes.executing() == 0) {
|
|
19
|
+
// Sanity-check: Where the journal is clean and not being written to:
|
|
20
|
+
// - Redundant headers exactly match their corresponding prepares.
|
|
21
|
+
// - The WAL's content matches `journal.headers`.
|
|
22
|
+
// - There are no zeroed entries (representing faulty journal entries) in the
|
|
23
|
+
// redundant WAL headers.
|
|
24
|
+
var wal_header_errors: u32 = 0;
|
|
25
|
+
for (
|
|
26
|
+
replica_storage.wal_headers(),
|
|
27
|
+
replica_storage.wal_prepares(),
|
|
28
|
+
replica.journal.headers,
|
|
29
|
+
0..,
|
|
30
|
+
) |*wal_header, *wal_prepare, *journal_header, slot| {
|
|
31
|
+
if (!replica.journal.dirty.bit(.{ .index = slot })) {
|
|
32
|
+
if (journal_header.operation == .reserved) {
|
|
33
|
+
// Ignore reserved headers -- when Journal.remove_entries_from()
|
|
34
|
+
// truncates the log, it cleans the in-memory journal without writing to
|
|
35
|
+
// the WAL.
|
|
36
|
+
} else {
|
|
37
|
+
if (wal_header.checksum == 0) {
|
|
38
|
+
log.err("{}: check: slot={} checksum=0", .{ replica_index, slot });
|
|
39
|
+
wal_header_errors += 1;
|
|
40
|
+
} else {
|
|
41
|
+
assert(wal_header.checksum == wal_prepare.header.checksum);
|
|
42
|
+
assert(wal_header.checksum == journal_header.checksum);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
assert(wal_header_errors == 0);
|
|
48
|
+
|
|
49
|
+
// Verify that prepares' trailing sector padding is zeroed.
|
|
50
|
+
for (0..constants.journal_slot_count) |slot| {
|
|
51
|
+
const prepare =
|
|
52
|
+
replica_storage.area_memory(.{ .wal_prepares = .{ .slot = slot } });
|
|
53
|
+
const header =
|
|
54
|
+
std.mem.bytesAsValue(vsr.Header, prepare[0..@sizeOf(vsr.Header)]);
|
|
55
|
+
const prepare_padding = prepare[header.size..vsr.sector_ceil(header.size)];
|
|
56
|
+
assert(stdx.zeroed(prepare_padding));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
//! Verify that the ManifestLevels tables are constructed consistently across replicas and after
|
|
2
|
+
//! recovering from a restart.
|
|
3
|
+
const std = @import("std");
|
|
4
|
+
const assert = std.debug.assert;
|
|
5
|
+
|
|
6
|
+
const vsr = @import("../../vsr.zig");
|
|
7
|
+
const constants = @import("../../constants.zig");
|
|
8
|
+
|
|
9
|
+
pub fn ManifestCheckerType(comptime Forest: type) type {
|
|
10
|
+
return struct {
|
|
11
|
+
const ManifestChecker = @This();
|
|
12
|
+
|
|
13
|
+
/// Maps checkpoint op to the cumulative checksum of all trees/levels checksum.
|
|
14
|
+
const Checkpoints = std.AutoHashMap(u64, u128);
|
|
15
|
+
|
|
16
|
+
checkpoints: Checkpoints,
|
|
17
|
+
|
|
18
|
+
pub fn init(allocator: std.mem.Allocator) ManifestChecker {
|
|
19
|
+
return .{ .checkpoints = Checkpoints.init(allocator) };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
pub fn deinit(checker: *ManifestChecker) void {
|
|
23
|
+
checker.checkpoints.deinit();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
pub fn forest_open(checker: *ManifestChecker, forest: *const Forest) void {
|
|
27
|
+
checker.check(forest);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
pub fn forest_checkpoint(checker: *ManifestChecker, forest: *const Forest) void {
|
|
31
|
+
checker.check(forest);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
fn check(checker: *ManifestChecker, forest: *const Forest) void {
|
|
35
|
+
assert(forest.grid.superblock.opened);
|
|
36
|
+
assert(forest.manifest_log.opened);
|
|
37
|
+
|
|
38
|
+
const checkpoint_op = forest.grid.superblock.working.vsr_state.checkpoint.header.op;
|
|
39
|
+
const checksum_stored = checker.checkpoints.getOrPut(checkpoint_op) catch @panic("oom");
|
|
40
|
+
const checksum_current = manifest_levels_checksum(forest);
|
|
41
|
+
|
|
42
|
+
// On open, we will usually have already have a checksum to compare against from a prior
|
|
43
|
+
// checkpoint. But not always: it is possible that we are recovering from a checkpoint
|
|
44
|
+
// that wrote e.g. 3/4 superblock copies and then crashed.
|
|
45
|
+
if (checksum_stored.found_existing) {
|
|
46
|
+
assert(checksum_stored.value_ptr.* == checksum_current);
|
|
47
|
+
} else {
|
|
48
|
+
checksum_stored.value_ptr.* = checksum_current;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fn manifest_levels_checksum(forest: *const Forest) u128 {
|
|
53
|
+
var checksum_stream = vsr.ChecksumStream.init();
|
|
54
|
+
for (0..constants.lsm_levels) |level| {
|
|
55
|
+
checksum_stream.add(std.mem.asBytes(&level));
|
|
56
|
+
|
|
57
|
+
inline for (Forest.tree_id_range.min..Forest.tree_id_range.max + 1) |tree_id_u16| {
|
|
58
|
+
const tree_id: Forest.TreeID = @enumFromInt(tree_id_u16);
|
|
59
|
+
const tree_level = forest.tree_for_id_const(tree_id).manifest.levels[level];
|
|
60
|
+
var tree_tables = tree_level.tables.iterator_from_index(0, .ascending);
|
|
61
|
+
|
|
62
|
+
checksum_stream.add(std.mem.asBytes(&tree_id));
|
|
63
|
+
checksum_stream.add(std.mem.asBytes(&tree_level.table_count_visible));
|
|
64
|
+
while (tree_tables.next()) |tree_table| {
|
|
65
|
+
checksum_stream.add(std.mem.asBytes(&tree_table.encode(.{
|
|
66
|
+
.tree_id = tree_id_u16,
|
|
67
|
+
.event = .insert, // (Placeholder event).
|
|
68
|
+
.level = @intCast(level),
|
|
69
|
+
})));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return checksum_stream.checksum();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const assert = std.debug.assert;
|
|
3
|
+
|
|
4
|
+
const MessagePool = @import("../../message_pool.zig").MessagePool;
|
|
5
|
+
const Message = MessagePool.Message;
|
|
6
|
+
const MessageBuffer = @import("../../message_buffer.zig").MessageBuffer;
|
|
7
|
+
const vsr = @import("../../vsr.zig");
|
|
8
|
+
const ProcessType = vsr.ProcessType;
|
|
9
|
+
|
|
10
|
+
const Network = @import("network.zig").Network;
|
|
11
|
+
|
|
12
|
+
pub const Process = union(ProcessType) {
|
|
13
|
+
replica: u8,
|
|
14
|
+
client: u128,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
pub const MessageBus = struct {
|
|
18
|
+
network: *Network,
|
|
19
|
+
pool: *MessagePool,
|
|
20
|
+
|
|
21
|
+
process: Process,
|
|
22
|
+
|
|
23
|
+
buffer: ?MessageBuffer,
|
|
24
|
+
suspended: bool = false,
|
|
25
|
+
resume_scheduled: bool = false,
|
|
26
|
+
/// The callback to be called when a message is received.
|
|
27
|
+
on_messages_callback: *const fn (message_bus: *MessageBus, buffer: *MessageBuffer) void,
|
|
28
|
+
|
|
29
|
+
pub const Options = struct {
|
|
30
|
+
network: *Network,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
pub fn init(
|
|
34
|
+
_: std.mem.Allocator,
|
|
35
|
+
process: Process,
|
|
36
|
+
message_pool: *MessagePool,
|
|
37
|
+
on_messages_callback: *const fn (message_bus: *MessageBus, buffer: *MessageBuffer) void,
|
|
38
|
+
options: Options,
|
|
39
|
+
) !MessageBus {
|
|
40
|
+
return MessageBus{
|
|
41
|
+
.network = options.network,
|
|
42
|
+
.pool = message_pool,
|
|
43
|
+
.process = process,
|
|
44
|
+
.buffer = MessageBuffer.init(message_pool),
|
|
45
|
+
.on_messages_callback = on_messages_callback,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pub fn deinit(bus: *MessageBus, _: std.mem.Allocator) void {
|
|
50
|
+
bus.buffer.?.deinit(bus.pool);
|
|
51
|
+
bus.buffer = null;
|
|
52
|
+
bus.resume_scheduled = false;
|
|
53
|
+
// NB: Network keeps a reference to a message bus even when a replica is de-initialized,
|
|
54
|
+
// so we don't assign bus.* to undefined here.
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
pub fn trace_gauge(_: *MessageBus) void {}
|
|
58
|
+
|
|
59
|
+
pub fn listen(_: *MessageBus) !void {}
|
|
60
|
+
|
|
61
|
+
pub fn tick(_: *MessageBus) void {}
|
|
62
|
+
|
|
63
|
+
pub fn tick_client(bus: *MessageBus) void {
|
|
64
|
+
bus.tick();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
pub fn get_message(
|
|
68
|
+
bus: *MessageBus,
|
|
69
|
+
comptime command: ?vsr.Command,
|
|
70
|
+
) MessagePool.GetMessageType(command) {
|
|
71
|
+
return bus.pool.get_message(command);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/// `@TypeOf(message)` is one of:
|
|
75
|
+
/// - `*Message`
|
|
76
|
+
/// - `MessageType(command)` for any `command`.
|
|
77
|
+
pub fn unref(bus: *MessageBus, message: anytype) void {
|
|
78
|
+
bus.pool.unref(message);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
pub fn resume_needed(bus: *MessageBus) bool {
|
|
82
|
+
return bus.suspended;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
pub fn resume_receive(bus: *MessageBus) void {
|
|
86
|
+
bus.suspended = false;
|
|
87
|
+
bus.resume_scheduled = true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
pub fn send_message_to_replica(bus: *MessageBus, replica: u8, message: *Message) void {
|
|
91
|
+
// Messages sent by a process to itself should never be passed to the message bus
|
|
92
|
+
if (bus.process == .replica) assert(replica != bus.process.replica);
|
|
93
|
+
|
|
94
|
+
bus.network.send_message(message, .{
|
|
95
|
+
.source = bus.process,
|
|
96
|
+
.target = .{ .replica = replica },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/// Try to send the message to the client with the given id.
|
|
101
|
+
/// If the client is not currently connected, the message is silently dropped.
|
|
102
|
+
pub fn send_message_to_client(bus: *MessageBus, client_id: u128, message: *Message) void {
|
|
103
|
+
assert(bus.process == .replica);
|
|
104
|
+
|
|
105
|
+
bus.network.send_message(message, .{
|
|
106
|
+
.source = bus.process,
|
|
107
|
+
.target = .{ .client = client_id },
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
};
|