tigerbeetle 0.0.34 → 0.0.37
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 +10 -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 +1084 -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 +11 -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 +362 -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 +1036 -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 +105 -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 +557 -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 +2910 -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/client.rb +1 -1
- 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,745 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const stdx = @import("stdx");
|
|
3
|
+
const assert = std.debug.assert;
|
|
4
|
+
|
|
5
|
+
const constants = @import("../constants.zig");
|
|
6
|
+
|
|
7
|
+
const Command = @import("../vsr.zig").Command;
|
|
8
|
+
const Zone = @import("../vsr.zig").Zone;
|
|
9
|
+
const CommitStage = @import("../vsr/replica.zig").CommitStage;
|
|
10
|
+
const Operation = @import("../tigerbeetle.zig").Operation;
|
|
11
|
+
const Duration = stdx.Duration;
|
|
12
|
+
const Peer = @import("../vsr.zig").Peer;
|
|
13
|
+
|
|
14
|
+
const TreeEnum = tree_enum: {
|
|
15
|
+
const tree_ids = @import("../state_machine.zig").tree_ids;
|
|
16
|
+
var tree_fields: []const std.builtin.Type.EnumField = &[_]std.builtin.Type.EnumField{};
|
|
17
|
+
|
|
18
|
+
for (std.meta.declarations(tree_ids)) |groove_field| {
|
|
19
|
+
const tree_ids_groove = @field(tree_ids, groove_field.name);
|
|
20
|
+
for (std.meta.fieldNames(@TypeOf(tree_ids_groove))) |field_name| {
|
|
21
|
+
tree_fields = tree_fields ++ &[_]std.builtin.Type.EnumField{.{
|
|
22
|
+
.name = groove_field.name ++ "." ++ field_name,
|
|
23
|
+
.value = @field(tree_ids_groove, field_name),
|
|
24
|
+
}};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
break :tree_enum @Type(.{ .@"enum" = .{
|
|
29
|
+
.tag_type = u32,
|
|
30
|
+
.fields = tree_fields,
|
|
31
|
+
.decls = &.{},
|
|
32
|
+
.is_exhaustive = true,
|
|
33
|
+
} });
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/// Returns the count of an exhaustive enum.
|
|
37
|
+
fn enum_count(EnumOrUnion: type) u8 {
|
|
38
|
+
const type_info = @typeInfo(EnumOrUnion);
|
|
39
|
+
assert(type_info == .@"enum" or type_info == .@"union");
|
|
40
|
+
|
|
41
|
+
const Enum = if (type_info == .@"enum")
|
|
42
|
+
type_info.@"enum"
|
|
43
|
+
else
|
|
44
|
+
@typeInfo(type_info.@"union".tag_type.?).@"enum";
|
|
45
|
+
assert(Enum.is_exhaustive);
|
|
46
|
+
|
|
47
|
+
return Enum.fields.len;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// Maps an exhaustive enum value from an enum type that might potentially start with a non-zero
|
|
51
|
+
/// value or be sparse to a continuous index that fits within enum_count().
|
|
52
|
+
fn index_from_enum(enum_tag: anytype) u8 {
|
|
53
|
+
const type_info = @typeInfo(@TypeOf(enum_tag));
|
|
54
|
+
assert(type_info == .@"enum" or type_info == .@"union");
|
|
55
|
+
|
|
56
|
+
const Enum = if (type_info == .@"enum")
|
|
57
|
+
type_info.@"enum"
|
|
58
|
+
else
|
|
59
|
+
@typeInfo(type_info.@"union".tag_type.?).@"enum";
|
|
60
|
+
assert(Enum.is_exhaustive);
|
|
61
|
+
|
|
62
|
+
inline for (Enum.fields, 0..) |enum_field, i| {
|
|
63
|
+
if (enum_field.value == @intFromEnum(enum_tag)) {
|
|
64
|
+
return i;
|
|
65
|
+
}
|
|
66
|
+
} else unreachable;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// TODO: It should be possible to get rid of all unbounded cardinality (eg, level_b being a u8) and
|
|
70
|
+
// replace them with enums instead. This would allow for calculating the stack limit automatically.
|
|
71
|
+
|
|
72
|
+
/// Base {Timing,Tracing} Event. This is further split up into two different Events that share the
|
|
73
|
+
/// same tag: ones for timing and ones for tracing.
|
|
74
|
+
///
|
|
75
|
+
/// This is because there's a difference between tracing and aggregate timing. When doing tracing,
|
|
76
|
+
/// the code needs to worry about the static allocation required for _concurrent_ traces. That is,
|
|
77
|
+
/// there might be multiple `scan_tree`s, with different `index`es happening at once.
|
|
78
|
+
///
|
|
79
|
+
/// When timing, this is flipped on its head: the timing code doesn't need space for concurrency
|
|
80
|
+
/// because it is called once, when an event has finished, and internally aggregates. The
|
|
81
|
+
/// aggregation is needed because there can be an unknown number of calls between flush intervals,
|
|
82
|
+
/// compared to tracing which is emitted as it happens.
|
|
83
|
+
///
|
|
84
|
+
/// Rather, it needs space for the cardinality of the tags you'd like to emit. In the case of
|
|
85
|
+
/// `scan_tree`s, this would be the tree it's scanning over, instead of the index of the scan.
|
|
86
|
+
pub const Event = union(enum) {
|
|
87
|
+
replica_commit: struct { stage: CommitStage.Tag, op: ?usize = null },
|
|
88
|
+
replica_aof_write: struct { op: usize },
|
|
89
|
+
replica_aof_checkpoint,
|
|
90
|
+
replica_sync_table: struct { index: usize },
|
|
91
|
+
replica_request: struct { operation: Operation },
|
|
92
|
+
replica_request_execute: struct { operation: Operation },
|
|
93
|
+
replica_request_local: struct { operation: Operation },
|
|
94
|
+
|
|
95
|
+
compact_beat: struct { tree: TreeEnum, level_b: u8 },
|
|
96
|
+
compact_beat_merge: struct { tree: TreeEnum, level_b: u8 },
|
|
97
|
+
compact_manifest,
|
|
98
|
+
compact_mutable: struct { tree: TreeEnum },
|
|
99
|
+
compact_mutable_suffix: struct { tree: TreeEnum },
|
|
100
|
+
|
|
101
|
+
lookup: struct { tree: TreeEnum },
|
|
102
|
+
lookup_worker: struct { index: u8, tree: TreeEnum },
|
|
103
|
+
|
|
104
|
+
scan_tree: struct { index: u8, tree: TreeEnum },
|
|
105
|
+
scan_tree_level: struct { index: u8, tree: TreeEnum, level: u8 },
|
|
106
|
+
|
|
107
|
+
grid_read: struct { iop: usize },
|
|
108
|
+
grid_write: struct { iop: usize },
|
|
109
|
+
storage_read: struct { zone: Zone },
|
|
110
|
+
storage_write: struct { zone: Zone },
|
|
111
|
+
|
|
112
|
+
metrics_emit,
|
|
113
|
+
|
|
114
|
+
client_request_round_trip: struct { operation: Operation },
|
|
115
|
+
|
|
116
|
+
loop_run_for_ns,
|
|
117
|
+
loop_tick,
|
|
118
|
+
|
|
119
|
+
pub const Tag = std.meta.Tag(Event);
|
|
120
|
+
|
|
121
|
+
/// Normally, Zig would stringify a union(enum) like this as `{"compact_beat": {"tree": ...}}`.
|
|
122
|
+
/// Remove this extra layer of indirection.
|
|
123
|
+
pub fn jsonStringify(event: Event, jw: anytype) !void {
|
|
124
|
+
switch (event) {
|
|
125
|
+
inline else => |payload, tag| {
|
|
126
|
+
if (@TypeOf(payload) == void) {
|
|
127
|
+
try jw.write("");
|
|
128
|
+
} else if (tag == .replica_commit) {
|
|
129
|
+
try jw.write(.{ .stage = @tagName(payload.stage), .op = payload.op });
|
|
130
|
+
} else {
|
|
131
|
+
try jw.write(payload);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/// Convert the base event to an EventTiming or EventMetric.
|
|
138
|
+
pub fn as(event: *const Event, EventType: type) EventType {
|
|
139
|
+
@setEvalBranchQuota(32_000);
|
|
140
|
+
return switch (event.*) {
|
|
141
|
+
inline else => |source_payload, tag| {
|
|
142
|
+
const TargetPayload = @FieldType(EventType, @tagName(tag));
|
|
143
|
+
const target_payload_info = @typeInfo(TargetPayload);
|
|
144
|
+
assert(target_payload_info == .void or target_payload_info == .@"struct");
|
|
145
|
+
|
|
146
|
+
const target_payload: TargetPayload = switch (@typeInfo(TargetPayload)) {
|
|
147
|
+
.void => {},
|
|
148
|
+
.@"struct" => blk: {
|
|
149
|
+
var target_payload: TargetPayload = undefined;
|
|
150
|
+
inline for (comptime std.meta.fieldNames(TargetPayload)) |field| {
|
|
151
|
+
@field(target_payload, field) = @field(source_payload, field);
|
|
152
|
+
}
|
|
153
|
+
break :blk target_payload;
|
|
154
|
+
},
|
|
155
|
+
else => unreachable,
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
return @unionInit(EventType, @tagName(tag), target_payload);
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
pub const EventTiming = union(Event.Tag) {
|
|
165
|
+
replica_commit: struct { stage: CommitStage.Tag },
|
|
166
|
+
replica_aof_write,
|
|
167
|
+
replica_aof_checkpoint,
|
|
168
|
+
replica_sync_table,
|
|
169
|
+
replica_request: struct { operation: Operation },
|
|
170
|
+
replica_request_execute: struct { operation: Operation },
|
|
171
|
+
replica_request_local: struct { operation: Operation },
|
|
172
|
+
|
|
173
|
+
compact_beat: struct { tree: TreeEnum },
|
|
174
|
+
compact_beat_merge: struct { tree: TreeEnum },
|
|
175
|
+
compact_manifest,
|
|
176
|
+
compact_mutable: struct { tree: TreeEnum },
|
|
177
|
+
compact_mutable_suffix: struct { tree: TreeEnum },
|
|
178
|
+
|
|
179
|
+
lookup: struct { tree: TreeEnum },
|
|
180
|
+
lookup_worker: struct { tree: TreeEnum },
|
|
181
|
+
|
|
182
|
+
scan_tree: struct { tree: TreeEnum },
|
|
183
|
+
scan_tree_level: struct { tree: TreeEnum },
|
|
184
|
+
|
|
185
|
+
grid_read,
|
|
186
|
+
grid_write,
|
|
187
|
+
storage_read: struct { zone: Zone },
|
|
188
|
+
storage_write: struct { zone: Zone },
|
|
189
|
+
|
|
190
|
+
metrics_emit,
|
|
191
|
+
|
|
192
|
+
client_request_round_trip: struct { operation: Operation },
|
|
193
|
+
|
|
194
|
+
loop_run_for_ns,
|
|
195
|
+
loop_tick,
|
|
196
|
+
|
|
197
|
+
pub const slot_limits = std.enums.EnumArray(Event.Tag, u32).init(.{
|
|
198
|
+
.replica_commit = enum_count(CommitStage.Tag),
|
|
199
|
+
.replica_aof_write = 1,
|
|
200
|
+
.replica_aof_checkpoint = 1,
|
|
201
|
+
.replica_sync_table = 1,
|
|
202
|
+
.replica_request = enum_count(Operation),
|
|
203
|
+
.replica_request_execute = enum_count(Operation),
|
|
204
|
+
.replica_request_local = enum_count(Operation),
|
|
205
|
+
.compact_beat = enum_count(TreeEnum),
|
|
206
|
+
.compact_beat_merge = enum_count(TreeEnum),
|
|
207
|
+
.compact_manifest = 1,
|
|
208
|
+
.compact_mutable = enum_count(TreeEnum),
|
|
209
|
+
.compact_mutable_suffix = enum_count(TreeEnum),
|
|
210
|
+
.lookup = enum_count(TreeEnum),
|
|
211
|
+
.lookup_worker = enum_count(TreeEnum),
|
|
212
|
+
.scan_tree = enum_count(TreeEnum),
|
|
213
|
+
.scan_tree_level = enum_count(TreeEnum),
|
|
214
|
+
.grid_read = 1,
|
|
215
|
+
.grid_write = 1,
|
|
216
|
+
.metrics_emit = 1,
|
|
217
|
+
.storage_read = enum_count(Zone),
|
|
218
|
+
.storage_write = enum_count(Zone),
|
|
219
|
+
.client_request_round_trip = enum_count(Operation),
|
|
220
|
+
.loop_run_for_ns = 1,
|
|
221
|
+
.loop_tick = 1,
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
pub const slot_bases = array: {
|
|
225
|
+
var array = std.enums.EnumArray(Event.Tag, u32).initFill(0);
|
|
226
|
+
var next: u32 = 0;
|
|
227
|
+
for (std.enums.values(Event.Tag)) |event_type| {
|
|
228
|
+
array.set(event_type, next);
|
|
229
|
+
next += slot_limits.get(event_type);
|
|
230
|
+
}
|
|
231
|
+
break :array array;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
pub const slot_count = count: {
|
|
235
|
+
var count: u32 = 0;
|
|
236
|
+
for (std.enums.values(Event.Tag)) |event_type| {
|
|
237
|
+
count += slot_limits.get(event_type);
|
|
238
|
+
}
|
|
239
|
+
break :count count;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// Unlike with EventTracing, which neatly organizes related events underneath one another, the
|
|
243
|
+
// order here does not matter.
|
|
244
|
+
//
|
|
245
|
+
// TODO: This could be computed automatically, at least in the cases where all, or all except
|
|
246
|
+
// one of the values are enums.
|
|
247
|
+
pub fn slot(event: *const EventTiming) u32 {
|
|
248
|
+
switch (event.*) {
|
|
249
|
+
// Single payload: CommitStage.Tag
|
|
250
|
+
inline .replica_commit => |data| {
|
|
251
|
+
const stage = index_from_enum(data.stage);
|
|
252
|
+
assert(stage < slot_limits.get(event.*));
|
|
253
|
+
|
|
254
|
+
return slot_bases.get(event.*) + stage;
|
|
255
|
+
},
|
|
256
|
+
// Single payload: Operation
|
|
257
|
+
inline .replica_request,
|
|
258
|
+
.replica_request_execute,
|
|
259
|
+
.replica_request_local,
|
|
260
|
+
.client_request_round_trip,
|
|
261
|
+
=> |data| {
|
|
262
|
+
const operation = index_from_enum(data.operation);
|
|
263
|
+
assert(operation < slot_limits.get(event.*));
|
|
264
|
+
|
|
265
|
+
return slot_bases.get(event.*) + operation;
|
|
266
|
+
},
|
|
267
|
+
// Single payload: TreeEnum
|
|
268
|
+
inline .compact_mutable,
|
|
269
|
+
.compact_mutable_suffix,
|
|
270
|
+
.lookup,
|
|
271
|
+
.lookup_worker,
|
|
272
|
+
.scan_tree,
|
|
273
|
+
=> |data| {
|
|
274
|
+
const tree_id = index_from_enum(data.tree);
|
|
275
|
+
assert(tree_id < slot_limits.get(event.*));
|
|
276
|
+
|
|
277
|
+
return slot_bases.get(event.*) + tree_id;
|
|
278
|
+
},
|
|
279
|
+
inline .compact_beat, .compact_beat_merge => |data| {
|
|
280
|
+
const tree_id = index_from_enum(data.tree);
|
|
281
|
+
const offset = tree_id;
|
|
282
|
+
assert(offset < slot_limits.get(event.*));
|
|
283
|
+
|
|
284
|
+
return slot_bases.get(event.*) + offset;
|
|
285
|
+
},
|
|
286
|
+
inline .scan_tree_level => |data| {
|
|
287
|
+
const tree_id = index_from_enum(data.tree);
|
|
288
|
+
const offset = tree_id;
|
|
289
|
+
assert(offset < slot_limits.get(event.*));
|
|
290
|
+
|
|
291
|
+
return slot_bases.get(event.*) + offset;
|
|
292
|
+
},
|
|
293
|
+
inline .storage_read, .storage_write => |data| {
|
|
294
|
+
const zone = index_from_enum(data.zone);
|
|
295
|
+
const offset = zone;
|
|
296
|
+
assert(offset < slot_limits.get(event.*));
|
|
297
|
+
|
|
298
|
+
return slot_bases.get(event.*) + offset;
|
|
299
|
+
},
|
|
300
|
+
inline else => |data, event_tag| {
|
|
301
|
+
comptime assert(@TypeOf(data) == void);
|
|
302
|
+
comptime assert(slot_limits.get(event_tag) == 1);
|
|
303
|
+
|
|
304
|
+
return comptime slot_bases.get(event_tag);
|
|
305
|
+
},
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
pub fn format(
|
|
310
|
+
event: *const EventTiming,
|
|
311
|
+
comptime fmt: []const u8,
|
|
312
|
+
options: std.fmt.FormatOptions,
|
|
313
|
+
writer: anytype,
|
|
314
|
+
) !void {
|
|
315
|
+
_ = fmt;
|
|
316
|
+
_ = options;
|
|
317
|
+
|
|
318
|
+
switch (event.*) {
|
|
319
|
+
inline else => |data| {
|
|
320
|
+
try format_data(data, writer);
|
|
321
|
+
},
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
pub const EventTracing = union(Event.Tag) {
|
|
327
|
+
replica_commit,
|
|
328
|
+
replica_aof_write,
|
|
329
|
+
replica_aof_checkpoint,
|
|
330
|
+
replica_sync_table: struct { index: usize },
|
|
331
|
+
replica_request,
|
|
332
|
+
replica_request_execute,
|
|
333
|
+
replica_request_local,
|
|
334
|
+
|
|
335
|
+
compact_beat,
|
|
336
|
+
compact_beat_merge,
|
|
337
|
+
compact_manifest,
|
|
338
|
+
compact_mutable,
|
|
339
|
+
compact_mutable_suffix,
|
|
340
|
+
|
|
341
|
+
lookup,
|
|
342
|
+
lookup_worker: struct { index: u8 },
|
|
343
|
+
|
|
344
|
+
scan_tree: struct { index: u8 },
|
|
345
|
+
scan_tree_level: struct { index: u8, level: u8 },
|
|
346
|
+
|
|
347
|
+
grid_read: struct { iop: usize },
|
|
348
|
+
grid_write: struct { iop: usize },
|
|
349
|
+
storage_read,
|
|
350
|
+
storage_write,
|
|
351
|
+
|
|
352
|
+
metrics_emit,
|
|
353
|
+
|
|
354
|
+
client_request_round_trip,
|
|
355
|
+
|
|
356
|
+
loop_run_for_ns,
|
|
357
|
+
loop_tick,
|
|
358
|
+
|
|
359
|
+
pub const stack_limits = std.enums.EnumArray(Event.Tag, u32).init(.{
|
|
360
|
+
.replica_commit = 1,
|
|
361
|
+
.replica_aof_write = 1,
|
|
362
|
+
.replica_aof_checkpoint = 1,
|
|
363
|
+
.replica_sync_table = constants.grid_missing_tables_max,
|
|
364
|
+
.replica_request = 1,
|
|
365
|
+
.replica_request_execute = 1,
|
|
366
|
+
.replica_request_local = 1,
|
|
367
|
+
.compact_beat = 1,
|
|
368
|
+
.compact_beat_merge = 1,
|
|
369
|
+
.compact_manifest = 1,
|
|
370
|
+
.compact_mutable = 1,
|
|
371
|
+
.compact_mutable_suffix = 1,
|
|
372
|
+
.lookup = 1,
|
|
373
|
+
.lookup_worker = constants.grid_iops_read_max,
|
|
374
|
+
.scan_tree = constants.lsm_scans_max,
|
|
375
|
+
.scan_tree_level = constants.lsm_scans_max * @as(u32, constants.lsm_levels),
|
|
376
|
+
.grid_read = constants.grid_iops_read_max,
|
|
377
|
+
.grid_write = constants.grid_iops_write_max,
|
|
378
|
+
.storage_read = 1,
|
|
379
|
+
.storage_write = 1,
|
|
380
|
+
.metrics_emit = 1,
|
|
381
|
+
.client_request_round_trip = 1,
|
|
382
|
+
.loop_run_for_ns = 1,
|
|
383
|
+
.loop_tick = 1,
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
pub const stack_bases = array: {
|
|
387
|
+
var array = std.enums.EnumArray(Event.Tag, u32).initDefault(0, .{});
|
|
388
|
+
var next: u32 = 0;
|
|
389
|
+
for (std.enums.values(Event.Tag)) |event_type| {
|
|
390
|
+
array.set(event_type, next);
|
|
391
|
+
next += stack_limits.get(event_type);
|
|
392
|
+
}
|
|
393
|
+
break :array array;
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
pub const stack_count = count: {
|
|
397
|
+
var count: u32 = 0;
|
|
398
|
+
for (std.enums.values(Event.Tag)) |event_type| {
|
|
399
|
+
count += stack_limits.get(event_type);
|
|
400
|
+
}
|
|
401
|
+
break :count count;
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
// Stack is a u32 since it must be losslessly encoded as a JSON integer.
|
|
405
|
+
pub fn stack(event: *const EventTracing) u32 {
|
|
406
|
+
switch (event.*) {
|
|
407
|
+
inline .replica_sync_table,
|
|
408
|
+
.lookup_worker,
|
|
409
|
+
=> |data| {
|
|
410
|
+
assert(data.index < stack_limits.get(event.*));
|
|
411
|
+
const stack_base = stack_bases.get(event.*);
|
|
412
|
+
return stack_base + @as(u32, @intCast(data.index));
|
|
413
|
+
},
|
|
414
|
+
.scan_tree => |data| {
|
|
415
|
+
assert(data.index < constants.lsm_scans_max);
|
|
416
|
+
// This event has "nested" sub-events, so its offset is calculated
|
|
417
|
+
// with padding to accommodate `scan_tree_level` events in between.
|
|
418
|
+
const stack_base = stack_bases.get(event.*);
|
|
419
|
+
const scan_tree_offset = (constants.lsm_levels + 1) * data.index;
|
|
420
|
+
return stack_base + scan_tree_offset;
|
|
421
|
+
},
|
|
422
|
+
.scan_tree_level => |data| {
|
|
423
|
+
assert(data.index < constants.lsm_scans_max);
|
|
424
|
+
assert(data.level < constants.lsm_levels);
|
|
425
|
+
// This is a "nested" event, so its offset is calculated
|
|
426
|
+
// relative to the parent `scan_tree`'s offset.
|
|
427
|
+
const stack_base = stack_bases.get(.scan_tree);
|
|
428
|
+
const scan_tree_offset = (constants.lsm_levels + 1) * data.index;
|
|
429
|
+
const scan_tree_level_offset = data.level + 1;
|
|
430
|
+
return stack_base + scan_tree_offset + scan_tree_level_offset;
|
|
431
|
+
},
|
|
432
|
+
inline .grid_read, .grid_write => |data| {
|
|
433
|
+
assert(data.iop < stack_limits.get(event.*));
|
|
434
|
+
const stack_base = stack_bases.get(event.*);
|
|
435
|
+
return stack_base + @as(u32, @intCast(data.iop));
|
|
436
|
+
},
|
|
437
|
+
inline else => |data, event_tag| {
|
|
438
|
+
comptime assert(@TypeOf(data) == void);
|
|
439
|
+
comptime assert(stack_limits.get(event_tag) == 1);
|
|
440
|
+
return comptime stack_bases.get(event_tag);
|
|
441
|
+
},
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
pub fn format(
|
|
446
|
+
event: *const EventTracing,
|
|
447
|
+
comptime fmt: []const u8,
|
|
448
|
+
options: std.fmt.FormatOptions,
|
|
449
|
+
writer: anytype,
|
|
450
|
+
) !void {
|
|
451
|
+
_ = fmt;
|
|
452
|
+
_ = options;
|
|
453
|
+
|
|
454
|
+
switch (event.*) {
|
|
455
|
+
inline else => |data| {
|
|
456
|
+
try format_data(data, writer);
|
|
457
|
+
},
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Some traces are very frequent, and would otherwise drown out useful information. These can be
|
|
462
|
+
// captured in aggregate only, meaning that the aggregate timing statistics will still be
|
|
463
|
+
// captured, but no per trace logs or JSON will be emitted.
|
|
464
|
+
pub fn aggregate_only(event: *const EventTracing) bool {
|
|
465
|
+
return switch (event.*) {
|
|
466
|
+
.loop_run_for_ns, .loop_tick => true,
|
|
467
|
+
else => false,
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
pub const EventMetric = union(enum) {
|
|
473
|
+
const Tag = std.meta.Tag(EventMetric);
|
|
474
|
+
|
|
475
|
+
table_count_visible: struct { tree: TreeEnum },
|
|
476
|
+
table_count_visible_max: struct { tree: TreeEnum },
|
|
477
|
+
replica_status,
|
|
478
|
+
replica_view,
|
|
479
|
+
replica_log_view,
|
|
480
|
+
replica_op,
|
|
481
|
+
replica_op_checkpoint,
|
|
482
|
+
replica_commit_min,
|
|
483
|
+
replica_commit_max,
|
|
484
|
+
replica_commit_timestamp,
|
|
485
|
+
replica_pipeline_queue_length,
|
|
486
|
+
replica_sync_stage,
|
|
487
|
+
replica_sync_op_min,
|
|
488
|
+
replica_sync_op_max,
|
|
489
|
+
replica_messages_in: struct { command: Command },
|
|
490
|
+
replica_messages_out: struct { command: Command },
|
|
491
|
+
journal_dirty,
|
|
492
|
+
journal_faulty,
|
|
493
|
+
grid_blocks_acquired,
|
|
494
|
+
grid_blocks_missing,
|
|
495
|
+
grid_cache_hits,
|
|
496
|
+
grid_cache_misses,
|
|
497
|
+
lsm_nodes_free,
|
|
498
|
+
lsm_manifest_block_count,
|
|
499
|
+
metrics_statsd_packets,
|
|
500
|
+
release,
|
|
501
|
+
clock_delta_ns,
|
|
502
|
+
message_bus_connections: struct { peer: std.meta.Tag(Peer) },
|
|
503
|
+
message_bus_connections_max,
|
|
504
|
+
compaction_values_physical: struct { tree: TreeEnum },
|
|
505
|
+
compaction_values_logical: struct { tree: TreeEnum },
|
|
506
|
+
|
|
507
|
+
pub const slot_limits = std.enums.EnumArray(Tag, u32).init(.{
|
|
508
|
+
.table_count_visible = enum_count(TreeEnum),
|
|
509
|
+
.table_count_visible_max = enum_count(TreeEnum),
|
|
510
|
+
.replica_status = 1,
|
|
511
|
+
.replica_view = 1,
|
|
512
|
+
.replica_log_view = 1,
|
|
513
|
+
.replica_op = 1,
|
|
514
|
+
.replica_op_checkpoint = 1,
|
|
515
|
+
.replica_commit_min = 1,
|
|
516
|
+
.replica_commit_max = 1,
|
|
517
|
+
.replica_commit_timestamp = 1,
|
|
518
|
+
.replica_pipeline_queue_length = 1,
|
|
519
|
+
.replica_sync_stage = 1,
|
|
520
|
+
.replica_sync_op_min = 1,
|
|
521
|
+
.replica_sync_op_max = 1,
|
|
522
|
+
.replica_messages_in = enum_count(Command),
|
|
523
|
+
.replica_messages_out = enum_count(Command),
|
|
524
|
+
.journal_dirty = 1,
|
|
525
|
+
.journal_faulty = 1,
|
|
526
|
+
.grid_blocks_acquired = 1,
|
|
527
|
+
.grid_blocks_missing = 1,
|
|
528
|
+
.grid_cache_hits = 1,
|
|
529
|
+
.grid_cache_misses = 1,
|
|
530
|
+
.lsm_nodes_free = 1,
|
|
531
|
+
.lsm_manifest_block_count = 1,
|
|
532
|
+
.metrics_statsd_packets = 1,
|
|
533
|
+
.release = 1,
|
|
534
|
+
.clock_delta_ns = 1,
|
|
535
|
+
.message_bus_connections = enum_count(Peer),
|
|
536
|
+
.message_bus_connections_max = 1,
|
|
537
|
+
.compaction_values_physical = enum_count(TreeEnum),
|
|
538
|
+
.compaction_values_logical = enum_count(TreeEnum),
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
pub const slot_bases = array: {
|
|
542
|
+
var array = std.enums.EnumArray(Tag, u32).initDefault(0, .{});
|
|
543
|
+
var next: u32 = 0;
|
|
544
|
+
for (std.enums.values(Tag)) |event_type| {
|
|
545
|
+
array.set(event_type, next);
|
|
546
|
+
next += slot_limits.get(event_type);
|
|
547
|
+
}
|
|
548
|
+
break :array array;
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
pub const slot_count = count: {
|
|
552
|
+
var count: u32 = 0;
|
|
553
|
+
for (std.enums.values(Tag)) |event_type| {
|
|
554
|
+
count += slot_limits.get(event_type);
|
|
555
|
+
}
|
|
556
|
+
break :count count;
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
pub fn slot(event: *const EventMetric) u32 {
|
|
560
|
+
switch (event.*) {
|
|
561
|
+
inline .table_count_visible,
|
|
562
|
+
.table_count_visible_max,
|
|
563
|
+
.compaction_values_physical,
|
|
564
|
+
.compaction_values_logical,
|
|
565
|
+
=> |data| {
|
|
566
|
+
const tree_id = index_from_enum(data.tree);
|
|
567
|
+
const offset = tree_id;
|
|
568
|
+
assert(offset < slot_limits.get(event.*));
|
|
569
|
+
|
|
570
|
+
return slot_bases.get(event.*) + offset;
|
|
571
|
+
},
|
|
572
|
+
inline .replica_messages_in, .replica_messages_out => |data| {
|
|
573
|
+
const command = index_from_enum(data.command);
|
|
574
|
+
const offset = command;
|
|
575
|
+
assert(offset < slot_limits.get(event.*));
|
|
576
|
+
|
|
577
|
+
return slot_bases.get(event.*) + offset;
|
|
578
|
+
},
|
|
579
|
+
inline .message_bus_connections => |data| {
|
|
580
|
+
const peer = index_from_enum(data.peer);
|
|
581
|
+
const offset = peer;
|
|
582
|
+
assert(offset < slot_limits.get(event.*));
|
|
583
|
+
|
|
584
|
+
return slot_bases.get(event.*) + offset;
|
|
585
|
+
},
|
|
586
|
+
else => {
|
|
587
|
+
return slot_bases.get(event.*);
|
|
588
|
+
},
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
pub fn format_data(
|
|
594
|
+
data: anytype,
|
|
595
|
+
writer: anytype,
|
|
596
|
+
) !void {
|
|
597
|
+
const Data = @TypeOf(data);
|
|
598
|
+
if (Data == void) return;
|
|
599
|
+
|
|
600
|
+
const fields = std.meta.fields(Data);
|
|
601
|
+
inline for (fields, 0..) |data_field, i| {
|
|
602
|
+
assert(data_field.type == bool or
|
|
603
|
+
@typeInfo(data_field.type) == .int or
|
|
604
|
+
@typeInfo(data_field.type) == .@"enum" or
|
|
605
|
+
@typeInfo(data_field.type) == .@"union");
|
|
606
|
+
|
|
607
|
+
const data_field_value = @field(data, data_field.name);
|
|
608
|
+
try writer.writeAll(data_field.name);
|
|
609
|
+
try writer.writeByte('=');
|
|
610
|
+
|
|
611
|
+
if (@typeInfo(data_field.type) == .@"enum" or
|
|
612
|
+
@typeInfo(data_field.type) == .@"union")
|
|
613
|
+
{
|
|
614
|
+
try writer.print("{s}", .{@tagName(data_field_value)});
|
|
615
|
+
} else {
|
|
616
|
+
try writer.print("{}", .{data_field_value});
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
if (i != fields.len - 1) {
|
|
620
|
+
try writer.writeByte(' ');
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
pub const EventTimingAggregate = struct {
|
|
626
|
+
event: EventTiming,
|
|
627
|
+
values: struct {
|
|
628
|
+
duration_min: Duration,
|
|
629
|
+
duration_max: Duration,
|
|
630
|
+
duration_sum: Duration,
|
|
631
|
+
|
|
632
|
+
count: u64,
|
|
633
|
+
},
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
pub const EventMetricAggregate = struct {
|
|
637
|
+
pub const ValueType = i65;
|
|
638
|
+
|
|
639
|
+
event: EventMetric,
|
|
640
|
+
value: ValueType,
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
test "EventMetric slot doesn't have collisions" {
|
|
644
|
+
const allocator = std.testing.allocator;
|
|
645
|
+
var stacks: std.ArrayListUnmanaged(u32) = .{};
|
|
646
|
+
defer stacks.deinit(allocator);
|
|
647
|
+
|
|
648
|
+
var g: @import("../testing/exhaustigen.zig") = .{};
|
|
649
|
+
while (!g.done()) {
|
|
650
|
+
const event: EventMetric = switch (g.enum_value(EventMetric.Tag)) {
|
|
651
|
+
.table_count_visible => .{ .table_count_visible = .{
|
|
652
|
+
.tree = g.enum_value(TreeEnum),
|
|
653
|
+
} },
|
|
654
|
+
.table_count_visible_max => .{ .table_count_visible_max = .{
|
|
655
|
+
.tree = g.enum_value(TreeEnum),
|
|
656
|
+
} },
|
|
657
|
+
.compaction_values_physical => .{ .compaction_values_physical = .{
|
|
658
|
+
.tree = g.enum_value(TreeEnum),
|
|
659
|
+
} },
|
|
660
|
+
.compaction_values_logical => .{ .compaction_values_logical = .{
|
|
661
|
+
.tree = g.enum_value(TreeEnum),
|
|
662
|
+
} },
|
|
663
|
+
.replica_messages_in => .{ .replica_messages_in = .{
|
|
664
|
+
.command = g.enum_value(Command),
|
|
665
|
+
} },
|
|
666
|
+
.replica_messages_out => .{ .replica_messages_out = .{
|
|
667
|
+
.command = g.enum_value(Command),
|
|
668
|
+
} },
|
|
669
|
+
.message_bus_connections => .{ .message_bus_connections = .{
|
|
670
|
+
.peer = g.enum_value(std.meta.Tag(Peer)),
|
|
671
|
+
} },
|
|
672
|
+
inline else => |tag| tag,
|
|
673
|
+
};
|
|
674
|
+
try stacks.append(allocator, event.slot());
|
|
675
|
+
}
|
|
676
|
+
for (0..stacks.items.len) |i| {
|
|
677
|
+
for (0..i) |j| {
|
|
678
|
+
assert(stacks.items[i] != stacks.items[j]);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
test "EventTiming slot doesn't have collisions" {
|
|
684
|
+
const allocator = std.testing.allocator;
|
|
685
|
+
var stacks: std.ArrayListUnmanaged(u32) = .{};
|
|
686
|
+
defer stacks.deinit(allocator);
|
|
687
|
+
|
|
688
|
+
var g: @import("../testing/exhaustigen.zig") = .{};
|
|
689
|
+
while (!g.done()) {
|
|
690
|
+
const event: EventTiming = switch (g.enum_value(Event.Tag)) {
|
|
691
|
+
.replica_commit => .{ .replica_commit = .{ .stage = g.enum_value(CommitStage.Tag) } },
|
|
692
|
+
.replica_aof_write => .replica_aof_write,
|
|
693
|
+
.replica_aof_checkpoint => .replica_aof_checkpoint,
|
|
694
|
+
.replica_sync_table => .replica_sync_table,
|
|
695
|
+
.replica_request => .{ .replica_request = .{ .operation = g.enum_value(Operation) } },
|
|
696
|
+
.replica_request_execute => .{ .replica_request_execute = .{
|
|
697
|
+
.operation = g.enum_value(Operation),
|
|
698
|
+
} },
|
|
699
|
+
.replica_request_local => .{ .replica_request_local = .{
|
|
700
|
+
.operation = g.enum_value(Operation),
|
|
701
|
+
} },
|
|
702
|
+
.compact_beat => .{ .compact_beat = .{
|
|
703
|
+
.tree = g.enum_value(TreeEnum),
|
|
704
|
+
} },
|
|
705
|
+
.compact_beat_merge => .{ .compact_beat_merge = .{
|
|
706
|
+
.tree = g.enum_value(TreeEnum),
|
|
707
|
+
} },
|
|
708
|
+
.compact_manifest => .compact_manifest,
|
|
709
|
+
.compact_mutable => .{ .compact_mutable = .{
|
|
710
|
+
.tree = g.enum_value(TreeEnum),
|
|
711
|
+
} },
|
|
712
|
+
.compact_mutable_suffix => .{ .compact_mutable_suffix = .{
|
|
713
|
+
.tree = g.enum_value(TreeEnum),
|
|
714
|
+
} },
|
|
715
|
+
.lookup => .{ .lookup = .{
|
|
716
|
+
.tree = g.enum_value(TreeEnum),
|
|
717
|
+
} },
|
|
718
|
+
.lookup_worker => .{ .lookup_worker = .{
|
|
719
|
+
.tree = g.enum_value(TreeEnum),
|
|
720
|
+
} },
|
|
721
|
+
.scan_tree => .{ .scan_tree = .{
|
|
722
|
+
.tree = g.enum_value(TreeEnum),
|
|
723
|
+
} },
|
|
724
|
+
.scan_tree_level => .{ .scan_tree_level = .{
|
|
725
|
+
.tree = g.enum_value(TreeEnum),
|
|
726
|
+
} },
|
|
727
|
+
.grid_read => .grid_read,
|
|
728
|
+
.grid_write => .grid_write,
|
|
729
|
+
.storage_read => .{ .storage_read = .{ .zone = g.enum_value(Zone) } },
|
|
730
|
+
.storage_write => .{ .storage_write = .{ .zone = g.enum_value(Zone) } },
|
|
731
|
+
.metrics_emit => .metrics_emit,
|
|
732
|
+
.client_request_round_trip => .{ .client_request_round_trip = .{
|
|
733
|
+
.operation = g.enum_value(Operation),
|
|
734
|
+
} },
|
|
735
|
+
.loop_run_for_ns => .loop_run_for_ns,
|
|
736
|
+
.loop_tick => .loop_tick,
|
|
737
|
+
};
|
|
738
|
+
try stacks.append(allocator, event.slot());
|
|
739
|
+
}
|
|
740
|
+
for (0..stacks.items.len) |i| {
|
|
741
|
+
for (0..i) |j| {
|
|
742
|
+
assert(stacks.items[i] != stacks.items[j]);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|