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,420 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const assert = std.debug.assert;
|
|
3
|
+
|
|
4
|
+
const stdx = @import("stdx");
|
|
5
|
+
const constants = @import("../constants.zig");
|
|
6
|
+
const fuzz = @import("../testing/fuzz.zig");
|
|
7
|
+
|
|
8
|
+
const TestTable = @import("cache_map.zig").TestTable;
|
|
9
|
+
const TestCacheMap = @import("cache_map.zig").TestCacheMap;
|
|
10
|
+
|
|
11
|
+
const log = std.log.scoped(.lsm_cache_map_fuzz);
|
|
12
|
+
const Key = TestTable.Key;
|
|
13
|
+
const Value = TestTable.Value;
|
|
14
|
+
|
|
15
|
+
const stash_value_count_max = 1024;
|
|
16
|
+
// Use a large scope (relative to stash_value_count_max) to increase the chances of
|
|
17
|
+
// (SetAssociativeCache) hash collisions.
|
|
18
|
+
const scope_value_count_max = stash_value_count_max;
|
|
19
|
+
|
|
20
|
+
const OpValue = struct {
|
|
21
|
+
op: u32,
|
|
22
|
+
value: Value,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const FuzzOpTag = std.meta.Tag(FuzzOp);
|
|
26
|
+
const FuzzOp = union(enum) {
|
|
27
|
+
compact,
|
|
28
|
+
get: Key,
|
|
29
|
+
upsert: Value,
|
|
30
|
+
remove: Key,
|
|
31
|
+
scope: enum { open, persist, discard },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const Environment = struct {
|
|
35
|
+
cache_map: TestCacheMap,
|
|
36
|
+
model: Model,
|
|
37
|
+
|
|
38
|
+
pub fn init(gpa: std.mem.Allocator, options: TestCacheMap.Options) !Environment {
|
|
39
|
+
var cache_map = try TestCacheMap.init(gpa, options);
|
|
40
|
+
errdefer cache_map.deinit(gpa);
|
|
41
|
+
|
|
42
|
+
var model = Model.init(gpa);
|
|
43
|
+
errdefer model.deinit(gpa);
|
|
44
|
+
|
|
45
|
+
return Environment{
|
|
46
|
+
.cache_map = cache_map,
|
|
47
|
+
.model = model,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
pub fn deinit(self: *Environment, gpa: std.mem.Allocator) void {
|
|
52
|
+
self.model.deinit();
|
|
53
|
+
self.cache_map.deinit(gpa);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
pub fn apply(env: *Environment, fuzz_ops: []const FuzzOp) !void {
|
|
57
|
+
// The cache_map should behave exactly like a hash map, with some exceptions:
|
|
58
|
+
// * .compact() removes values added more than one .compact() ago.
|
|
59
|
+
// * .scope_close(.discard) rolls back all operations done from the corresponding
|
|
60
|
+
// .scope_open()
|
|
61
|
+
|
|
62
|
+
for (fuzz_ops, 0..) |fuzz_op, fuzz_op_index| {
|
|
63
|
+
log.debug("Running fuzz_ops[{}/{}] == {}", .{ fuzz_op_index, fuzz_ops.len, fuzz_op });
|
|
64
|
+
|
|
65
|
+
// Apply fuzz_op to the tree and the model.
|
|
66
|
+
switch (fuzz_op) {
|
|
67
|
+
.compact => {
|
|
68
|
+
env.cache_map.compact();
|
|
69
|
+
env.model.compact();
|
|
70
|
+
},
|
|
71
|
+
.upsert => |value| {
|
|
72
|
+
env.cache_map.upsert(&value);
|
|
73
|
+
try env.model.upsert(&value);
|
|
74
|
+
},
|
|
75
|
+
.remove => |key| {
|
|
76
|
+
env.cache_map.remove(key);
|
|
77
|
+
try env.model.remove(key);
|
|
78
|
+
},
|
|
79
|
+
.get => |key| {
|
|
80
|
+
// Get account from cache_map.
|
|
81
|
+
const cache_map_value = env.cache_map.get(key);
|
|
82
|
+
|
|
83
|
+
// Compare result to model.
|
|
84
|
+
const model_value = env.model.get(key);
|
|
85
|
+
if (model_value == null) {
|
|
86
|
+
assert(cache_map_value == null);
|
|
87
|
+
} else if (env.model.compacts > model_value.?.op) {
|
|
88
|
+
// .compact() support; if the entry has an op 1 or more compacts ago, it
|
|
89
|
+
// doesn't have to exist in the cache_map. It may still be served from the
|
|
90
|
+
// cache layer, however.
|
|
91
|
+
stdx.maybe(cache_map_value == null);
|
|
92
|
+
if (cache_map_value) |cache_map_value_unwrapped| {
|
|
93
|
+
assert(std.meta.eql(cache_map_value_unwrapped.*, model_value.?.value));
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
assert(std.meta.eql(model_value.?.value, cache_map_value.?.*));
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
.scope => |mode| switch (mode) {
|
|
100
|
+
.open => {
|
|
101
|
+
env.cache_map.scope_open();
|
|
102
|
+
env.model.scope_open();
|
|
103
|
+
},
|
|
104
|
+
.persist => {
|
|
105
|
+
env.cache_map.scope_close(.persist);
|
|
106
|
+
try env.model.scope_close(.persist);
|
|
107
|
+
},
|
|
108
|
+
.discard => {
|
|
109
|
+
env.cache_map.scope_close(.discard);
|
|
110
|
+
try env.model.scope_close(.discard);
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// Verifies both the positive and negative spaces, as both are equally important. We verify
|
|
118
|
+
/// the positive space by iterating over our model, and ensuring everything exists and is
|
|
119
|
+
/// equal in the cache_map.
|
|
120
|
+
///
|
|
121
|
+
/// We verify the negative space by iterating over the cache_map's cache and maps directly,
|
|
122
|
+
/// ensuring that:
|
|
123
|
+
/// 1. The values in the cache all exist and are equal in the model.
|
|
124
|
+
/// 2. The values in stash either exists and are equal in the model, or there's the same key
|
|
125
|
+
/// in the cache.
|
|
126
|
+
/// 3. The values in stash_2 either exists and are equal in the model, or there's the same key
|
|
127
|
+
/// in stash_1 or the cache.
|
|
128
|
+
pub fn verify(env: *Environment) void {
|
|
129
|
+
var checked: u32 = 0;
|
|
130
|
+
var it = env.model.iterator();
|
|
131
|
+
while (it.next()) |kv| {
|
|
132
|
+
// Compare from cache_map, if found:
|
|
133
|
+
const cache_map_value = env.cache_map.get(kv.key_ptr.*);
|
|
134
|
+
stdx.maybe(cache_map_value != null);
|
|
135
|
+
if (cache_map_value) |cache_map_value_unwrapped| {
|
|
136
|
+
assert(std.meta.eql(kv.value_ptr.value, cache_map_value_unwrapped.*));
|
|
137
|
+
} else {
|
|
138
|
+
// .compact() support:
|
|
139
|
+
assert(env.model.compacts > kv.value_ptr.op);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
checked += 1;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
log.info("Verified {} items from model exist and match in cache_map.", .{checked});
|
|
146
|
+
|
|
147
|
+
// It's fine for the cache_map to have values older than .compact() in it; good, in fact,
|
|
148
|
+
// but they _MUST NOT_ be stale.
|
|
149
|
+
if (env.cache_map.cache) |*cache| {
|
|
150
|
+
for (cache.values, 0..) |*cache_value, i| {
|
|
151
|
+
// If the count for an index is 0, the value doesn't exist.
|
|
152
|
+
if (cache.counts.get(i) == 0) {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const model_val = env.model.get(TestTable.key_from_value(cache_value));
|
|
157
|
+
assert(std.meta.eql(cache_value.*, model_val.?.value));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// The stash can have stale values, but in that case the real value _must_ exist
|
|
162
|
+
// in the cache. It should be impossible for the stash to have a value that isn't in the
|
|
163
|
+
// model, since cache_map.remove() removes from both the cache and stash.
|
|
164
|
+
var stash_iterator = env.cache_map.stash.keyIterator();
|
|
165
|
+
while (stash_iterator.next()) |stash_value| {
|
|
166
|
+
// Get account from model.
|
|
167
|
+
const model_value = env.model.get(TestTable.key_from_value(stash_value));
|
|
168
|
+
|
|
169
|
+
// Even if the stash has stale values, the key must still exist in the model.
|
|
170
|
+
assert(model_value != null);
|
|
171
|
+
|
|
172
|
+
const stash_value_equal = std.meta.eql(stash_value.*, model_value.?.value);
|
|
173
|
+
|
|
174
|
+
if (!stash_value_equal) {
|
|
175
|
+
if (env.cache_map.cache) |*cache| {
|
|
176
|
+
// We verified all cache entries were equal and correct above, so if it exists,
|
|
177
|
+
// it must be right.
|
|
178
|
+
const cache_value = cache.get(
|
|
179
|
+
TestTable.key_from_value(stash_value),
|
|
180
|
+
);
|
|
181
|
+
assert(cache_value != null);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
log.info(
|
|
187
|
+
"Verified all items in the cache and stash exist and match the model.",
|
|
188
|
+
.{},
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const Model = struct {
|
|
194
|
+
const Map = std.hash_map.AutoHashMap(Key, OpValue);
|
|
195
|
+
const UndoLog = std.ArrayList(struct {
|
|
196
|
+
key: Key,
|
|
197
|
+
value: ?OpValue,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
map: Map,
|
|
201
|
+
undo_log: UndoLog,
|
|
202
|
+
scope_active: bool = false,
|
|
203
|
+
compacts: u32 = 0,
|
|
204
|
+
|
|
205
|
+
fn init(gpa: std.mem.Allocator) Model {
|
|
206
|
+
return .{
|
|
207
|
+
.map = Map.init(gpa),
|
|
208
|
+
.undo_log = UndoLog.init(gpa),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
fn deinit(model: *Model) void {
|
|
213
|
+
model.undo_log.deinit();
|
|
214
|
+
model.map.deinit();
|
|
215
|
+
model.* = undefined;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
fn get(model: *Model, key: Key) ?*OpValue {
|
|
219
|
+
return model.map.getPtr(key);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
fn iterator(model: *Model) Map.Iterator {
|
|
223
|
+
return model.map.iterator();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
fn upsert(model: *Model, value: *const Value) !void {
|
|
227
|
+
const key = TestTable.key_from_value(value);
|
|
228
|
+
const kv_old = try model.map.fetchPut(
|
|
229
|
+
key,
|
|
230
|
+
.{ .op = model.compacts, .value = value.* },
|
|
231
|
+
);
|
|
232
|
+
if (model.scope_active) {
|
|
233
|
+
try model.undo_log.append(.{
|
|
234
|
+
.key = key,
|
|
235
|
+
.value = if (kv_old) |kv| kv.value else null,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
fn remove(model: *Model, key: Key) !void {
|
|
241
|
+
const kv_old = model.map.fetchRemove(key);
|
|
242
|
+
if (model.scope_active) {
|
|
243
|
+
try model.undo_log.append(.{
|
|
244
|
+
.key = key,
|
|
245
|
+
.value = if (kv_old) |kv| kv.value else null,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
fn compact(model: *Model) void {
|
|
251
|
+
assert(!model.scope_active);
|
|
252
|
+
model.compacts += 1;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
fn scope_open(model: *Model) void {
|
|
256
|
+
assert(!model.scope_active);
|
|
257
|
+
assert(model.undo_log.items.len == 0);
|
|
258
|
+
model.scope_active = true;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
fn scope_close(model: *Model, mode: enum { persist, discard }) !void {
|
|
262
|
+
assert(model.scope_active);
|
|
263
|
+
model.scope_active = false;
|
|
264
|
+
defer assert(model.undo_log.items.len == 0);
|
|
265
|
+
|
|
266
|
+
switch (mode) {
|
|
267
|
+
.discard => while (model.undo_log.pop()) |undo_entry| {
|
|
268
|
+
if (undo_entry.value) |value| {
|
|
269
|
+
try model.map.put(undo_entry.key, value);
|
|
270
|
+
} else {
|
|
271
|
+
_ = model.map.remove(undo_entry.key);
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
.persist => model.undo_log.clearRetainingCapacity(),
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
fn random_id(prng: *stdx.PRNG) u32 {
|
|
280
|
+
return fuzz.random_id(prng, u32, .{
|
|
281
|
+
.average_hot = 8,
|
|
282
|
+
.average_cold = scope_value_count_max + stash_value_count_max +
|
|
283
|
+
TestCacheMap.Cache.value_count_max_multiple,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
pub fn generate_fuzz_ops(
|
|
288
|
+
gpa: std.mem.Allocator,
|
|
289
|
+
prng: *stdx.PRNG,
|
|
290
|
+
fuzz_op_count: usize,
|
|
291
|
+
) ![]const FuzzOp {
|
|
292
|
+
log.info("fuzz_op_count = {}", .{fuzz_op_count});
|
|
293
|
+
|
|
294
|
+
const fuzz_ops = try gpa.alloc(FuzzOp, fuzz_op_count);
|
|
295
|
+
errdefer gpa.free(fuzz_ops);
|
|
296
|
+
|
|
297
|
+
const fuzz_op_weights = stdx.PRNG.EnumWeightsType(FuzzOpTag){
|
|
298
|
+
// Always do puts, and always more puts than removes.
|
|
299
|
+
.upsert = constants.lsm_compaction_ops * 2,
|
|
300
|
+
// Maybe do some removes.
|
|
301
|
+
.remove = if (prng.boolean()) 0 else constants.lsm_compaction_ops,
|
|
302
|
+
// Maybe do some gets.
|
|
303
|
+
.get = if (prng.boolean()) 0 else constants.lsm_compaction_ops,
|
|
304
|
+
// Maybe do some extra compacts.
|
|
305
|
+
.compact = if (prng.boolean()) 0 else 2,
|
|
306
|
+
// Maybe use scopes.
|
|
307
|
+
.scope = if (prng.boolean()) 0 else @divExact(constants.lsm_compaction_ops, 4),
|
|
308
|
+
};
|
|
309
|
+
log.info("fuzz_op_weights = {:.2}", .{fuzz_op_weights});
|
|
310
|
+
|
|
311
|
+
// TODO: Is there a point to making _max random (both here and in .init) and anything less than
|
|
312
|
+
// the maximum capacity...?
|
|
313
|
+
var op: u64 = 0;
|
|
314
|
+
var operations_since_scope_open: usize = 0;
|
|
315
|
+
const operations_since_scope_open_max: usize = scope_value_count_max;
|
|
316
|
+
var upserts_since_compact: usize = 0;
|
|
317
|
+
const upserts_since_compact_max: usize = stash_value_count_max;
|
|
318
|
+
var scope_is_open = false;
|
|
319
|
+
for (fuzz_ops, 0..) |*fuzz_op, i| {
|
|
320
|
+
var fuzz_op_tag: FuzzOpTag = undefined;
|
|
321
|
+
if (upserts_since_compact >= upserts_since_compact_max) {
|
|
322
|
+
// We have to compact before doing any other operations, but the scope must be closed.
|
|
323
|
+
fuzz_op_tag = FuzzOpTag.compact;
|
|
324
|
+
|
|
325
|
+
if (scope_is_open) {
|
|
326
|
+
fuzz_op_tag = FuzzOpTag.scope;
|
|
327
|
+
}
|
|
328
|
+
} else if (operations_since_scope_open >= operations_since_scope_open_max) {
|
|
329
|
+
// We have to close our scope before doing anything else.
|
|
330
|
+
fuzz_op_tag = FuzzOpTag.scope;
|
|
331
|
+
} else if (i == fuzz_ops.len - 1 and scope_is_open) {
|
|
332
|
+
// Ensure we close scope before ending.
|
|
333
|
+
fuzz_op_tag = FuzzOpTag.scope;
|
|
334
|
+
} else if (scope_is_open) {
|
|
335
|
+
fuzz_op_tag = prng.enum_weighted(FuzzOpTag, fuzz_op_weights);
|
|
336
|
+
if (fuzz_op_tag == FuzzOpTag.compact) {
|
|
337
|
+
// We can't compact while a scope is open.
|
|
338
|
+
fuzz_op_tag = FuzzOpTag.scope;
|
|
339
|
+
}
|
|
340
|
+
} else {
|
|
341
|
+
// Otherwise pick a random FuzzOp.
|
|
342
|
+
fuzz_op_tag = prng.enum_weighted(FuzzOpTag, fuzz_op_weights);
|
|
343
|
+
if (i == fuzz_ops.len - 1 and fuzz_op_tag == FuzzOpTag.scope) {
|
|
344
|
+
// We can't let our final operation be a scope open.
|
|
345
|
+
fuzz_op_tag = FuzzOpTag.get;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
fuzz_op.* = switch (fuzz_op_tag) {
|
|
350
|
+
.upsert => blk: {
|
|
351
|
+
upserts_since_compact += 1;
|
|
352
|
+
|
|
353
|
+
if (scope_is_open) {
|
|
354
|
+
operations_since_scope_open += 1;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
break :blk FuzzOp{ .upsert = .{
|
|
358
|
+
.key = random_id(prng),
|
|
359
|
+
.value = prng.int(u32),
|
|
360
|
+
} };
|
|
361
|
+
},
|
|
362
|
+
.remove => blk: {
|
|
363
|
+
if (scope_is_open) {
|
|
364
|
+
operations_since_scope_open += 1;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
break :blk FuzzOp{ .remove = random_id(prng) };
|
|
368
|
+
},
|
|
369
|
+
.get => FuzzOp{ .get = random_id(prng) },
|
|
370
|
+
.compact => blk: {
|
|
371
|
+
upserts_since_compact = 0;
|
|
372
|
+
op += 1;
|
|
373
|
+
|
|
374
|
+
break :blk FuzzOp{ .compact = {} };
|
|
375
|
+
},
|
|
376
|
+
.scope => blk: {
|
|
377
|
+
operations_since_scope_open = 0;
|
|
378
|
+
defer scope_is_open = !scope_is_open;
|
|
379
|
+
|
|
380
|
+
if (scope_is_open) {
|
|
381
|
+
break :blk FuzzOp{ .scope = if (prng.boolean()) .persist else .discard };
|
|
382
|
+
} else {
|
|
383
|
+
break :blk FuzzOp{ .scope = .open };
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return fuzz_ops;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
pub fn main(gpa: std.mem.Allocator, fuzz_args: fuzz.FuzzArgs) !void {
|
|
393
|
+
var prng = stdx.PRNG.from_seed(fuzz_args.seed);
|
|
394
|
+
|
|
395
|
+
const fuzz_op_count = @min(
|
|
396
|
+
fuzz_args.events_max orelse @as(usize, 1E9),
|
|
397
|
+
fuzz.random_int_exponential(&prng, usize, 1E8),
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
const fuzz_ops = try generate_fuzz_ops(gpa, &prng, fuzz_op_count);
|
|
401
|
+
defer gpa.free(fuzz_ops);
|
|
402
|
+
|
|
403
|
+
// Running the same fuzz with and without cache enabled.
|
|
404
|
+
inline for (&.{ TestCacheMap.Cache.value_count_max_multiple, 0 }) |cache_value_count_max| {
|
|
405
|
+
const options = TestCacheMap.Options{
|
|
406
|
+
.cache_value_count_max = cache_value_count_max,
|
|
407
|
+
.stash_value_count_max = stash_value_count_max,
|
|
408
|
+
.scope_value_count_max = scope_value_count_max,
|
|
409
|
+
.name = "fuzz map",
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
var env = try Environment.init(gpa, options);
|
|
413
|
+
defer env.deinit(gpa);
|
|
414
|
+
|
|
415
|
+
try env.apply(fuzz_ops);
|
|
416
|
+
env.verify();
|
|
417
|
+
|
|
418
|
+
log.info("Passed {any}!", .{options});
|
|
419
|
+
}
|
|
420
|
+
}
|