pigeonhole-db 1.1.0
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 +7 -0
- data/Cargo.lock +899 -0
- data/Cargo.toml +45 -0
- data/LICENSE +21 -0
- data/README.md +22 -0
- data/extconf.rb +12 -0
- data/lib/pigeonhole/api.rb +615 -0
- data/lib/pigeonhole/index.rb +208 -0
- data/lib/pigeonhole/memory.rb +507 -0
- data/lib/pigeonhole/version.rb +6 -0
- data/lib/pigeonhole-db.rb +6 -0
- data/lib/pigeonhole.rb +47 -0
- data/sig/pigeonhole.rbs +1484 -0
- data/src/budget.rs +205 -0
- data/src/classes.rs +279 -0
- data/src/convert.rs +192 -0
- data/src/db.rs +685 -0
- data/src/error.rs +151 -0
- data/src/feed.rs +316 -0
- data/src/fork.rs +64 -0
- data/src/gvl.rs +112 -0
- data/src/index.rs +1157 -0
- data/src/lib.rs +534 -0
- data/src/memory.rs +2178 -0
- data/src/read.rs +312 -0
- data/src/table.rs +1161 -0
- data/src/vector.rs +262 -0
- data/src/walk.rs +406 -0
- data/vendor/bundle/ruby/3.4.0/bin/minitest +29 -0
- data/vendor/bundle/ruby/3.4.0/bin/rake +29 -0
- data/vendor/bundle/ruby/3.4.0/bin/rake-compiler +29 -0
- data/vendor/bundle/ruby/3.4.0/bin/rake-compiler-dock +29 -0
- data/vendor/bundle/ruby/3.4.0/bin/rb-sys-dock +29 -0
- data/vendor/bundle/ruby/3.4.0/bin/rbs +29 -0
- data/vendor/bundle/ruby/3.4.0/cache/drb-2.2.3.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/logger-1.7.0.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/minitest-6.0.6.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/prism-1.9.0.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/rake-13.4.2.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/rake-compiler-1.3.2.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/rake-compiler-dock-1.12.0.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/rb_sys-0.9.130.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/rbs-4.2.0.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/toml-rb-6.0.0.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/cache/tsort-0.2.0.gem +0 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.9.0/gem.build_complete +0 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.9.0/gem_make.out +44 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.9.0/mkmf.log +74 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.9.0/prism/prism.so +0 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/rbs-4.2.0/gem.build_complete +0 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/rbs-4.2.0/gem_make.out +41 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/rbs-4.2.0/mkmf.log +102 -0
- data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/rbs-4.2.0/rbs_extension.so +0 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/LICENSE.txt +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/drb.gemspec +42 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/acl.rb +239 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/drb.rb +1993 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/eq.rb +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extserv.rb +44 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extservm.rb +94 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/gw.rb +161 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/observer.rb +26 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/ssl.rb +354 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/timeridconv.rb +97 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/unix.rb +118 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/version.rb +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/weakidconv.rb +31 -0
- data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb.rb +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md +104 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/errors.rb +9 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/formatter.rb +36 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/log_device.rb +265 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/period.rb +47 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/severity.rb +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/version.rb +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb +789 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/History.rdoc +1860 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/Manifest.txt +41 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/README.rdoc +763 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/Rakefile +89 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/bin/minitest +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/design_rationale.rb +54 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/hoe/minitest.rb +30 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/assertions.rb +821 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/autorun.rb +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/benchmark.rb +452 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/bisect.rb +304 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/complete.rb +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/compress.rb +94 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/error_on_warning.rb +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/expectations.rb +321 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/find_minimal_combination.rb +127 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/hell.rb +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/manual_plugins.rb +4 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/parallel.rb +72 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/path_expander.rb +432 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/pride.rb +4 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/pride_plugin.rb +135 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/server.rb +49 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/server_plugin.rb +88 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/spec.rb +324 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/sprint.rb +105 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/sprint_plugin.rb +39 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/test.rb +232 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/test_task.rb +331 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest.rb +1232 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/metametameta.rb +150 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_bisect.rb +249 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_find_minimal_combination.rb +138 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_assertions.rb +1729 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_benchmark.rb +151 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_reporter.rb +437 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_spec.rb +1095 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_test.rb +1295 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_test_task.rb +57 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_path_expander.rb +229 -0
- data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_server.rb +146 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/BSDmakefile +58 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/CHANGELOG.md +786 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/CODE_OF_CONDUCT.md +76 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/CONTRIBUTING.md +58 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/LICENSE.md +7 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/Makefile +116 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/README.md +143 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/config.yml +4739 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/build_system.md +119 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/configuration.md +68 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/cruby_compilation.md +27 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/design.md +53 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/encoding.md +121 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/fuzzing.md +88 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/heredocs.md +36 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/javascript.md +118 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/local_variable_depth.md +229 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/mapping.md +117 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/parser_translation.md +24 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/parsing_rules.md +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/releasing.md +75 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/relocation.md +34 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/ripper_translation.md +63 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/ruby_api.md +45 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/ruby_parser_translation.md +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/serialization.md +233 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/testing.md +55 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/Makefile +273 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/api_node.c +6945 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/api_pack.c +276 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/extconf.rb +127 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/extension.c +1427 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/extension.h +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/ast.h +8254 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/defines.h +260 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/diagnostic.h +458 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/encoding.h +283 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/node.h +129 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/options.h +488 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/pack.h +163 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/parser.h +936 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/prettyprint.h +34 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/regexp.h +43 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/static_literals.h +121 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_buffer.h +236 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_char.h +204 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_constant_pool.h +218 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_integer.h +130 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_list.h +103 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_memchr.h +29 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_newline_list.h +113 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_string.h +200 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_strncasecmp.h +32 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_strpbrk.h +46 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/version.h +29 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism.h +408 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/compiler.rb +801 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/desugar_compiler.rb +392 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/dispatcher.rb +2210 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/dot_visitor.rb +4767 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/dsl.rb +1003 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/ffi.rb +578 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/inspect_visitor.rb +2393 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/lex_compat.rb +911 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/mutation_compiler.rb +772 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/node.rb +19966 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/node_ext.rb +511 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/pack.rb +230 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/parse_result/comments.rb +188 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/parse_result/errors.rb +66 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/parse_result/newlines.rb +155 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/parse_result.rb +907 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/pattern.rb +269 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/append_as_bytes.rb +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/byteindex.rb +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/scan_byte.rb +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/unpack1.rb +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/warn.rb +36 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/prism.so +0 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/reflection.rb +416 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/relocation.rb +505 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/serialize.rb +2400 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/string_query.rb +31 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser/builder.rb +62 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser/compiler.rb +2234 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser/lexer.rb +820 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser.rb +376 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser_current.rb +26 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser_versions.rb +36 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper/filter.rb +53 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper/lexer.rb +135 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper/sexp.rb +126 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper/shim.rb +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper.rb +3520 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ruby_parser.rb +1964 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation.rb +18 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/visitor.rb +813 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism.rb +98 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/prism.gemspec +172 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/compiler.rbi +12 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/dsl.rbi +524 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/inspect_visitor.rbi +12 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/node.rbi +8750 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/node_ext.rbi +107 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/parse_result.rbi +404 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/reflection.rbi +58 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/string_query.rbi +12 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/translation/parser.rbi +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/translation/parser_versions.rbi +23 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/translation/ripper.rbi +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/visitor.rbi +473 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism.rbi +63 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/compiler.rbs +9 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/dispatcher.rbs +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/dot_visitor.rbs +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/dsl.rbs +351 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/inspect_visitor.rbs +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/lex_compat.rbs +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/mutation_compiler.rbs +159 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/node.rbs +4042 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/node_ext.rbs +149 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/pack.rbs +43 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/parse_result/comments.rbs +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/parse_result.rbs +197 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/pattern.rbs +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/reflection.rbs +50 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/relocation.rbs +185 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/serialize.rbs +8 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/string_query.rbs +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/visitor.rbs +169 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism.rbs +272 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/diagnostic.c +854 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/encoding.c +5340 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/node.c +8685 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/options.c +338 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/pack.c +509 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/prettyprint.c +8957 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/prism.c +22679 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/regexp.c +790 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/serialize.c +2274 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/static_literals.c +617 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/token_type.c +703 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_buffer.c +357 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_char.c +318 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_constant_pool.c +342 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_integer.c +670 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_list.c +49 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_memchr.c +35 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_newline_list.c +125 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_string.c +381 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_strncasecmp.c +36 -0
- data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_strpbrk.c +206 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/History.rdoc +2454 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/MIT-LICENSE +21 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/README.rdoc +155 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/command_line_usage.rdoc +171 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile1 +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile2 +35 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/a.c +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/b.c +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/main.c +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/glossary.rdoc +42 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/jamis.rb +592 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/proto_rake.rdoc +127 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rake.1 +156 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rakefile.rdoc +635 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rational.rdoc +151 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/exe/rake +27 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb +847 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/backtrace.rb +25 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/clean.rb +78 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cloneable.rb +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb +122 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/default_loader.rb +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/dsl_definition.rb +196 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/early_time.rb +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/core.rb +26 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/string.rb +176 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_creation_task.rb +25 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_list.rb +435 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_task.rb +58 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils.rb +137 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils_ext.rb +135 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_chain.rb +57 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_exception_mixin.rb +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/late_time.rb +18 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/linked_list.rb +112 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/loaders/makefile.rb +54 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/multi_task.rb +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/name_space.rb +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/options.rb +31 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/packagetask.rb +222 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/phony.rb +16 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/private_reader.rb +21 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/promise.rb +100 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/pseudo_status.rb +30 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_module.rb +67 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_test_loader.rb +27 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rule_recursion_overflow_error.rb +20 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/scope.rb +43 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb +434 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_argument_error.rb +8 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_arguments.rb +113 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_manager.rb +333 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/tasklib.rb +12 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/testtask.rb +192 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_history_display.rb +49 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_pool.rb +157 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/trace_output.rb +23 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/version.rb +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/win32.rb +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake.rb +69 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/rake.gemspec +102 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/Gemfile +8 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/History.md +708 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/LICENSE.txt +20 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/README.md +505 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/Rakefile +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/appveyor.yml +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/bin/rake-compiler +24 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/cucumber.yml +4 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/compile.feature +79 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/cross-compile.feature +23 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/cross-package-multi.feature +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/cross-package.feature +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/java-compile.feature +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/java-no-native-compile.feature +33 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/java-package.feature +24 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/package.feature +40 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/compilation.rb +70 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/cross_compilation.rb +27 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/execution.rb +52 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/folders.rb +32 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/gem.rb +46 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/java_compilation.rb +7 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/support/env.rb +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/support/file_template_helpers.rb +137 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/support/generator_helpers.rb +123 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/support/platform_extension_helpers.rb +27 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/baseextensiontask.rb +90 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/compiler_config.rb +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/extensioncompiler.rb +51 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/extensiontask.rb +621 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/javaextensiontask.rb +321 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/bin/cross-ruby.rake +189 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/bootstrap.rake +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/common.rake +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/cucumber.rake +23 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/gem.rake +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/rspec.rake +9 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/CHANGELOG.md +446 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/CONTRIBUTING.md +109 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/Dockerfile.jruby +79 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/Dockerfile.mri.erb +282 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/Gemfile +8 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/LICENSE.txt +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/README.md +447 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/Rakefile +246 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/bin/rake-compiler-dock +18 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/buildkitd.toml +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/gem_helper.rb +54 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/mk_i686.rb +18 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/mk_musl_cross.sh +37 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/mk_osxcross.sh +45 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/mk_pkg_config.sh +24 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/parallel_docker_build.rb +169 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0004-Enable-build-of-static-libruby.patch +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0005-build-miniruby-first.patch +16 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/patches/rake-compiler-1.3.1/0006-ruby-4-rubyspec-capiext.patch +16 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/rcd-env.sh +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/runas +7 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/sigfw.c +45 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_codesign +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_vbox +30 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/sudoers +1 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/colors.rb +43 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/docker_check.rb +356 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/predefined_user_group.rb +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/starter.rb +206 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/version.rb +4 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock.rb +151 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/Dockerfile +66 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/README.md +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/binutils-mingw-w64-ignore-check-errors.patch +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/gcc-mingw-w64-only-c-c++.patch +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/mingw-w64-enable-ucrt.patch +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/rake-compiler-dock.gemspec +34 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.alpine +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.debian +24 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/fixtures/mig_test_rpc.defs +8 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Gemfile +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Rakefile +97 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RcdTestExtService.java +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RubyRcdTest.java +16 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/extconf.rb +111 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/rcd_test_ext.c +65 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/rcd_test_ext.h +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/lib/rcd_test.rb +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/rcd_test.gemspec +28 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/test/test_basic.rb +49 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_environment_variables.rb +108 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_mig.rb +18 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_parallel_docker_build.rb +95 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_rubygems_plugins.rb +12 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_starter.rb +158 -0
- data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_versions.rb +82 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/LICENSE-APACHE +190 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/LICENSE-MIT +21 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/README.md +42 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/certs/ianks.pem +21 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/exe/rb-sys-dock +495 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo/config.rb +72 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo/metadata.rb +158 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo.rb +9 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo_builder/link_flag_converter.rb +37 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo_builder.rb +370 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/error.rb +43 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/extensiontask.rb +188 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/mkmf/config.rb +75 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/mkmf.rb +413 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/toolchain_info/data.rb +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/toolchain_info.rb +82 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/util/logger.rb +73 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/version.rb +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys.rb +8 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/BSDL +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/CHANGELOG.md +2463 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/COPYING +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/Dockerfile.jruby +53 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/README.md +240 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/Rakefile +1213 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/Steepfile +55 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/config.yml +920 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/array.rbs +4205 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/basic_object.rbs +376 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/binding.rbs +148 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/builtin.rbs +278 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/class.rbs +223 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/comparable.rbs +192 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/complex.rbs +812 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/constants.rbs +96 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/data.rbs +415 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/dir.rbs +993 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/encoding.rbs +1368 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/enumerable.rbs +2506 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/enumerator/arithmetic_sequence.rbs +70 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/enumerator/product.rbs +92 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/enumerator.rbs +705 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/env.rbs +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/errno.rbs +682 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/errors.rbs +789 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/exception.rbs +485 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/false_class.rbs +82 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/fiber.rbs +570 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/fiber_error.rbs +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/file.rbs +2045 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/file_constants.rbs +463 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/file_stat.rbs +534 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/file_test.rbs +331 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/float.rbs +1292 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/gc.rbs +788 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/global_variables.rbs +184 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/hash.rbs +2183 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/integer.rbs +1374 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/io/buffer.rbs +995 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/io/wait.rbs +48 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/io.rbs +3473 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/kernel.rbs +3172 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/marshal.rbs +207 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/match_data.rbs +637 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/math.rbs +770 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/method.rbs +422 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/module.rbs +1856 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/nil_class.rbs +210 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/numeric.rbs +832 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/object.rbs +108 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/object_space/weak_key_map.rbs +166 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/object_space.rbs +197 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/pathname.rbs +1312 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/proc.rbs +905 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/process.rbs +2316 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/ractor.rbs +914 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/random.rbs +255 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/range.rbs +1209 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rational.rbs +502 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rb_config.rbs +88 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/ops.rbs +154 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/unnamed/argf.rbs +1236 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/unnamed/env_class.rbs +1214 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/unnamed/main_class.rbs +123 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/unnamed/random.rbs +186 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/refinement.rbs +59 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/regexp.rbs +1974 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/ruby.rbs +53 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/ruby_vm.rbs +809 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/basic_specification.rbs +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/config_file.rbs +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/dependency_installer.rbs +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/errors.rbs +112 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/installer.rbs +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/path_support.rbs +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/platform.rbs +7 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/request_set.rbs +49 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/requirement.rbs +138 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/rubygems.rbs +1108 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/source_list.rbs +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/specification.rbs +31 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/stream_ui.rbs +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/uninstaller.rbs +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/version.rbs +133 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/set.rbs +751 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/signal.rbs +110 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/string.rbs +5532 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/struct.rbs +668 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/symbol.rbs +482 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/thread.rbs +1821 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/thread_group.rbs +79 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/time.rbs +1793 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/trace_point.rbs +483 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/true_class.rbs +98 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/unbound_method.rbs +337 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/warning.rbs +87 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/CONTRIBUTING.md +107 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/aliases.md +79 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/architecture.md +110 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/collection.md +192 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/config.md +171 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/data_and_struct.md +86 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/encoding.md +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/gem.md +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/inline.md +634 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/rbs_by_example.md +309 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/release.md +303 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/repo.md +125 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/rust.md +96 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/sigs.md +167 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/stdlib.md +155 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/syntax.md +952 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/tools.md +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/type_fingerprint.md +21 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/wasm_serialization.md +80 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/exe/rbs +7 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/Makefile +273 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/ast_translation.c +1870 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/ast_translation.h +41 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/class_constants.c +189 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/class_constants.h +105 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/compat.h +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/extconf.rb +40 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/legacy_location.c +299 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/legacy_location.h +82 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/main.c +649 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/rbs_extension.h +16 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/rbs_string_bridging.c +9 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/rbs_string_bridging.h +24 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/goodcheck.yml +91 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/ast.h +1055 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/defines.h +104 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/lexer.h +208 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/location.h +40 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/parser.h +187 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/serialize.h +39 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/string.h +47 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_allocator.h +59 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_assert.h +20 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_buffer.h +83 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_constant_pool.h +155 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_encoding.h +282 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_unescape.h +24 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs.h +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ancestor_graph.rb +92 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate/annotations.rb +199 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate/formatter.rb +82 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate/rdoc_annotator.rb +398 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate/rdoc_source.rb +131 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate.rb +8 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/annotation.rb +29 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/comment.rb +29 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/declarations.rb +472 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/directives.rb +49 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/members.rb +451 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/annotations.rb +451 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/comment_block.rb +247 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/declarations.rb +291 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/helpers/constant_helper.rb +28 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/members.rb +762 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/type_param.rb +235 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/visitor.rb +137 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/buffer.rb +189 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/builtin_names.rb +58 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/cli/colored_io.rb +48 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/cli/diff.rb +84 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/cli/validate.rb +294 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/cli.rb +1253 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/cleaner.rb +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/config/lockfile.rb +92 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/config/lockfile_generator.rb +269 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/config.rb +81 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/installer.rb +32 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/base.rb +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/git.rb +265 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/local.rb +81 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/rubygems.rb +48 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/stdlib.rb +50 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources.rb +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection.rb +16 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/constant.rb +28 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/definition.rb +415 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/definition_builder/ancestor_builder.rb +681 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/definition_builder/method_builder.rb +295 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/definition_builder.rb +1057 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/diff.rb +131 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment/class_entry.rb +81 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment/module_entry.rb +91 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment/use_map.rb +77 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment.rb +1028 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment_loader.rb +167 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment_walker.rb +155 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/errors.rb +634 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/factory.rb +18 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/file_finder.rb +28 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/inline_parser/comment_association.rb +117 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/inline_parser.rb +568 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/location_aux.rb +170 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/locator.rb +247 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/method_type.rb +145 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/namespace.rb +154 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/parser/lex_result.rb +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/parser/token.rb +23 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/parser_aux.rb +144 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/helpers.rb +164 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/node_usage.rb +99 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/rb.rb +816 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/rbi.rb +793 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/runtime/helpers.rb +59 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/runtime/reflection.rb +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/runtime/value_object_generator.rb +278 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/runtime.rb +680 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/repository.rb +127 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/resolver/constant_resolver.rb +219 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/resolver/type_name_resolver.rb +167 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/rewriter.rb +70 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/sorter.rb +198 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/source.rb +99 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/substitution.rb +83 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/subtractor.rb +204 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/errors.rb +80 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/guaranteed.rb +30 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/hook.rb +212 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/observer.rb +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/setup.rb +84 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/setup_helper.rb +50 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/tester.rb +167 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/type_check.rb +457 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test.rb +112 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/type_alias_dependency.rb +100 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/type_alias_regularity.rb +126 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/type_name.rb +122 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/types.rb +1646 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test/convertibles.rb +177 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test/spy.rb +138 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test/type_assertions.rb +383 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test/with_aliases.rb +145 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test.rb +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/validator.rb +186 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/variance_calculator.rb +189 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/vendorer.rb +71 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/version.rb +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/deserializer.rb +213 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/location.rb +61 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/parser.rb +174 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/runtime.rb +211 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/serialization_schema.rb +111 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/writer.rb +424 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs.rb +117 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs_extension.so +0 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs_jars.rb +39 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rdoc/discover.rb +20 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rdoc_plugin/parser.rb +168 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/rbs.gemspec +77 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/annotation.json +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/comment.json +26 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/decls.json +326 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/function.json +98 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/location.json +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/members.json +266 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/methodType.json +50 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/typeParam.json +52 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/types.json +317 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ancestor_builder.rbs +163 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ancestor_graph.rbs +60 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotate/annotations.rbs +102 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotate/formatter.rbs +24 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotate/rdoc_annotater.rbs +85 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotate/rdoc_source.rbs +32 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotation.rbs +27 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/annotations.rbs +470 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/comment_block.rbs +127 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/declarations.rbs +158 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/helpers/location_helper.rbs +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/members.rbs +198 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/buffer.rbs +108 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/builtin_names.rbs +44 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/cli/colored_io.rbs +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/cli/diff.rbs +15 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/cli/validate.rbs +47 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/cli.rbs +89 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/cleaner.rbs +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/config/lockfile.rbs +74 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/config/lockfile_generator.rbs +68 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/config.rbs +46 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/installer.rbs +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/sources.rbs +214 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection.rbs +4 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/comment.rbs +26 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/constant.rbs +21 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/declarations.rbs +274 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/definition.rbs +232 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/definition_builder.rbs +181 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/diff.rbs +28 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/directives.rbs +77 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment/class_entry.rbs +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment/module_entry.rbs +65 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment.rbs +286 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment_loader.rbs +111 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment_walker.rbs +65 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/errors.rbs +408 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/factory.rbs +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/file_finder.rbs +28 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/inline_parser/comment_association.rbs +71 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/inline_parser.rbs +126 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/location.rbs +135 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/locator.rbs +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/manifest.yaml +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/members.rbs +258 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/method_builder.rbs +89 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/method_types.rbs +58 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/namespace.rbs +161 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/parser.rbs +164 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/helpers.rbs +29 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/node_usage.rbs +20 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/rb.rbs +96 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/rbi.rbs +104 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/runtime.rbs +182 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/rbs.rbs +21 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/rdoc/rbs.rbs +67 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/repository.rbs +85 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/resolver/constant_resolver.rbs +92 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/resolver/context.rbs +34 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/resolver/type_name_resolver.rbs +61 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/rewriter.rbs +45 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/shims/bundler.rbs +38 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/shims/enumerable.rbs +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/shims/rubygems.rbs +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/sorter.rbs +41 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/source.rbs +48 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/substitution.rbs +48 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/subtractor.rbs +37 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/test/errors.rbs +52 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/test/guranteed.rbs +9 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/test/type_check.rbs +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/test.rbs +82 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/type_alias_dependency.rbs +53 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/type_alias_regularity.rbs +98 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/type_param.rbs +115 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/typename.rbs +89 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/types.rbs +588 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/unit_test/convertibles.rbs +154 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/unit_test/spy.rbs +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/unit_test/type_assertions.rbs +211 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/unit_test/with_aliases.rbs +136 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/use_map.rbs +35 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/util.rbs +9 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/validator.rbs +63 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/variance_calculator.rbs +87 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/vendorer.rbs +51 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/version.rbs +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/visitor.rbs +47 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/wasm/deserializer.rbs +66 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/wasm/serialization_schema.rbs +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/writer.rbs +127 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/ast.c +1644 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/lexer.c +3223 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/lexer.re +187 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/lexstate.c +222 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/location.c +31 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/parser.c +4318 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/serialize.c +965 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/string.c +41 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_allocator.c +171 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_assert.c +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_buffer.c +54 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_constant_pool.c +268 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_encoding.c +21454 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_unescape.c +167 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/abbrev/0/abbrev.rbs +66 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/abbrev/0/array.rbs +26 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/base64/0/base64.rbs +355 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/benchmark/0/benchmark.rbs +452 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/bigdecimal/0/big_decimal.rbs +1647 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/bigdecimal-math/0/big_math.rbs +280 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/cgi/0/core.rbs +911 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/cgi/0/manifest.yaml +4 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/cgi-escape/0/escape.rbs +171 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/coverage/0/coverage.rbs +266 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/csv/0/csv.rbs +3776 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/csv/0/manifest.yaml +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/date/0/date.rbs +1598 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/date/0/date_time.rbs +617 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/date/0/time.rbs +26 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/dbm/0/dbm.rbs +421 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/delegate/0/delegator.rbs +188 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/delegate/0/kernel.rbs +47 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/delegate/0/simple_delegator.rbs +96 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/did_you_mean/0/did_you_mean.rbs +344 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/digest/0/digest.rbs +693 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/erb/0/erb.rbs +933 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/etc/0/etc.rbs +884 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/fileutils/0/fileutils.rbs +1753 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/find/0/find.rbs +49 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/forwardable/0/forwardable.rbs +271 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/io-console/0/io-console.rbs +414 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/ipaddr/0/ipaddr.rbs +431 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs +1963 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/kconv/0/kconv.rbs +166 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/formatter.rbs +45 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/log_device.rbs +100 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/logger.rbs +796 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/manifest.yaml +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/period.rbs +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/severity.rbs +34 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/kernel.rbs +42 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/abstract_reporter.rbs +52 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/assertion.rbs +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/assertions.rbs +590 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/backtrace_filter.rbs +23 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/bench_spec.rbs +102 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/benchmark.rbs +259 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/composite_reporter.rbs +25 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/compress.rbs +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/error_on_warning.rbs +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/expectation.rbs +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/expectations.rbs +21 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/guard.rbs +64 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/mock.rbs +64 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/parallel/executor.rbs +46 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/parallel/test/class_methods.rbs +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/parallel/test.rbs +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/parallel.rbs +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/pride_io.rbs +62 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/pride_lol.rbs +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/progress_reporter.rbs +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/reportable.rbs +53 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/reporter.rbs +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/result.rbs +28 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/runnable.rbs +163 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/skip.rbs +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/spec/dsl/instance_methods.rbs +48 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/spec/dsl.rbs +129 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/spec.rbs +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/statistics_reporter.rbs +81 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/summary_reporter.rbs +18 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/test/lifecycle_hooks.rbs +92 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/test.rbs +69 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/unexpected_error.rbs +12 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/unexpected_warning.rbs +6 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/unit/test_case.rbs +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/unit.rbs +4 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest.rbs +115 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/monitor/0/monitor.rbs +363 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/mutex_m/0/mutex_m.rbs +104 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-http/0/manifest.yaml +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-http/0/net-http.rbs +5580 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-protocol/0/manifest.yaml +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-protocol/0/net-protocol.rbs +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-smtp/0/manifest.yaml +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-smtp/0/net-smtp.rbs +55 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/nkf/0/nkf.rbs +402 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/objspace/0/objspace.rbs +470 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/observable/0/observable.rbs +217 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/open-uri/0/manifest.yaml +4 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/open-uri/0/open-uri.rbs +433 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/open3/0/open3.rbs +606 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/openssl/0/manifest.yaml +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/openssl/0/openssl.rbs +12237 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/optparse/0/optparse.rbs +1734 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pathname/0/pathname.rbs +36 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pp/0/manifest.yaml +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pp/0/pp.rbs +301 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/prettyprint/0/prettyprint.rbs +383 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pstore/0/pstore.rbs +608 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/core_ext.rbs +12 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/dbm.rbs +237 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/manifest.yaml +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/psych.rbs +455 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/store.rbs +57 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pty/0/pty.rbs +240 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/random-formatter/0/random-formatter.rbs +277 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/code_object.rbs +52 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/comment.rbs +61 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/context.rbs +153 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/markup.rbs +117 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/options.rbs +76 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/parser.rbs +56 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/rdoc.rbs +393 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/ri.rbs +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/store.rbs +48 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/top_level.rbs +97 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/resolv/0/manifest.yaml +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/resolv/0/resolv.rbs +1787 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/ripper/0/ripper.rbs +1654 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/securerandom/0/manifest.yaml +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/securerandom/0/securerandom.rbs +49 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/shellwords/0/shellwords.rbs +229 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/singleton/0/singleton.rbs +137 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/addrinfo.rbs +666 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/basic_socket.rbs +590 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/constants.rbs +2295 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/ip_socket.rbs +94 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/socket.rbs +4170 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/socket_error.rbs +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/tcp_server.rbs +192 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/tcp_socket.rbs +87 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/udp_socket.rbs +133 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/unix_server.rbs +169 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/unix_socket.rbs +172 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/stringio/0/stringio.rbs +1682 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/strscan/0/string_scanner.rbs +1648 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tempfile/0/manifest.yaml +3 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tempfile/0/tempfile.rbs +483 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/time/0/time.rbs +434 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/timeout/0/timeout.rbs +132 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tmpdir/0/tmpdir.rbs +69 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tsort/0/cyclic.rbs +8 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tsort/0/interfaces.rbs +20 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tsort/0/tsort.rbs +410 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/common.rbs +621 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/file.rbs +118 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/ftp.rbs +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/generic.rbs +1111 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/http.rbs +104 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/https.rbs +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/ldap.rbs +230 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/ldaps.rbs +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/mailto.rbs +92 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/rfc2396_parser.rbs +189 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/rfc3986_parser.rbs +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/ws.rbs +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/wss.rbs +9 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/yaml/0/manifest.yaml +2 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/yaml/0/yaml.rbs +1 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/buf_error.rbs +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/data_error.rbs +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/deflate.rbs +211 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/error.rbs +20 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file/crc_error.rbs +12 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file/error.rbs +23 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file/length_error.rbs +12 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file/no_footer.rbs +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file.rbs +156 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_reader.rbs +293 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_writer.rbs +169 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/inflate.rbs +180 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/mem_error.rbs +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/need_dict.rbs +13 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/stream_end.rbs +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/stream_error.rbs +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/version_error.rbs +11 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/zlib.rbs +449 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/zstream.rbs +200 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/wasm/README.md +109 -0
- data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/wasm/rbs_wasm.c +479 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/LICENSE +19 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/README.md +135 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/datetime.rb +54 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/dumper.rb +182 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/errors.rb +17 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/inline_table.rb +18 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/keyvalue.rb +45 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/parser.rb +296 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/string.rb +41 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/table.rb +34 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/table_array.rb +43 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/version.rb +5 -0
- data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb.rb +90 -0
- data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/Gemfile +4 -0
- data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/LICENSE.txt +22 -0
- data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/README.md +72 -0
- data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/Rakefile +10 -0
- data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/bin/console +14 -0
- data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/bin/setup +8 -0
- data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/lib/tsort.rb +455 -0
- data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/tsort.gemspec +29 -0
- data/vendor/bundle/ruby/3.4.0/specifications/drb-2.2.3.gemspec +22 -0
- data/vendor/bundle/ruby/3.4.0/specifications/logger-1.7.0.gemspec +22 -0
- data/vendor/bundle/ruby/3.4.0/specifications/minitest-6.0.6.gemspec +35 -0
- data/vendor/bundle/ruby/3.4.0/specifications/prism-1.9.0.gemspec +24 -0
- data/vendor/bundle/ruby/3.4.0/specifications/rake-13.4.2.gemspec +26 -0
- data/vendor/bundle/ruby/3.4.0/specifications/rake-compiler-1.3.2.gemspec +33 -0
- data/vendor/bundle/ruby/3.4.0/specifications/rake-compiler-dock-1.12.0.gemspec +28 -0
- data/vendor/bundle/ruby/3.4.0/specifications/rb_sys-0.9.130.gemspec +29 -0
- data/vendor/bundle/ruby/3.4.0/specifications/rbs-4.2.0.gemspec +33 -0
- data/vendor/bundle/ruby/3.4.0/specifications/toml-rb-6.0.0.gemspec +27 -0
- data/vendor/bundle/ruby/3.4.0/specifications/tsort-0.2.0.gemspec +23 -0
- data/vendor/cache/Cargo.toml +21 -0
- data/vendor/cache/LICENSE +21 -0
- data/vendor/cache/README.md +5 -0
- data/vendor/cache/src/hash.rs +85 -0
- data/vendor/cache/src/lib.rs +751 -0
- data/vendor/cache/src/loom_tests.rs +340 -0
- data/vendor/cache/src/s3fifo.rs +648 -0
- data/vendor/cache/src/sync.rs +25 -0
- data/vendor/cache/src/tests.rs +260 -0
- data/vendor/compaction/Cargo.toml +32 -0
- data/vendor/compaction/LICENSE +21 -0
- data/vendor/compaction/README.md +5 -0
- data/vendor/compaction/src/blob.rs +478 -0
- data/vendor/compaction/src/cursor.rs +700 -0
- data/vendor/compaction/src/gc.rs +802 -0
- data/vendor/compaction/src/job.rs +861 -0
- data/vendor/compaction/src/lib.rs +102 -0
- data/vendor/compaction/src/merge.rs +995 -0
- data/vendor/compaction/src/picker.rs +681 -0
- data/vendor/compaction/src/resolver.rs +1346 -0
- data/vendor/engine/Cargo.toml +56 -0
- data/vendor/engine/LICENSE +21 -0
- data/vendor/engine/README.md +5 -0
- data/vendor/engine/src/admission.rs +421 -0
- data/vendor/engine/src/catalog.rs +1233 -0
- data/vendor/engine/src/check.rs +1386 -0
- data/vendor/engine/src/clock.rs +244 -0
- data/vendor/engine/src/clock_loom.rs +482 -0
- data/vendor/engine/src/close_gate.rs +325 -0
- data/vendor/engine/src/compact.rs +1509 -0
- data/vendor/engine/src/engine/hooks.rs +1654 -0
- data/vendor/engine/src/engine/info.rs +229 -0
- data/vendor/engine/src/engine.rs +6114 -0
- data/vendor/engine/src/error.rs +490 -0
- data/vendor/engine/src/feed.rs +960 -0
- data/vendor/engine/src/feed_reader.rs +1600 -0
- data/vendor/engine/src/flush.rs +839 -0
- data/vendor/engine/src/flushed_roots.rs +158 -0
- data/vendor/engine/src/flushed_through_loom.rs +77 -0
- data/vendor/engine/src/health.rs +201 -0
- data/vendor/engine/src/large.rs +372 -0
- data/vendor/engine/src/large_settle.rs +201 -0
- data/vendor/engine/src/lib.rs +112 -0
- data/vendor/engine/src/load_slot.rs +324 -0
- data/vendor/engine/src/maintenance.rs +935 -0
- data/vendor/engine/src/manifest/flight.rs +563 -0
- data/vendor/engine/src/manifest.rs +1516 -0
- data/vendor/engine/src/nonblocking.rs +603 -0
- data/vendor/engine/src/options.rs +334 -0
- data/vendor/engine/src/position.rs +125 -0
- data/vendor/engine/src/purge_guard.rs +220 -0
- data/vendor/engine/src/read/keys.rs +1049 -0
- data/vendor/engine/src/read/knn.rs +423 -0
- data/vendor/engine/src/read/reduce.rs +2057 -0
- data/vendor/engine/src/read/traverse.rs +1013 -0
- data/vendor/engine/src/read.rs +2429 -0
- data/vendor/engine/src/row_cache.rs +1101 -0
- data/vendor/engine/src/shard/tablets.rs +3582 -0
- data/vendor/engine/src/shard.rs +12215 -0
- data/vendor/engine/src/snapshot.rs +1429 -0
- data/vendor/engine/src/source.rs +1379 -0
- data/vendor/engine/src/timer_state.rs +226 -0
- data/vendor/engine/src/waker.rs +124 -0
- data/vendor/engine/src/watermark_waiters.rs +674 -0
- data/vendor/engine/src/write.rs +1321 -0
- data/vendor/format/Cargo.toml +40 -0
- data/vendor/format/LICENSE +21 -0
- data/vendor/format/README.md +5 -0
- data/vendor/format/src/blob.rs +101 -0
- data/vendor/format/src/block.rs +1120 -0
- data/vendor/format/src/bloom.rs +456 -0
- data/vendor/format/src/buckets.rs +552 -0
- data/vendor/format/src/bytes.rs +101 -0
- data/vendor/format/src/checksum.rs +132 -0
- data/vendor/format/src/compress.rs +196 -0
- data/vendor/format/src/cursor.rs +110 -0
- data/vendor/format/src/distance.rs +598 -0
- data/vendor/format/src/error.rs +93 -0
- data/vendor/format/src/exact.rs +602 -0
- data/vendor/format/src/feed.rs +285 -0
- data/vendor/format/src/filter.rs +157 -0
- data/vendor/format/src/half.rs +182 -0
- data/vendor/format/src/hash.rs +127 -0
- data/vendor/format/src/hll.rs +500 -0
- data/vendor/format/src/ids.rs +95 -0
- data/vendor/format/src/key.rs +620 -0
- data/vendor/format/src/kind_params.rs +101 -0
- data/vendor/format/src/lib.rs +54 -0
- data/vendor/format/src/manifest.rs +1287 -0
- data/vendor/format/src/roaring.rs +865 -0
- data/vendor/format/src/scan.rs +297 -0
- data/vendor/format/src/shm.rs +805 -0
- data/vendor/format/src/sst.rs +233 -0
- data/vendor/format/src/superblock.rs +345 -0
- data/vendor/format/src/value.rs +163 -0
- data/vendor/format/src/varint.rs +87 -0
- data/vendor/format/src/vector.rs +936 -0
- data/vendor/format/src/version.rs +92 -0
- data/vendor/format/src/wal.rs +999 -0
- data/vendor/io/Cargo.toml +29 -0
- data/vendor/io/LICENSE +21 -0
- data/vendor/io/README.md +5 -0
- data/vendor/io/src/async_poll.rs +44 -0
- data/vendor/io/src/buf.rs +694 -0
- data/vendor/io/src/completion.rs +444 -0
- data/vendor/io/src/error.rs +110 -0
- data/vendor/io/src/file.rs +206 -0
- data/vendor/io/src/lib.rs +53 -0
- data/vendor/io/src/nowait.rs +256 -0
- data/vendor/io/src/os/mod.rs +149 -0
- data/vendor/io/src/os/unix.rs +897 -0
- data/vendor/io/src/os/windows.rs +552 -0
- data/vendor/io/src/own.rs +257 -0
- data/vendor/io/src/pread.rs +854 -0
- data/vendor/io/src/ring_wake.rs +113 -0
- data/vendor/io/src/shared.rs +410 -0
- data/vendor/io/src/sim.rs +1545 -0
- data/vendor/io/src/sys.rs +214 -0
- data/vendor/io/src/uring.rs +1839 -0
- data/vendor/io/src/vfs.rs +154 -0
- data/vendor/memory/Cargo.toml +34 -0
- data/vendor/memory/LICENSE +21 -0
- data/vendor/memory/README.md +11 -0
- data/vendor/memory/src/consolidate.rs +640 -0
- data/vendor/memory/src/dedup.rs +231 -0
- data/vendor/memory/src/error.rs +131 -0
- data/vendor/memory/src/feed_loop.rs +572 -0
- data/vendor/memory/src/forget.rs +724 -0
- data/vendor/memory/src/hooks.rs +109 -0
- data/vendor/memory/src/ivf.rs +204 -0
- data/vendor/memory/src/layout.rs +340 -0
- data/vendor/memory/src/lib.rs +61 -0
- data/vendor/memory/src/recall.rs +1182 -0
- data/vendor/memory/src/store.rs +1785 -0
- data/vendor/memory/src/watch.rs +339 -0
- data/vendor/memtable/Cargo.toml +24 -0
- data/vendor/memtable/LICENSE +21 -0
- data/vendor/memtable/README.md +5 -0
- data/vendor/memtable/src/lib.rs +1658 -0
- data/vendor/memtable/src/loom_tests.rs +274 -0
- data/vendor/memtable/src/mem.rs +344 -0
- data/vendor/memtable/src/tests.rs +1061 -0
- data/vendor/pager/Cargo.toml +23 -0
- data/vendor/pager/LICENSE +21 -0
- data/vendor/pager/README.md +5 -0
- data/vendor/pager/src/alloc.rs +1008 -0
- data/vendor/pager/src/lib.rs +1710 -0
- data/vendor/pigeonhole/Cargo.toml +42 -0
- data/vendor/pigeonhole/LICENSE +21 -0
- data/vendor/pigeonhole/README.md +99 -0
- data/vendor/pigeonhole/src/cell.rs +829 -0
- data/vendor/pigeonhole/src/check.rs +368 -0
- data/vendor/pigeonhole/src/db.rs +2324 -0
- data/vendor/pigeonhole/src/doc_support.rs +89 -0
- data/vendor/pigeonhole/src/error.rs +257 -0
- data/vendor/pigeonhole/src/feed.rs +696 -0
- data/vendor/pigeonhole/src/info.rs +425 -0
- data/vendor/pigeonhole/src/lib.rs +202 -0
- data/vendor/pigeonhole/src/merge.rs +135 -0
- data/vendor/pigeonhole/src/metrics.rs +476 -0
- data/vendor/pigeonhole/src/nonblocking.rs +666 -0
- data/vendor/pigeonhole/src/options.rs +2075 -0
- data/vendor/pigeonhole/src/read/budget.rs +584 -0
- data/vendor/pigeonhole/src/read.rs +2463 -0
- data/vendor/pigeonhole/src/recovery.rs +876 -0
- data/vendor/pigeonhole/src/retry.rs +358 -0
- data/vendor/pigeonhole/src/set.rs +103 -0
- data/vendor/pigeonhole/src/table.rs +861 -0
- data/vendor/pigeonhole/src/vector.rs +351 -0
- data/vendor/pigeonhole/src/write.rs +2815 -0
- data/vendor/runtime/Cargo.toml +21 -0
- data/vendor/runtime/LICENSE +21 -0
- data/vendor/runtime/README.md +5 -0
- data/vendor/runtime/src/completion.rs +629 -0
- data/vendor/runtime/src/drivers.rs +1175 -0
- data/vendor/runtime/src/lib.rs +1546 -0
- data/vendor/runtime/src/pool.rs +992 -0
- data/vendor/runtime/src/sched.rs +809 -0
- data/vendor/runtime/src/signal.rs +532 -0
- data/vendor/runtime/src/submit_gate.rs +144 -0
- data/vendor/shm/Cargo.toml +24 -0
- data/vendor/shm/LICENSE +21 -0
- data/vendor/shm/README.md +5 -0
- data/vendor/shm/src/lib.rs +427 -0
- data/vendor/shm/src/lock.rs +153 -0
- data/vendor/shm/src/region.rs +1609 -0
- data/vendor/sst/Cargo.toml +26 -0
- data/vendor/sst/LICENSE +21 -0
- data/vendor/sst/README.md +5 -0
- data/vendor/sst/src/blob.rs +380 -0
- data/vendor/sst/src/iter.rs +803 -0
- data/vendor/sst/src/lib.rs +695 -0
- data/vendor/sst/src/reader.rs +814 -0
- data/vendor/sst/src/writer.rs +596 -0
- data/vendor/text/Cargo.toml +26 -0
- data/vendor/text/LICENSE +21 -0
- data/vendor/text/README.md +9 -0
- data/vendor/text/src/error.rs +108 -0
- data/vendor/text/src/fuzzy.rs +265 -0
- data/vendor/text/src/highlight.rs +236 -0
- data/vendor/text/src/index.rs +1152 -0
- data/vendor/text/src/layout.rs +424 -0
- data/vendor/text/src/lib.rs +75 -0
- data/vendor/text/src/maxscore.rs +658 -0
- data/vendor/text/src/query.rs +450 -0
- data/vendor/text/src/search.rs +569 -0
- data/vendor/text/src/sloppy.rs +460 -0
- data/vendor/text/src/tokenizer.rs +163 -0
- data/vendor/vector/Cargo.toml +28 -0
- data/vendor/vector/LICENSE +21 -0
- data/vendor/vector/README.md +9 -0
- data/vendor/vector/src/error.rs +63 -0
- data/vendor/vector/src/half.rs +167 -0
- data/vendor/vector/src/hooks.rs +135 -0
- data/vendor/vector/src/index.rs +2690 -0
- data/vendor/vector/src/layout.rs +102 -0
- data/vendor/vector/src/lib.rs +52 -0
- data/vendor/vector/src/point.rs +500 -0
- data/vendor/vector/src/rebalancer.rs +200 -0
- data/vendor/vector/src/registry.rs +81 -0
- data/vendor/wal/Cargo.toml +25 -0
- data/vendor/wal/LICENSE +21 -0
- data/vendor/wal/README.md +5 -0
- data/vendor/wal/src/feed.rs +610 -0
- data/vendor/wal/src/foreground.rs +122 -0
- data/vendor/wal/src/lib.rs +458 -0
- data/vendor/wal/src/mem.rs +166 -0
- data/vendor/wal/src/recovery.rs +426 -0
- data/vendor/wal/src/stream.rs +2382 -0
- metadata +1310 -0
|
@@ -0,0 +1,1710 @@
|
|
|
1
|
+
//! Page file for Pigeonhole: superblock pair, extent allocator, epoch-deferred freeing.
|
|
2
|
+
//!
|
|
3
|
+
//! The pager owns the main file's space, not its contents. It hands out power-of-two
|
|
4
|
+
//! [`Extent`]s, flips the superblock to publish a new root, and frees extents only when the
|
|
5
|
+
//! engine says no live view can reach them.
|
|
6
|
+
//!
|
|
7
|
+
//! The free-space bitmap is not persisted (decision D8): at open the engine reads the manifest
|
|
8
|
+
//! and passes every live extent to [`OpenedPager::finish`]; everything else is free. A crash
|
|
9
|
+
//! therefore never leaks space, and no bitmap can disagree with the manifest.
|
|
10
|
+
//!
|
|
11
|
+
//! The in-memory mock for the layers above is simply a `Pager` over
|
|
12
|
+
//! [`SimVfs`](pigeonhole_io::sim::SimVfs) ([`Pager::create`] with any path).
|
|
13
|
+
//!
|
|
14
|
+
//! # Threading
|
|
15
|
+
//!
|
|
16
|
+
//! `Pager` is shared by every shard (`&self` methods, internally synchronized). The calls
|
|
17
|
+
//! differ in what they may block on:
|
|
18
|
+
//!
|
|
19
|
+
//! - [`Pager::allocate`], [`Pager::abandon`], [`Pager::retire`], [`Pager::reclaim`],
|
|
20
|
+
//! [`Pager::stats`], [`Pager::shrink_plan`] and [`Pager::clear_for`] only touch
|
|
21
|
+
//! memory, except that `allocate` preallocates more file. Ahead of need, once no free
|
|
22
|
+
//! block of the largest class (64 MiB) is left: one `fallocate` on the caller's thread,
|
|
23
|
+
//! outside the allocator lock, with its `sync_all` submitted to the I/O backend. Inline,
|
|
24
|
+
//! only when no free extent fits (a growth ahead still in flight, or a file under
|
|
25
|
+
//! 128 MiB): one `fallocate` and `sync_all` under the allocator lock. They run per flush
|
|
26
|
+
//! or compaction output, never per write.
|
|
27
|
+
//! - [`Pager::read`] and [`Pager::write`] are positional I/O on the caller's thread.
|
|
28
|
+
//! - [`Pager::commit_root`] and [`Pager::mark_clean`] block on two fsyncs. They must not run
|
|
29
|
+
//! on a shard's foreground loop (decision D30): the manifest task uses
|
|
30
|
+
//! [`Pager::submit_commit_root`], whose fsyncs run on the I/O backend. Root commits must
|
|
31
|
+
//! not overlap; an overlapping commit fails instead of racing.
|
|
32
|
+
//! - [`Pager::relocate`], [`Pager::relocate_below`], [`Pager::relocate_into`] and
|
|
33
|
+
//! [`Pager::truncate_tail`] copy or truncate on the caller's thread (online shrink is a
|
|
34
|
+
//! background job).
|
|
35
|
+
//!
|
|
36
|
+
//! # Example
|
|
37
|
+
//!
|
|
38
|
+
//! ```
|
|
39
|
+
//! use std::path::Path;
|
|
40
|
+
//! use pigeonhole_io::VfsRef;
|
|
41
|
+
//! use pigeonhole_io::sim::SimVfs;
|
|
42
|
+
//! use pigeonhole_pager::{Pager, Root};
|
|
43
|
+
//!
|
|
44
|
+
//! # fn main() -> pigeonhole_pager::Result<()> {
|
|
45
|
+
//! let vfs: VfsRef = SimVfs::new(7);
|
|
46
|
+
//! let path = Path::new("/db/data.phdb");
|
|
47
|
+
//! let pager = Pager::create(&vfs, path)?;
|
|
48
|
+
//!
|
|
49
|
+
//! // Write a "manifest snapshot" into a fresh extent and publish it.
|
|
50
|
+
//! let snapshot = pager.allocate(100)?;
|
|
51
|
+
//! pager.write(snapshot, 0, b"manifest bytes")?;
|
|
52
|
+
//! let root = Root { snapshot: Some(snapshot), snapshot_len: 14, manifest_version: 1, ..Root::default() };
|
|
53
|
+
//! pager.commit_root(root)?;
|
|
54
|
+
//! drop(pager);
|
|
55
|
+
//!
|
|
56
|
+
//! // Reopen: read the root, read the manifest, then name every live extent.
|
|
57
|
+
//! let opened = Pager::open(&vfs, path, true)?;
|
|
58
|
+
//! assert_eq!(opened.root(), root);
|
|
59
|
+
//! let pager = opened.finish([snapshot])?;
|
|
60
|
+
//! let mut buf = [0u8; 14];
|
|
61
|
+
//! pager.read(snapshot, 0, &mut buf)?;
|
|
62
|
+
//! assert_eq!(&buf, b"manifest bytes");
|
|
63
|
+
//! # Ok(())
|
|
64
|
+
//! # }
|
|
65
|
+
//! ```
|
|
66
|
+
//!
|
|
67
|
+
//! Part of [Pigeonhole](https://github.com/CodingAnarchy/pigeonhole). See the crate README.
|
|
68
|
+
#![forbid(unsafe_code)]
|
|
69
|
+
|
|
70
|
+
mod alloc;
|
|
71
|
+
|
|
72
|
+
use std::collections::hash_map::DefaultHasher;
|
|
73
|
+
use std::fmt;
|
|
74
|
+
use std::hash::Hasher;
|
|
75
|
+
use std::path::Path;
|
|
76
|
+
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
|
77
|
+
use std::sync::{Arc, Condvar, Mutex, MutexGuard, OnceLock, PoisonError, TryLockError};
|
|
78
|
+
|
|
79
|
+
use pigeonhole_format::superblock::{
|
|
80
|
+
EXTENSION_AREA, Features, SUPERBLOCK_PAGE_A, SUPERBLOCK_PAGE_B, Superblock,
|
|
81
|
+
};
|
|
82
|
+
use pigeonhole_format::{FormatVersion, ManifestVersion, PAGE_SIZE};
|
|
83
|
+
use pigeonhole_io::{Completion, ErrorKind, FileRef, IoBuf, OpenOptions, VfsRef};
|
|
84
|
+
|
|
85
|
+
use crate::alloc::{Alloc, LoadError, UNIT_BYTES, UNIT_PAGES};
|
|
86
|
+
|
|
87
|
+
/// A region [`Pager::clear_for`] holds for a larger extent, and the live extents to move
|
|
88
|
+
/// out of it.
|
|
89
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
90
|
+
pub struct Clearing {
|
|
91
|
+
/// The region, as an extent of the class it is cleared for.
|
|
92
|
+
pub region: Extent,
|
|
93
|
+
/// The region's live extents, largest first.
|
|
94
|
+
pub occupants: Vec<Extent>,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/// An allocated extent: `64 KiB << size_class` bytes at `page`. The persisted form.
|
|
98
|
+
pub use pigeonhole_format::superblock::ExtentRef as Extent;
|
|
99
|
+
|
|
100
|
+
/// Result alias for this crate.
|
|
101
|
+
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|
102
|
+
|
|
103
|
+
/// Pager errors.
|
|
104
|
+
///
|
|
105
|
+
/// ```
|
|
106
|
+
/// use pigeonhole_io::VfsRef;
|
|
107
|
+
/// use pigeonhole_io::sim::SimVfs;
|
|
108
|
+
/// use pigeonhole_pager::{Error, Pager};
|
|
109
|
+
///
|
|
110
|
+
/// let vfs: VfsRef = SimVfs::new(1);
|
|
111
|
+
/// let pager = Pager::create(&vfs, "/db/data.phdb".as_ref()).unwrap();
|
|
112
|
+
/// assert!(matches!(pager.allocate(65 << 20), Err(Error::TooLarge)));
|
|
113
|
+
/// ```
|
|
114
|
+
#[derive(Debug)]
|
|
115
|
+
#[non_exhaustive]
|
|
116
|
+
pub enum Error {
|
|
117
|
+
/// The underlying file failed.
|
|
118
|
+
Io(pigeonhole_io::Error),
|
|
119
|
+
/// Neither superblock is valid, or a structure failed to decode.
|
|
120
|
+
Format(pigeonhole_format::Error),
|
|
121
|
+
/// No free extent of the requested size and the file cannot grow.
|
|
122
|
+
NoSpace,
|
|
123
|
+
/// The request is larger than the largest extent (64 MiB).
|
|
124
|
+
TooLarge,
|
|
125
|
+
/// The file was created by a newer, incompatible format.
|
|
126
|
+
UnsupportedVersion(u32),
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
impl fmt::Display for Error {
|
|
130
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
131
|
+
match self {
|
|
132
|
+
Error::Io(e) => write!(f, "page file I/O: {e}"),
|
|
133
|
+
Error::Format(e) => write!(f, "page file format: {e}"),
|
|
134
|
+
Error::NoSpace => f.write_str("no free extent and the file cannot grow"),
|
|
135
|
+
Error::TooLarge => f.write_str("extent request larger than 64 MiB"),
|
|
136
|
+
Error::UnsupportedVersion(v) => write!(f, "unsupported page file format version {v}"),
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
impl std::error::Error for Error {
|
|
142
|
+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
143
|
+
match self {
|
|
144
|
+
Error::Io(e) => Some(e),
|
|
145
|
+
Error::Format(e) => Some(e),
|
|
146
|
+
_ => None,
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
impl From<pigeonhole_io::Error> for Error {
|
|
152
|
+
fn from(e: pigeonhole_io::Error) -> Self {
|
|
153
|
+
Self::Io(e)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
impl From<pigeonhole_format::Error> for Error {
|
|
158
|
+
fn from(e: pigeonhole_format::Error) -> Self {
|
|
159
|
+
match e {
|
|
160
|
+
pigeonhole_format::Error::UnsupportedVersion { found, .. } => {
|
|
161
|
+
Self::UnsupportedVersion(found)
|
|
162
|
+
}
|
|
163
|
+
e => Self::Format(e),
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
fn io_err(kind: ErrorKind, context: &'static str) -> Error {
|
|
169
|
+
Error::Io(pigeonhole_io::Error::new(kind, context))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/// What the superblock points at: the manifest snapshot block and the live part of the
|
|
173
|
+
/// delta log (decision D7).
|
|
174
|
+
///
|
|
175
|
+
/// ```
|
|
176
|
+
/// use pigeonhole_pager::{Extent, Root};
|
|
177
|
+
///
|
|
178
|
+
/// let empty = Root::default();
|
|
179
|
+
/// assert_eq!(empty.snapshot, None);
|
|
180
|
+
/// let root = Root {
|
|
181
|
+
/// snapshot: Some(Extent { page: 16, size_class: 0 }),
|
|
182
|
+
/// snapshot_len: 512,
|
|
183
|
+
/// manifest_version: 3,
|
|
184
|
+
/// ..Root::default()
|
|
185
|
+
/// };
|
|
186
|
+
/// assert_ne!(root, empty);
|
|
187
|
+
/// ```
|
|
188
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
189
|
+
pub struct Root {
|
|
190
|
+
/// Extent holding the snapshot block; `None` for an empty database.
|
|
191
|
+
pub snapshot: Option<Extent>,
|
|
192
|
+
/// Length of the snapshot block.
|
|
193
|
+
pub snapshot_len: u32,
|
|
194
|
+
/// Extent holding the delta log, if any delta follows the snapshot.
|
|
195
|
+
pub log: Option<Extent>,
|
|
196
|
+
/// Live bytes of the delta log.
|
|
197
|
+
pub log_len: u32,
|
|
198
|
+
/// Manifest version of this root.
|
|
199
|
+
pub manifest_version: ManifestVersion,
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
impl Root {
|
|
203
|
+
fn from_superblock(sb: &Superblock) -> Self {
|
|
204
|
+
Self {
|
|
205
|
+
snapshot: sb.snapshot,
|
|
206
|
+
snapshot_len: sb.snapshot_len,
|
|
207
|
+
log: sb.log,
|
|
208
|
+
log_len: sb.log_len,
|
|
209
|
+
manifest_version: sb.manifest_version,
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/// Flag bit 0 of the superblock: the last writer closed cleanly.
|
|
215
|
+
const FLAG_CLEAN: u64 = 1;
|
|
216
|
+
|
|
217
|
+
/// A pager that has read its superblock but does not yet know which extents are live.
|
|
218
|
+
///
|
|
219
|
+
/// ```
|
|
220
|
+
/// use pigeonhole_io::VfsRef;
|
|
221
|
+
/// use pigeonhole_io::sim::SimVfs;
|
|
222
|
+
/// use pigeonhole_pager::{Pager, Root};
|
|
223
|
+
///
|
|
224
|
+
/// # fn main() -> pigeonhole_pager::Result<()> {
|
|
225
|
+
/// let vfs: VfsRef = SimVfs::new(3);
|
|
226
|
+
/// let path = "/db/data.phdb".as_ref();
|
|
227
|
+
/// let id = Pager::create(&vfs, path)?.db_id();
|
|
228
|
+
///
|
|
229
|
+
/// let opened = Pager::open(&vfs, path, false)?;
|
|
230
|
+
/// assert_eq!(opened.db_id(), id);
|
|
231
|
+
/// assert_eq!(opened.root(), Root::default());
|
|
232
|
+
/// // The engine reads the manifest through `opened.file()` here, then names live extents.
|
|
233
|
+
/// let pager = opened.finish([])?;
|
|
234
|
+
/// assert_eq!(pager.stats().allocated_bytes, 0);
|
|
235
|
+
/// # Ok(())
|
|
236
|
+
/// # }
|
|
237
|
+
/// ```
|
|
238
|
+
#[derive(Debug)]
|
|
239
|
+
pub struct OpenedPager {
|
|
240
|
+
file: FileRef,
|
|
241
|
+
writable: bool,
|
|
242
|
+
superblock: Superblock,
|
|
243
|
+
slot: u64,
|
|
244
|
+
/// Either superblock page holds a valid superblock of an older format version, or the
|
|
245
|
+
/// two valid pages' feature sets differ: `finish` rewrites both.
|
|
246
|
+
older: bool,
|
|
247
|
+
/// The current page's extension area.
|
|
248
|
+
extension: Extension,
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
impl OpenedPager {
|
|
252
|
+
/// The current root, from the newest valid superblock.
|
|
253
|
+
pub fn root(&self) -> Root {
|
|
254
|
+
Root::from_superblock(&self.superblock)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/// The feature sets of the newest valid superblock (D269).
|
|
258
|
+
pub fn features(&self) -> Features {
|
|
259
|
+
self.superblock.features
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/// The database id.
|
|
263
|
+
pub fn db_id(&self) -> [u8; 16] {
|
|
264
|
+
self.superblock.db_id
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/// The newest valid superblock's `sequence` (FORMAT §8.2), before any root commit of this
|
|
268
|
+
/// open.
|
|
269
|
+
pub fn sequence(&self) -> u64 {
|
|
270
|
+
self.superblock.sequence
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/// Whether the last writer closed cleanly. The flag stays set until the next root
|
|
274
|
+
/// commit, which clears it.
|
|
275
|
+
pub fn clean_shutdown(&self) -> bool {
|
|
276
|
+
self.superblock.flags & FLAG_CLEAN != 0
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/// Turns a writable open into a read-only one after the manifest was read (a writer
|
|
280
|
+
/// process that may not write this file, ICR 0059): `finish` then neither syncs nor
|
|
281
|
+
/// upgrades, and the pager refuses root commits. The file handle stays as opened.
|
|
282
|
+
pub fn into_read_only(mut self) -> Self {
|
|
283
|
+
self.writable = false;
|
|
284
|
+
self
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/// The file, for reading the manifest before `finish`.
|
|
288
|
+
pub fn file(&self) -> &FileRef {
|
|
289
|
+
&self.file
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/// Marks `live` extents allocated (everything else is free) and returns a usable pager.
|
|
293
|
+
/// `live` must include the manifest snapshot and log extents, every SST and every blob
|
|
294
|
+
/// extent. Exact duplicates are accepted (tablets may share an SST after a split);
|
|
295
|
+
/// overlapping, misaligned or out-of-file extents fail with [`Error::Format`]. A writable
|
|
296
|
+
/// pager first makes the file's current length durable (`sync_all`).
|
|
297
|
+
///
|
|
298
|
+
/// If either superblock page holds an older format version, a writable pager then commits
|
|
299
|
+
/// the current root twice, so both pages carry [`FormatVersion::CURRENT`] before its
|
|
300
|
+
/// caller writes anything an older build could not read (ICR 0046): an older build
|
|
301
|
+
/// refuses the file with an unsupported-version error instead of falling back to the
|
|
302
|
+
/// page it can still decode. A crash between the two commits leaves one older page
|
|
303
|
+
/// naming the same root, and the next writable open finishes the upgrade. Two pages
|
|
304
|
+
/// whose feature sets differ (a crash inside [`Pager::set_features`]) are rewritten the
|
|
305
|
+
/// same way, with the current page's sets.
|
|
306
|
+
pub fn finish(self, live: impl IntoIterator<Item = Extent>) -> Result<Pager> {
|
|
307
|
+
let upgrade = self.writable && self.older;
|
|
308
|
+
let pager = self.load(live)?;
|
|
309
|
+
if upgrade {
|
|
310
|
+
let root = pager.root();
|
|
311
|
+
pager.commit_root(root)?;
|
|
312
|
+
pager.commit_root(root)?;
|
|
313
|
+
}
|
|
314
|
+
Ok(pager)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
fn load(self, live: impl IntoIterator<Item = Extent>) -> Result<Pager> {
|
|
318
|
+
// The allocator is sized from the length the page cache shows, which a process that
|
|
319
|
+
// died between a growth's `fallocate` and its `sync_all` left longer than the disk's.
|
|
320
|
+
// Make it durable before handing out that tail: root commits sync with `sync_data`.
|
|
321
|
+
// Skipped when the file is exactly as long as the last committed root recorded and
|
|
322
|
+
// that root came from a clean close (#158, D203): that length was made durable by the
|
|
323
|
+
// growth or truncation that set it (each syncs before it is used) or by an earlier
|
|
324
|
+
// open. A length that differs either way (a growth or a truncation interrupted by a
|
|
325
|
+
// crash) is synced as before. A clean flag left stale by a crash in a session that
|
|
326
|
+
// committed nothing is harmless here: such a session neither grew nor truncated
|
|
327
|
+
// durably past the recorded length without the length differing.
|
|
328
|
+
let recorded = self.superblock.file_pages * PAGE_SIZE as u64;
|
|
329
|
+
let settled = self.clean_shutdown() && self.file.len()? == recorded;
|
|
330
|
+
if self.writable && !settled {
|
|
331
|
+
self.file.sync_all()?;
|
|
332
|
+
}
|
|
333
|
+
let frontier = self.file.len()?.div_ceil(UNIT_BYTES);
|
|
334
|
+
let alloc = Alloc::load(frontier, live).map_err(|e| {
|
|
335
|
+
let what = match e {
|
|
336
|
+
LoadError::Invalid => "live extent is not a valid extent",
|
|
337
|
+
LoadError::Overlap => "live extents overlap",
|
|
338
|
+
LoadError::PastEnd => "live extent past the end of the file",
|
|
339
|
+
};
|
|
340
|
+
Error::Format(pigeonhole_format::Error::Corrupt { what })
|
|
341
|
+
})?;
|
|
342
|
+
let frontier = alloc.frontier();
|
|
343
|
+
Ok(Pager {
|
|
344
|
+
inner: Arc::new(Inner {
|
|
345
|
+
file: self.file,
|
|
346
|
+
data_file: OnceLock::new(),
|
|
347
|
+
writable: self.writable,
|
|
348
|
+
db_id: self.superblock.db_id,
|
|
349
|
+
alloc: Mutex::new(alloc),
|
|
350
|
+
state: Mutex::new(CommitState {
|
|
351
|
+
root: Root::from_superblock(&self.superblock),
|
|
352
|
+
sequence: self.superblock.sequence,
|
|
353
|
+
slot: self.slot,
|
|
354
|
+
version: self.superblock.version,
|
|
355
|
+
features: self.superblock.features,
|
|
356
|
+
extension: self.extension,
|
|
357
|
+
poisoned: false,
|
|
358
|
+
}),
|
|
359
|
+
committing: AtomicBool::new(false),
|
|
360
|
+
growths: AtomicU64::new(0),
|
|
361
|
+
growth_nanos: AtomicU64::new(0),
|
|
362
|
+
ahead: AtomicBool::new(false),
|
|
363
|
+
ahead_flight: Mutex::new(None),
|
|
364
|
+
growths_ahead: AtomicU64::new(0),
|
|
365
|
+
ahead_nanos: AtomicU64::new(0),
|
|
366
|
+
side: SideSyncs::default(),
|
|
367
|
+
root_observer: OnceLock::new(),
|
|
368
|
+
frontier: AtomicU64::new(frontier),
|
|
369
|
+
}),
|
|
370
|
+
})
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/// The main page file. Shared by every shard (`&self` methods, internally synchronized;
|
|
375
|
+
/// allocation is per flush or compaction output, never per write). See the crate docs'
|
|
376
|
+
/// *Threading* section for what each call may block on.
|
|
377
|
+
///
|
|
378
|
+
/// Space is handed out as power-of-two [`Extent`]s from an in-memory buddy allocator
|
|
379
|
+
/// (lowest address first within the smallest fitting size). An extent is freed either at
|
|
380
|
+
/// once ([`abandon`](Pager::abandon), for output never published) or after epoch-deferred
|
|
381
|
+
/// reclamation ([`retire`](Pager::retire) then [`reclaim`](Pager::reclaim)), so a view that
|
|
382
|
+
/// can still reach an extent never sees it reused.
|
|
383
|
+
///
|
|
384
|
+
/// ```
|
|
385
|
+
/// use pigeonhole_io::VfsRef;
|
|
386
|
+
/// use pigeonhole_io::sim::SimVfs;
|
|
387
|
+
/// use pigeonhole_pager::{Pager, Root};
|
|
388
|
+
///
|
|
389
|
+
/// # fn main() -> pigeonhole_pager::Result<()> {
|
|
390
|
+
/// let vfs: VfsRef = SimVfs::new(9);
|
|
391
|
+
/// let pager = Pager::create(&vfs, "/db/data.phdb".as_ref())?;
|
|
392
|
+
/// let old = pager.allocate(64 << 10)?;
|
|
393
|
+
/// pager.commit_root(Root { snapshot: Some(old), manifest_version: 1, ..Root::default() })?;
|
|
394
|
+
///
|
|
395
|
+
/// // Version 2 no longer references `old`; a snapshot of version 1 may still read it.
|
|
396
|
+
/// let new = pager.allocate(64 << 10)?;
|
|
397
|
+
/// pager.commit_root(Root { snapshot: Some(new), manifest_version: 2, ..Root::default() })?;
|
|
398
|
+
/// pager.retire(old, 2);
|
|
399
|
+
/// assert_eq!(pager.reclaim(1), 0); // a view at version 1 is still live
|
|
400
|
+
/// assert_eq!(pager.reclaim(2), 1); // every live view is at version 2 or later
|
|
401
|
+
/// # Ok(())
|
|
402
|
+
/// # }
|
|
403
|
+
/// ```
|
|
404
|
+
#[derive(Debug)]
|
|
405
|
+
pub struct Pager {
|
|
406
|
+
inner: Arc<Inner>,
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
#[derive(Debug)]
|
|
410
|
+
struct Inner {
|
|
411
|
+
file: FileRef,
|
|
412
|
+
/// A second handle on the same file for SST and blob extents, opened for direct I/O
|
|
413
|
+
/// (#403); set once at open, `file` otherwise.
|
|
414
|
+
data_file: OnceLock<FileRef>,
|
|
415
|
+
writable: bool,
|
|
416
|
+
db_id: [u8; 16],
|
|
417
|
+
alloc: Mutex<Alloc>,
|
|
418
|
+
state: Mutex<CommitState>,
|
|
419
|
+
/// Set while a root commit runs; overlapping commits are refused.
|
|
420
|
+
committing: AtomicBool,
|
|
421
|
+
/// File growths, and the nanoseconds they held the allocator (ICR 0015).
|
|
422
|
+
growths: AtomicU64,
|
|
423
|
+
growth_nanos: AtomicU64,
|
|
424
|
+
/// Set while a growth ahead of need is in flight (one at a time).
|
|
425
|
+
ahead: AtomicBool,
|
|
426
|
+
/// That growth's sync, with its continuation, until a blocking commit takes it to wait
|
|
427
|
+
/// on: the wait drives I/O only its thread or a waiter completes (an io_uring ring the
|
|
428
|
+
/// committing thread owns, the simulator's deferred device), which the side syncs'
|
|
429
|
+
/// condvar alone would wait for for ever.
|
|
430
|
+
ahead_flight: Mutex<Option<Completion<()>>>,
|
|
431
|
+
/// Growths ahead of need that completed, and the nanoseconds their `fallocate` took
|
|
432
|
+
/// on the allocating thread.
|
|
433
|
+
growths_ahead: AtomicU64,
|
|
434
|
+
ahead_nanos: AtomicU64,
|
|
435
|
+
/// Growth and truncation syncs in flight, which a commit must see the outcome of before
|
|
436
|
+
/// it publishes (D58), without holding the allocator lock (#182).
|
|
437
|
+
side: SideSyncs,
|
|
438
|
+
/// The allocator's frontier (units), kept beside it so a commit reads it for the
|
|
439
|
+
/// superblock without taking the allocator lock, which a growth holds across its sync
|
|
440
|
+
/// (#182). Updated under that lock whenever the frontier moves.
|
|
441
|
+
frontier: AtomicU64,
|
|
442
|
+
/// Called with the new superblock's sequence after each successful root commit
|
|
443
|
+
/// ([`Pager::on_root_commit`], D310).
|
|
444
|
+
root_observer: OnceLock<RootObserver>,
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/// A root-commit observer ([`Pager::on_root_commit`]).
|
|
448
|
+
struct RootObserver(Box<dyn Fn(u64) + Send + Sync>);
|
|
449
|
+
|
|
450
|
+
impl fmt::Debug for RootObserver {
|
|
451
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
452
|
+
f.write_str("RootObserver")
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/// Commit steps a finished side sync resumes; [`Parked::run`] them with no pager lock held.
|
|
457
|
+
#[must_use]
|
|
458
|
+
struct Parked(Vec<Box<dyn FnOnce() + Send>>);
|
|
459
|
+
|
|
460
|
+
impl Parked {
|
|
461
|
+
fn run(self) {
|
|
462
|
+
for step in self.0 {
|
|
463
|
+
step();
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
impl fmt::Debug for SideSyncs {
|
|
469
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
470
|
+
f.debug_struct("SideSyncs")
|
|
471
|
+
.field("in_flight", &lock(&self.state).in_flight)
|
|
472
|
+
.finish_non_exhaustive()
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/// How often a blocking commit waiting for side syncs looks again for a growth's sync to
|
|
477
|
+
/// drive ([`Inner::wait_side_idle`]).
|
|
478
|
+
const SIDE_RECHECK: std::time::Duration = std::time::Duration::from_millis(1);
|
|
479
|
+
|
|
480
|
+
/// The growths' and truncations' `sync_all`s in flight (#182). A commit's sync may succeed
|
|
481
|
+
/// only because one of them was handed the error for the same pages (D58), so before a
|
|
482
|
+
/// commit publishes, every side sync that may have overlapped it must have finished: a
|
|
483
|
+
/// failed one poisons the pager first. A submitted commit never waits for that on the I/O
|
|
484
|
+
/// backend's thread: it parks its next step, and the side sync that finishes last
|
|
485
|
+
/// resubmits it.
|
|
486
|
+
#[derive(Default)]
|
|
487
|
+
struct SideSyncs {
|
|
488
|
+
state: Mutex<SideState>,
|
|
489
|
+
/// Signalled when the count reaches zero (for a blocking commit).
|
|
490
|
+
idle: Condvar,
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
#[derive(Default)]
|
|
494
|
+
struct SideState {
|
|
495
|
+
in_flight: u32,
|
|
496
|
+
/// Commits' next steps, parked until no side sync is in flight.
|
|
497
|
+
parked: Vec<Box<dyn FnOnce() + Send>>,
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
impl SideSyncs {
|
|
501
|
+
/// Counts a side sync in flight until [`SideSyncs::finish`].
|
|
502
|
+
fn start(&self) {
|
|
503
|
+
lock(&self.state).in_flight += 1;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/// Ends a side sync: `poisoned` has already been set if it failed. Returns the parked
|
|
507
|
+
/// commit steps when it was the last one in flight, for the caller to run once it holds
|
|
508
|
+
/// no pager lock (a step can end its commit, which takes the allocator lock). Their steps
|
|
509
|
+
/// only submit I/O, so the thread running them (an allocating shard or compaction
|
|
510
|
+
/// thread) does not wait for it.
|
|
511
|
+
fn finish(&self) -> Parked {
|
|
512
|
+
let mut st = lock(&self.state);
|
|
513
|
+
st.in_flight -= 1;
|
|
514
|
+
if st.in_flight != 0 {
|
|
515
|
+
return Parked(Vec::new());
|
|
516
|
+
}
|
|
517
|
+
let parked = std::mem::take(&mut st.parked);
|
|
518
|
+
drop(st);
|
|
519
|
+
self.idle.notify_all();
|
|
520
|
+
Parked(parked)
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/// Runs `step` now if no side sync is in flight, else when the last one finishes.
|
|
524
|
+
fn after(&self, step: impl FnOnce() + Send + 'static) {
|
|
525
|
+
let mut st = lock(&self.state);
|
|
526
|
+
if st.in_flight != 0 {
|
|
527
|
+
st.parked.push(Box::new(step));
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
drop(st);
|
|
531
|
+
step();
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/// Waits until no side sync is in flight, or `timeout` passes; returns whether none is.
|
|
535
|
+
fn wait_idle_for(&self, timeout: std::time::Duration) -> bool {
|
|
536
|
+
let st = lock(&self.state);
|
|
537
|
+
let (st, _) = self
|
|
538
|
+
.idle
|
|
539
|
+
.wait_timeout_while(st, timeout, |st| st.in_flight != 0)
|
|
540
|
+
.unwrap_or_else(PoisonError::into_inner);
|
|
541
|
+
st.in_flight == 0
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
#[derive(Debug)]
|
|
546
|
+
struct CommitState {
|
|
547
|
+
/// The root most recently committed (or reloaded).
|
|
548
|
+
root: Root,
|
|
549
|
+
/// Sequence of the current superblock.
|
|
550
|
+
sequence: u64,
|
|
551
|
+
/// Page of the current superblock; the next commit writes the other one.
|
|
552
|
+
slot: u64,
|
|
553
|
+
/// Format version of the current superblock: older until a writable pager's first
|
|
554
|
+
/// commit (which `finish` makes at once for an older file), then the current one.
|
|
555
|
+
version: FormatVersion,
|
|
556
|
+
/// The file's feature sets (format 4, D269), carried into every root commit: compat
|
|
557
|
+
/// bits a newer build set are kept, not cleared.
|
|
558
|
+
features: Features,
|
|
559
|
+
/// The extension area, carried likewise (D269).
|
|
560
|
+
extension: Extension,
|
|
561
|
+
/// A sync of the file failed: a commit's (the on-disk root is uncertain) or a growth's
|
|
562
|
+
/// or truncation's. An fsync error may have dropped written data, and on Linux it is
|
|
563
|
+
/// reported to one sync only, so a later sync succeeding proves nothing: no further
|
|
564
|
+
/// commit is attempted (decision D58). Set under the allocator lock when a growth or
|
|
565
|
+
/// truncation sync fails; see `Inner::check_syncs`.
|
|
566
|
+
poisoned: bool,
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/// A root commit in flight: the encoded superblock and where it goes.
|
|
570
|
+
struct PendingCommit {
|
|
571
|
+
page: Box<[u8; PAGE_SIZE]>,
|
|
572
|
+
slot: u64,
|
|
573
|
+
sequence: u64,
|
|
574
|
+
root: Root,
|
|
575
|
+
/// The feature sets the page carries: the current ones once it is durable.
|
|
576
|
+
features: Features,
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
fn lock<T>(m: &Mutex<T>) -> MutexGuard<'_, T> {
|
|
580
|
+
m.lock().unwrap_or_else(PoisonError::into_inner)
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/// The guard, or `None` while another thread holds `m`.
|
|
584
|
+
fn try_lock<T>(m: &Mutex<T>) -> Option<MutexGuard<'_, T>> {
|
|
585
|
+
match m.try_lock() {
|
|
586
|
+
Ok(g) => Some(g),
|
|
587
|
+
Err(TryLockError::Poisoned(p)) => Some(p.into_inner()),
|
|
588
|
+
Err(TryLockError::WouldBlock) => None,
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/// The smallest size class holding `bytes`.
|
|
593
|
+
fn class_for(bytes: u64) -> Result<u8> {
|
|
594
|
+
let class = (0..=Extent::MAX_CLASS).find(|&c| UNIT_BYTES << c >= bytes);
|
|
595
|
+
class.ok_or(Error::TooLarge)
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
fn poisoned_error() -> pigeonhole_io::Error {
|
|
599
|
+
pigeonhole_io::Error::new(
|
|
600
|
+
ErrorKind::Other,
|
|
601
|
+
"an earlier root commit failed, or a sync of the file did; reopen the database",
|
|
602
|
+
)
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
fn grow_error(e: pigeonhole_io::Error) -> Error {
|
|
606
|
+
match e.kind {
|
|
607
|
+
ErrorKind::NoSpace => Error::NoSpace,
|
|
608
|
+
_ => Error::Io(e),
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/// A fresh database id: [`Vfs::random_u64`](pigeonhole_io::Vfs::random_u64) mixed with the
|
|
613
|
+
/// path, so a simulated `Vfs` replays the same id from its seed.
|
|
614
|
+
fn random_db_id(vfs: &VfsRef, path: &Path) -> [u8; 16] {
|
|
615
|
+
let mut id = [0u8; 16];
|
|
616
|
+
let (halves, _) = id.as_chunks_mut::<8>();
|
|
617
|
+
for (i, half) in halves.iter_mut().enumerate() {
|
|
618
|
+
let mut h = DefaultHasher::new();
|
|
619
|
+
h.write_u64(vfs.random_u64());
|
|
620
|
+
h.write(path.as_os_str().as_encoded_bytes());
|
|
621
|
+
h.write_usize(i);
|
|
622
|
+
*half = h.finish().to_le_bytes();
|
|
623
|
+
}
|
|
624
|
+
id
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/// Reads one superblock slot. A short file reads as a truncated (invalid) superblock.
|
|
628
|
+
fn read_slot(
|
|
629
|
+
file: &FileRef,
|
|
630
|
+
slot: u64,
|
|
631
|
+
page: &mut [u8; PAGE_SIZE],
|
|
632
|
+
) -> Result<pigeonhole_format::Result<Superblock>> {
|
|
633
|
+
match file.read_at(page, slot * PAGE_SIZE as u64) {
|
|
634
|
+
Ok(()) => Ok(Superblock::decode(page)),
|
|
635
|
+
Err(e) if e.kind == ErrorKind::UnexpectedEof => {
|
|
636
|
+
Ok(Err(pigeonhole_format::Error::Truncated {
|
|
637
|
+
what: "superblock",
|
|
638
|
+
}))
|
|
639
|
+
}
|
|
640
|
+
Err(e) => Err(e.into()),
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/// The current superblock and its page, and whether either page holds a valid superblock of
|
|
645
|
+
/// an older format version.
|
|
646
|
+
fn read_superblocks(file: &FileRef) -> Result<(Superblock, u64, bool)> {
|
|
647
|
+
read_superblocks_with(file).map(|(sb, slot, older, _)| (sb, slot, older))
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/// As [`read_superblocks`], with the current page's extension area (zero before format 4).
|
|
651
|
+
fn read_superblocks_with(file: &FileRef) -> Result<(Superblock, u64, bool, Extension)> {
|
|
652
|
+
let mut pages = [[0u8; PAGE_SIZE]; 2];
|
|
653
|
+
let [page_a, page_b] = &mut pages;
|
|
654
|
+
let a = read_slot(file, SUPERBLOCK_PAGE_A, page_a)?;
|
|
655
|
+
let b = read_slot(file, SUPERBLOCK_PAGE_B, page_b)?;
|
|
656
|
+
// A page of an older format, or two pages whose feature sets differ (a crash between a
|
|
657
|
+
// feature change's two commits, `Pager::set_features`): a writable open rewrites both.
|
|
658
|
+
let older = [&a, &b]
|
|
659
|
+
.iter()
|
|
660
|
+
.any(|r| matches!(r, Ok(sb) if sb.version < FormatVersion::CURRENT))
|
|
661
|
+
|| matches!((&a, &b), (Ok(x), Ok(y)) if x.features != y.features);
|
|
662
|
+
let (sb, slot) = Superblock::choose(a, b)?;
|
|
663
|
+
let mut extension = Extension::default();
|
|
664
|
+
if sb.version >= FormatVersion(4) {
|
|
665
|
+
let page = &pages[usize::from(slot == SUPERBLOCK_PAGE_B)];
|
|
666
|
+
extension.0.copy_from_slice(&page[EXTENSION_AREA]);
|
|
667
|
+
}
|
|
668
|
+
Ok((sb, slot, older, extension))
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/// The superblock's extension area (FORMAT §8.2, D269), carried unchanged into every root
|
|
672
|
+
/// commit so a later 1.x feature's data there survives a build that does not know it.
|
|
673
|
+
#[derive(Clone)]
|
|
674
|
+
struct Extension(Box<[u8; EXTENSION_LEN]>);
|
|
675
|
+
|
|
676
|
+
const EXTENSION_LEN: usize = EXTENSION_AREA.end - EXTENSION_AREA.start;
|
|
677
|
+
|
|
678
|
+
impl Default for Extension {
|
|
679
|
+
fn default() -> Self {
|
|
680
|
+
Self(Box::new([0; EXTENSION_LEN]))
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
impl fmt::Debug for Extension {
|
|
685
|
+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
686
|
+
let used = self.0.iter().filter(|&&b| b != 0).count();
|
|
687
|
+
write!(f, "Extension({used} nonzero bytes)")
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
impl Inner {
|
|
692
|
+
/// Validates and encodes a commit of `root` and claims the commit slot.
|
|
693
|
+
fn begin(&self, root: Root, clean: bool) -> pigeonhole_io::Result<PendingCommit> {
|
|
694
|
+
self.begin_with(Some(root), clean, None)
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/// [`Inner::begin`], with `root` and `features` defaulting to the current ones, read
|
|
698
|
+
/// under the state lock as the commit slot is claimed (a feature change commits the root
|
|
699
|
+
/// that is current then, never one read earlier; perf287's S1 on #858).
|
|
700
|
+
fn begin_with(
|
|
701
|
+
&self,
|
|
702
|
+
root: Option<Root>,
|
|
703
|
+
clean: bool,
|
|
704
|
+
features: Option<Features>,
|
|
705
|
+
) -> pigeonhole_io::Result<PendingCommit> {
|
|
706
|
+
use pigeonhole_io::Error as IoError;
|
|
707
|
+
if !self.writable {
|
|
708
|
+
return Err(IoError::new(
|
|
709
|
+
ErrorKind::Unsupported,
|
|
710
|
+
"root commit on a read-only pager",
|
|
711
|
+
));
|
|
712
|
+
}
|
|
713
|
+
if self.committing.swap(true, Ordering::AcqRel) {
|
|
714
|
+
return Err(IoError::new(ErrorKind::Other, "root commits overlap"));
|
|
715
|
+
}
|
|
716
|
+
let st = lock(&self.state);
|
|
717
|
+
if st.poisoned {
|
|
718
|
+
drop(st);
|
|
719
|
+
self.committing.store(false, Ordering::Release);
|
|
720
|
+
return Err(poisoned_error());
|
|
721
|
+
}
|
|
722
|
+
let sequence = st.sequence + 1;
|
|
723
|
+
let slot = st.slot ^ 1;
|
|
724
|
+
let root = root.unwrap_or(st.root);
|
|
725
|
+
let features = features.unwrap_or(st.features);
|
|
726
|
+
let file_pages = self.frontier.load(Ordering::Acquire) * UNIT_PAGES;
|
|
727
|
+
let sb = Superblock {
|
|
728
|
+
version: FormatVersion::CURRENT,
|
|
729
|
+
page_size: PAGE_SIZE as u32,
|
|
730
|
+
sequence,
|
|
731
|
+
db_id: self.db_id,
|
|
732
|
+
snapshot: root.snapshot,
|
|
733
|
+
snapshot_len: root.snapshot_len,
|
|
734
|
+
log: root.log,
|
|
735
|
+
log_len: root.log_len,
|
|
736
|
+
manifest_version: root.manifest_version,
|
|
737
|
+
file_pages,
|
|
738
|
+
flags: if clean { FLAG_CLEAN } else { 0 },
|
|
739
|
+
features,
|
|
740
|
+
};
|
|
741
|
+
let mut page = Box::new([0u8; PAGE_SIZE]);
|
|
742
|
+
sb.encode(&mut page);
|
|
743
|
+
page[EXTENSION_AREA].copy_from_slice(&st.extension.0[..]);
|
|
744
|
+
drop(st);
|
|
745
|
+
Ok(PendingCommit {
|
|
746
|
+
page,
|
|
747
|
+
slot,
|
|
748
|
+
sequence,
|
|
749
|
+
root,
|
|
750
|
+
features,
|
|
751
|
+
})
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/// Waits until no side sync is in flight (a blocking commit, on its caller's thread),
|
|
755
|
+
/// driving a growth ahead's sync if no other thread has taken it. A growth stores its
|
|
756
|
+
/// sync just after submitting it, so the wait looks for it again while it waits.
|
|
757
|
+
fn wait_side_idle(&self) {
|
|
758
|
+
loop {
|
|
759
|
+
let flight = lock(&self.ahead_flight).take();
|
|
760
|
+
if let Some(c) = flight {
|
|
761
|
+
// Its outcome reaches the pager through the continuation (a failure poisons).
|
|
762
|
+
let _ = c.wait();
|
|
763
|
+
}
|
|
764
|
+
if self.side.wait_idle_for(SIDE_RECHECK) {
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/// Fails if a growth's or truncation's sync failed. A commit calls it after each of its
|
|
771
|
+
/// own syncs succeeded, once no side sync is in flight ([`SideSyncs`]): that sync may
|
|
772
|
+
/// have succeeded only because a concurrent one was handed the error for the same pages,
|
|
773
|
+
/// and a failed side sync poisons before it stops counting as in flight.
|
|
774
|
+
fn check_syncs(&self) -> pigeonhole_io::Result<()> {
|
|
775
|
+
if lock(&self.state).poisoned {
|
|
776
|
+
return Err(poisoned_error());
|
|
777
|
+
}
|
|
778
|
+
Ok(())
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/// Writes the superblock once the first sync succeeded and no other sync failed
|
|
782
|
+
/// (blocking: waits for side syncs in flight).
|
|
783
|
+
fn write_superblock(&self, p: &PendingCommit) -> pigeonhole_io::Result<()> {
|
|
784
|
+
self.wait_side_idle();
|
|
785
|
+
self.check_syncs()?;
|
|
786
|
+
self.file.write_at(&p.page[..], p.slot * PAGE_SIZE as u64)
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/// Ends a commit: on success the new root is current; on failure (or if another sync
|
|
790
|
+
/// failed meanwhile) the pager is poisoned. No side sync may be in flight.
|
|
791
|
+
fn end(
|
|
792
|
+
&self,
|
|
793
|
+
p: PendingCommit,
|
|
794
|
+
result: pigeonhole_io::Result<()>,
|
|
795
|
+
) -> pigeonhole_io::Result<()> {
|
|
796
|
+
let result = result.and_then(|()| self.check_syncs());
|
|
797
|
+
let mut st = lock(&self.state);
|
|
798
|
+
match &result {
|
|
799
|
+
Ok(()) => {
|
|
800
|
+
st.root = p.root;
|
|
801
|
+
st.sequence = p.sequence;
|
|
802
|
+
st.slot = p.slot;
|
|
803
|
+
st.version = FormatVersion::CURRENT;
|
|
804
|
+
st.features = p.features;
|
|
805
|
+
}
|
|
806
|
+
Err(_) => st.poisoned = true,
|
|
807
|
+
}
|
|
808
|
+
drop(st);
|
|
809
|
+
if result.is_ok()
|
|
810
|
+
&& let Some(observe) = self.root_observer.get()
|
|
811
|
+
{
|
|
812
|
+
(observe.0)(p.sequence);
|
|
813
|
+
}
|
|
814
|
+
if result.is_ok() {
|
|
815
|
+
// The manifest extents the durable root names may no longer be abandoned.
|
|
816
|
+
let mut alloc = lock(&self.alloc);
|
|
817
|
+
for e in p.root.snapshot.into_iter().chain(p.root.log) {
|
|
818
|
+
alloc.publish(e);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
self.committing.store(false, Ordering::Release);
|
|
822
|
+
result
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/// Sync, write the non-current superblock, sync; blocking.
|
|
826
|
+
fn commit(&self, root: Root, clean: bool) -> pigeonhole_io::Result<()> {
|
|
827
|
+
let p = self.begin(root, clean)?;
|
|
828
|
+
self.commit_pending(p)
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
/// A blocking commit of the current root with `features` ([`Pager::set_features`]):
|
|
832
|
+
/// the root and sets are taken as the commit slot is claimed, and `features` becomes
|
|
833
|
+
/// current only once the page is durable.
|
|
834
|
+
fn commit_features(&self, features: Features) -> pigeonhole_io::Result<()> {
|
|
835
|
+
let p = self.begin_with(None, false, Some(features))?;
|
|
836
|
+
self.commit_pending(p)
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
fn commit_pending(&self, p: PendingCommit) -> pigeonhole_io::Result<()> {
|
|
840
|
+
let result = self
|
|
841
|
+
.file
|
|
842
|
+
.sync_data()
|
|
843
|
+
.and_then(|()| self.write_superblock(&p))
|
|
844
|
+
.and_then(|()| self.file.sync_data());
|
|
845
|
+
self.wait_side_idle();
|
|
846
|
+
self.end(p, result)
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/// The same steps, all submitted to the I/O backend: sync, superblock write, sync. No
|
|
850
|
+
/// step waits on the thread that resolves the one before (#182): one that must wait for a
|
|
851
|
+
/// side sync in flight is parked ([`SideSyncs::after`]) and submitted when it finishes.
|
|
852
|
+
fn submit_commit(self: Arc<Self>, root: Root) -> Completion<()> {
|
|
853
|
+
let p = match self.begin(root, false) {
|
|
854
|
+
Ok(p) => p,
|
|
855
|
+
Err(e) => return Completion::ready(Err(e)),
|
|
856
|
+
};
|
|
857
|
+
let (done, resolver) = Completion::pair();
|
|
858
|
+
let first = self.file.submit_sync_data();
|
|
859
|
+
// The continuations' own completions are not needed: `resolver` reports the outcome.
|
|
860
|
+
let _chained = first.map(move |synced| {
|
|
861
|
+
let inner = Arc::clone(&self);
|
|
862
|
+
self.side
|
|
863
|
+
.after(move || inner.submit_superblock(p, synced, resolver));
|
|
864
|
+
Ok(())
|
|
865
|
+
});
|
|
866
|
+
done
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/// A submitted commit's second step, with no side sync in flight: writes the superblock
|
|
870
|
+
/// (if the first sync and every side sync succeeded) and submits the second sync.
|
|
871
|
+
fn submit_superblock(
|
|
872
|
+
self: Arc<Self>,
|
|
873
|
+
p: PendingCommit,
|
|
874
|
+
synced: pigeonhole_io::Result<()>,
|
|
875
|
+
resolver: pigeonhole_io::Resolver<()>,
|
|
876
|
+
) {
|
|
877
|
+
if let Err(e) = synced.and_then(|()| self.check_syncs()) {
|
|
878
|
+
resolver.resolve(self.end(p, Err(e)));
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
let mut page = IoBuf::zeroed(PAGE_SIZE);
|
|
882
|
+
page.copy_from_slice(&p.page[..]);
|
|
883
|
+
let written = self.file.submit_write(page, p.slot * PAGE_SIZE as u64);
|
|
884
|
+
let _chained = written.map(move |r| {
|
|
885
|
+
let r = r.map(drop);
|
|
886
|
+
if let Err(e) = r {
|
|
887
|
+
resolver.resolve(self.end(p, Err(e)));
|
|
888
|
+
return Ok(());
|
|
889
|
+
}
|
|
890
|
+
let second = self.file.submit_sync_data();
|
|
891
|
+
let _chained = second.map(move |synced| {
|
|
892
|
+
let inner = Arc::clone(&self);
|
|
893
|
+
self.side
|
|
894
|
+
.after(move || resolver.resolve(inner.end(p, synced)));
|
|
895
|
+
Ok(())
|
|
896
|
+
});
|
|
897
|
+
Ok(())
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
impl Pager {
|
|
903
|
+
/// Creates a new database file at `path` with an empty root (`Root::default()`) and a
|
|
904
|
+
/// fresh random db id. Fails if the file exists.
|
|
905
|
+
///
|
|
906
|
+
/// The file is usable once this returns (superblock A written and synced, directory
|
|
907
|
+
/// entry synced). A crash during `create` can leave a file without a valid superblock;
|
|
908
|
+
/// [`Pager::open`] then fails with [`Error::Format`], and the caller may remove it and
|
|
909
|
+
/// create again since nothing was ever committed to it.
|
|
910
|
+
pub fn create(vfs: &VfsRef, path: &Path) -> Result<Pager> {
|
|
911
|
+
let mut opts = OpenOptions::read_write_create();
|
|
912
|
+
opts.create_new = true;
|
|
913
|
+
let file = vfs.open(path, opts)?;
|
|
914
|
+
file.set_len(UNIT_BYTES).map_err(grow_error)?;
|
|
915
|
+
let superblock = Superblock {
|
|
916
|
+
version: FormatVersion::CURRENT,
|
|
917
|
+
page_size: PAGE_SIZE as u32,
|
|
918
|
+
sequence: 1,
|
|
919
|
+
db_id: random_db_id(vfs, path),
|
|
920
|
+
snapshot: None,
|
|
921
|
+
snapshot_len: 0,
|
|
922
|
+
log: None,
|
|
923
|
+
log_len: 0,
|
|
924
|
+
manifest_version: 0,
|
|
925
|
+
file_pages: UNIT_PAGES,
|
|
926
|
+
flags: 0,
|
|
927
|
+
features: Default::default(),
|
|
928
|
+
};
|
|
929
|
+
let mut page = [0u8; PAGE_SIZE];
|
|
930
|
+
superblock.encode(&mut page);
|
|
931
|
+
file.write_at(&page, SUPERBLOCK_PAGE_A * PAGE_SIZE as u64)?;
|
|
932
|
+
file.sync_all()?;
|
|
933
|
+
let dir = match path.parent() {
|
|
934
|
+
Some(d) if !d.as_os_str().is_empty() => d,
|
|
935
|
+
_ => Path::new("."),
|
|
936
|
+
};
|
|
937
|
+
vfs.sync_dir(dir)?;
|
|
938
|
+
OpenedPager {
|
|
939
|
+
file,
|
|
940
|
+
writable: true,
|
|
941
|
+
superblock,
|
|
942
|
+
slot: SUPERBLOCK_PAGE_A,
|
|
943
|
+
older: false,
|
|
944
|
+
extension: Extension::default(),
|
|
945
|
+
}
|
|
946
|
+
.finish([])
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/// Opens an existing file and reads both superblocks. No recovery scan. A read-only pager
|
|
950
|
+
/// (reader processes) never allocates, retires or commits; it only reads and reloads.
|
|
951
|
+
pub fn open(vfs: &VfsRef, path: &Path, writable: bool) -> Result<OpenedPager> {
|
|
952
|
+
let mut opts = OpenOptions::read();
|
|
953
|
+
opts.write = writable;
|
|
954
|
+
let file = vfs.open(path, opts)?;
|
|
955
|
+
let (superblock, slot, older, extension) = read_superblocks_with(&file)?;
|
|
956
|
+
// `choose` refused unknown incompatible features; a writer also refuses unknown
|
|
957
|
+
// read-only-compatible ones (a reader process may read the file).
|
|
958
|
+
if writable {
|
|
959
|
+
superblock.features.check_write()?;
|
|
960
|
+
}
|
|
961
|
+
Ok(OpenedPager {
|
|
962
|
+
file,
|
|
963
|
+
writable,
|
|
964
|
+
superblock,
|
|
965
|
+
slot,
|
|
966
|
+
older,
|
|
967
|
+
extension,
|
|
968
|
+
})
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/// The file handle: superblocks, the manifest, and the copies `shrink` and `backup` make.
|
|
972
|
+
pub fn file(&self) -> &FileRef {
|
|
973
|
+
&self.inner.file
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/// The handle SST and blob extents are read and written through: the direct-I/O handle
|
|
977
|
+
/// set by [`Pager::set_data_file`] (#403), or [`Pager::file`].
|
|
978
|
+
pub fn data_file(&self) -> &FileRef {
|
|
979
|
+
self.inner.data_file.get().unwrap_or(&self.inner.file)
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
/// Sets the handle for SST and blob extents: a second handle on the same file, opened
|
|
983
|
+
/// for direct I/O (#403). Only the first call takes effect; call it at open, before any
|
|
984
|
+
/// extent is read or written.
|
|
985
|
+
pub fn set_data_file(&self, file: FileRef) {
|
|
986
|
+
let _ = self.inner.data_file.set(file);
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/// The database id.
|
|
990
|
+
pub fn db_id(&self) -> [u8; 16] {
|
|
991
|
+
self.inner.db_id
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
/// The root most recently committed.
|
|
995
|
+
pub fn root(&self) -> Root {
|
|
996
|
+
lock(&self.inner.state).root
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/// The current superblock's `sequence` (FORMAT §8.2): as of the last commit, or the last
|
|
1000
|
+
/// reload for a read-only pager.
|
|
1001
|
+
pub fn sequence(&self) -> u64 {
|
|
1002
|
+
lock(&self.inner.state).sequence
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/// Sets the one observer every later successful root commit calls with its new
|
|
1006
|
+
/// sequence, on the committing thread, once the commit is durable and before the commit
|
|
1007
|
+
/// returns (the change feed's sidecar, D310). Returns `false`, leaving the first one, if
|
|
1008
|
+
/// an observer is already set. It must not commit a root itself.
|
|
1009
|
+
///
|
|
1010
|
+
/// ```
|
|
1011
|
+
/// use std::sync::Arc;
|
|
1012
|
+
/// use std::sync::atomic::{AtomicU64, Ordering};
|
|
1013
|
+
/// use pigeonhole_io::{VfsRef, sim::SimVfs};
|
|
1014
|
+
/// use pigeonhole_pager::Pager;
|
|
1015
|
+
///
|
|
1016
|
+
/// # fn main() -> pigeonhole_pager::Result<()> {
|
|
1017
|
+
/// let vfs: VfsRef = SimVfs::new(3);
|
|
1018
|
+
/// let pager = Pager::create(&vfs, "/db/data.phdb".as_ref())?;
|
|
1019
|
+
/// let seen = Arc::new(AtomicU64::new(0));
|
|
1020
|
+
/// let s = Arc::clone(&seen);
|
|
1021
|
+
/// assert!(pager.on_root_commit(Box::new(move |seq| s.store(seq, Ordering::Relaxed))));
|
|
1022
|
+
/// pager.commit_root(pager.root())?;
|
|
1023
|
+
/// assert_eq!(seen.load(Ordering::Relaxed), pager.sequence());
|
|
1024
|
+
/// # Ok(())
|
|
1025
|
+
/// # }
|
|
1026
|
+
/// ```
|
|
1027
|
+
pub fn on_root_commit(&self, observer: Box<dyn Fn(u64) + Send + Sync>) -> bool {
|
|
1028
|
+
self.inner.root_observer.set(RootObserver(observer)).is_ok()
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
/// The file's feature sets (D269): as of the last commit, or the last reload for a
|
|
1032
|
+
/// read-only pager.
|
|
1033
|
+
pub fn features(&self) -> Features {
|
|
1034
|
+
lock(&self.inner.state).features
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
/// The current superblock's format version: [`FormatVersion::CURRENT`] once a writable
|
|
1038
|
+
/// pager has committed (an older file is upgraded at `finish`), the file's own on a
|
|
1039
|
+
/// read-only pager, which never upgrades.
|
|
1040
|
+
pub fn format_version(&self) -> FormatVersion {
|
|
1041
|
+
lock(&self.inner.state).version
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/// Replaces the file's feature sets (D269; FORMAT §8.2), committing twice so both
|
|
1045
|
+
/// superblock pages carry them before this returns. Call it before the first write that
|
|
1046
|
+
/// uses a newly set feature, and after the last write that used a cleared one: then no
|
|
1047
|
+
/// page a build may choose disagrees with what the file holds. Each commit names the
|
|
1048
|
+
/// root current when it starts, so a root committed between them is kept, and the new
|
|
1049
|
+
/// sets become current only once the first page is durable: a failed commit leaves them
|
|
1050
|
+
/// as they were (and poisons the pager, as any failed commit does). A crash between the
|
|
1051
|
+
/// two commits leaves the pages disagreeing, and the next writable open rewrites both
|
|
1052
|
+
/// with the current page's sets ([`OpenedPager::finish`]).
|
|
1053
|
+
///
|
|
1054
|
+
/// The caller serializes it with root commits, as root commits are with each other: an
|
|
1055
|
+
/// overlapping one fails ("root commits overlap"). The engine's manifest writer calls it
|
|
1056
|
+
/// under its exclusion, before the commit whose edits first use the feature (D294), so it
|
|
1057
|
+
/// never interleaves with a manifest commit. Equal sets commit nothing.
|
|
1058
|
+
pub fn set_features(&self, features: Features) -> Result<()> {
|
|
1059
|
+
if self.features() == features {
|
|
1060
|
+
return Ok(());
|
|
1061
|
+
}
|
|
1062
|
+
self.inner.commit_features(features)?;
|
|
1063
|
+
Ok(self.inner.commit_features(features)?)
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
/// Allocates the smallest extent of at least `bytes` (64 KiB minimum), growing the file
|
|
1067
|
+
/// if needed. Never returns an extent that is allocated or awaiting reclamation.
|
|
1068
|
+
pub fn allocate(&self, bytes: u64) -> Result<Extent> {
|
|
1069
|
+
self.allocate_from(bytes, false)
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
/// As [`Pager::allocate`], from the lowest-addressed free block that fits whatever its
|
|
1073
|
+
/// size (splitting a larger one) rather than the smallest free class. The manifest's
|
|
1074
|
+
/// snapshot rewrites use it, so the manifest settles low in the file instead of in
|
|
1075
|
+
/// whichever small hole is free, which `shrink` relies on to move it out of the way.
|
|
1076
|
+
pub fn allocate_lowest(&self, bytes: u64) -> Result<Extent> {
|
|
1077
|
+
self.allocate_from(bytes, true)
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/// As [`Pager::allocate_lowest`], but only from free space that starts below `limit`:
|
|
1081
|
+
/// never grows the file. Fails with [`Error::NoSpace`], allocating nothing, if the
|
|
1082
|
+
/// lowest free block that fits does not lie below it. `shrink` rewrites the manifest's
|
|
1083
|
+
/// snapshot this way, so a rewrite that cannot move it down leaves it where it is.
|
|
1084
|
+
pub fn allocate_lowest_below(&self, bytes: u64, limit: Extent) -> Result<Extent> {
|
|
1085
|
+
let class = class_for(bytes)?;
|
|
1086
|
+
if !self.inner.writable {
|
|
1087
|
+
return Err(io_err(
|
|
1088
|
+
ErrorKind::Unsupported,
|
|
1089
|
+
"allocate on a read-only pager",
|
|
1090
|
+
));
|
|
1091
|
+
}
|
|
1092
|
+
let mut alloc = lock(&self.inner.alloc);
|
|
1093
|
+
match alloc.alloc_lowest(class) {
|
|
1094
|
+
Some(e) if e.page < limit.page => Ok(e),
|
|
1095
|
+
Some(e) => {
|
|
1096
|
+
alloc.release_live(e);
|
|
1097
|
+
Err(Error::NoSpace)
|
|
1098
|
+
}
|
|
1099
|
+
None => Err(Error::NoSpace),
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
fn allocate_from(&self, bytes: u64, lowest: bool) -> Result<Extent> {
|
|
1104
|
+
let class = class_for(bytes)?;
|
|
1105
|
+
if !self.inner.writable {
|
|
1106
|
+
return Err(io_err(
|
|
1107
|
+
ErrorKind::Unsupported,
|
|
1108
|
+
"allocate on a read-only pager",
|
|
1109
|
+
));
|
|
1110
|
+
}
|
|
1111
|
+
let mut alloc = lock(&self.inner.alloc);
|
|
1112
|
+
let free = if lowest {
|
|
1113
|
+
alloc.alloc_lowest(class)
|
|
1114
|
+
} else {
|
|
1115
|
+
alloc.alloc_free(class)
|
|
1116
|
+
};
|
|
1117
|
+
if let Some(e) = free {
|
|
1118
|
+
self.maybe_grow_ahead(alloc, lowest);
|
|
1119
|
+
return Ok(e);
|
|
1120
|
+
}
|
|
1121
|
+
// The allocator lock is held across this one `fallocate` and `sync_all` (at most
|
|
1122
|
+
// 64 MiB, once per file growth) so two growths cannot claim the same tail; other
|
|
1123
|
+
// allocations wait. Preallocate rather than extend sparsely: a full disk fails here,
|
|
1124
|
+
// as `NoSpace`. The `sync_all` makes the new length durable now, because root commits
|
|
1125
|
+
// sync with `sync_data`, which need not persist a length change: without it a
|
|
1126
|
+
// power loss after the commit could cut the file short of a published extent.
|
|
1127
|
+
let (_, end) = alloc.grow_target(class);
|
|
1128
|
+
let from = alloc.frontier() * UNIT_BYTES;
|
|
1129
|
+
let started = std::time::Instant::now();
|
|
1130
|
+
self.inner
|
|
1131
|
+
.file
|
|
1132
|
+
.allocate(from, end * UNIT_BYTES - from)
|
|
1133
|
+
.map_err(grow_error)?;
|
|
1134
|
+
// A failed sync poisons (decision D58): it may have been handed the error for pages
|
|
1135
|
+
// a flush wrote, which the next commit's sync would then not report. A commit whose
|
|
1136
|
+
// sync overlaps this one waits for its outcome before publishing (#182).
|
|
1137
|
+
self.inner.side.start();
|
|
1138
|
+
let synced = self.inner.file.sync_all();
|
|
1139
|
+
if synced.is_err() {
|
|
1140
|
+
lock(&self.inner.state).poisoned = true;
|
|
1141
|
+
}
|
|
1142
|
+
let parked = self.inner.side.finish();
|
|
1143
|
+
let grown = synced.map(|()| alloc.alloc_grown(class));
|
|
1144
|
+
self.inner
|
|
1145
|
+
.frontier
|
|
1146
|
+
.store(alloc.frontier(), Ordering::Release);
|
|
1147
|
+
drop(alloc);
|
|
1148
|
+
parked.run();
|
|
1149
|
+
let grown = grown?;
|
|
1150
|
+
self.inner.growths.fetch_add(1, Ordering::Relaxed);
|
|
1151
|
+
self.inner.growth_nanos.fetch_add(
|
|
1152
|
+
u64::try_from(started.elapsed().as_nanos()).unwrap_or(u64::MAX),
|
|
1153
|
+
Ordering::Relaxed,
|
|
1154
|
+
);
|
|
1155
|
+
self.maybe_grow_ahead(lock(&self.inner.alloc), lowest);
|
|
1156
|
+
Ok(grown)
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/// After an allocation (not a relocation's `allocate_lowest`, which packs the file
|
|
1160
|
+
/// toward its start): grows the file ahead of need if no free block of the largest class
|
|
1161
|
+
/// is left ([`Alloc::wants_ahead`]) and no such growth is in flight, so the next large
|
|
1162
|
+
/// allocation finds free space instead of growing the file inline, under the allocator
|
|
1163
|
+
/// lock, on the thread that needs it.
|
|
1164
|
+
///
|
|
1165
|
+
/// The tail is claimed under the lock (placeholders, so nothing is allocated there yet);
|
|
1166
|
+
/// the `fallocate` runs on this thread after the lock is dropped, and the `sync_all`
|
|
1167
|
+
/// that makes the new length durable is submitted to the I/O backend. Its completion
|
|
1168
|
+
/// frees the claimed space, or poisons the pager if it failed (D58); root commits wait
|
|
1169
|
+
/// for its outcome as for any side sync (#182). A failed `fallocate` (a full disk) gives
|
|
1170
|
+
/// the claim back and reports nothing: the next inline growth reports it.
|
|
1171
|
+
fn maybe_grow_ahead(&self, mut alloc: MutexGuard<'_, Alloc>, lowest: bool) {
|
|
1172
|
+
if lowest || !alloc.wants_ahead() || self.inner.ahead.swap(true, Ordering::AcqRel) {
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
let (from, end) = alloc.claim_ahead();
|
|
1176
|
+
drop(alloc);
|
|
1177
|
+
let started = std::time::Instant::now();
|
|
1178
|
+
let allocated = self
|
|
1179
|
+
.inner
|
|
1180
|
+
.file
|
|
1181
|
+
.allocate(from * UNIT_BYTES, (end - from) * UNIT_BYTES);
|
|
1182
|
+
self.inner.ahead_nanos.fetch_add(
|
|
1183
|
+
u64::try_from(started.elapsed().as_nanos()).unwrap_or(u64::MAX),
|
|
1184
|
+
Ordering::Relaxed,
|
|
1185
|
+
);
|
|
1186
|
+
if allocated.is_err() {
|
|
1187
|
+
lock(&self.inner.alloc).release_ahead(from, end, false);
|
|
1188
|
+
self.inner.ahead.store(false, Ordering::Release);
|
|
1189
|
+
return;
|
|
1190
|
+
}
|
|
1191
|
+
self.inner.side.start();
|
|
1192
|
+
let inner = Arc::clone(&self.inner);
|
|
1193
|
+
let flight = self.inner.file.submit_sync_all().map(move |synced| {
|
|
1194
|
+
let mut alloc = lock(&inner.alloc);
|
|
1195
|
+
if synced.is_err() {
|
|
1196
|
+
// Before the sync stops counting as in flight, as in `allocate_from`.
|
|
1197
|
+
lock(&inner.state).poisoned = true;
|
|
1198
|
+
}
|
|
1199
|
+
alloc.release_ahead(from, end, synced.is_ok());
|
|
1200
|
+
inner.frontier.store(alloc.frontier(), Ordering::Release);
|
|
1201
|
+
let parked = inner.side.finish();
|
|
1202
|
+
drop(alloc);
|
|
1203
|
+
inner.ahead.store(false, Ordering::Release);
|
|
1204
|
+
if synced.is_ok() {
|
|
1205
|
+
inner.growths_ahead.fetch_add(1, Ordering::Relaxed);
|
|
1206
|
+
}
|
|
1207
|
+
parked.run();
|
|
1208
|
+
Ok(())
|
|
1209
|
+
});
|
|
1210
|
+
// Kept for a blocking commit to drive (`Inner::wait_side_idle`); dropped once done.
|
|
1211
|
+
if !flight.is_ready() {
|
|
1212
|
+
*lock(&self.inner.ahead_flight) = Some(flight);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
/// Sets the growth ahead of need ([`Pager::allocate`]): once no free block of at least
|
|
1217
|
+
/// `block` bytes (rounded up to a size class) is left and the file is at least `from`
|
|
1218
|
+
/// bytes long, an allocation grows the file by such a block outside the allocator lock.
|
|
1219
|
+
/// The defaults are 64 MiB from 128 MiB. A test hook: tests on the simulator, which
|
|
1220
|
+
/// keeps whole files in memory, set it small so they reach it.
|
|
1221
|
+
#[doc(hidden)]
|
|
1222
|
+
pub fn set_grow_ahead(&self, block: u64, from: u64) -> Result<()> {
|
|
1223
|
+
let class = class_for(block)?;
|
|
1224
|
+
lock(&self.inner.alloc).set_ahead(class, from.div_ceil(UNIT_BYTES));
|
|
1225
|
+
Ok(())
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
/// Returns an extent that was allocated but never published in a root (an abandoned
|
|
1229
|
+
/// flush or compaction output). Freed immediately.
|
|
1230
|
+
///
|
|
1231
|
+
/// Never call it on a published extent: retire that instead. The pager refuses (and
|
|
1232
|
+
/// debug-asserts on) every extent it knows a durable root references — those loaded at
|
|
1233
|
+
/// open and the manifest snapshot and log of each committed root — and retired or
|
|
1234
|
+
/// unallocated ones. It cannot tell an SST or blob extent published in this session
|
|
1235
|
+
/// from pending output (it never reads the manifest), so that part is the caller's
|
|
1236
|
+
/// contract.
|
|
1237
|
+
pub fn abandon(&self, extent: Extent) {
|
|
1238
|
+
let freed = lock(&self.inner.alloc).release_live(extent);
|
|
1239
|
+
debug_assert!(
|
|
1240
|
+
freed,
|
|
1241
|
+
"abandon of an extent that is not pending output: {extent:?}"
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
/// Shrinks an extent that was allocated but never published in a root to the smallest
|
|
1246
|
+
/// one holding `bytes` (64 KiB minimum), and returns it: the same first page, a size
|
|
1247
|
+
/// class no larger. The freed tail is reusable at once. Bytes already written below
|
|
1248
|
+
/// `bytes` stay where they are, so a finished flush or compaction output trims to its
|
|
1249
|
+
/// length before it is published. Unpublished space is never referenced by a durable
|
|
1250
|
+
/// root, so this needs no retirement (D8).
|
|
1251
|
+
///
|
|
1252
|
+
/// Returns `extent` unchanged if `bytes` exceeds it. Never call it on a published
|
|
1253
|
+
/// extent; as with [`Pager::abandon`], the pager refuses (returns `extent` unchanged,
|
|
1254
|
+
/// and debug-asserts) any extent it knows is published, retired or unallocated.
|
|
1255
|
+
pub fn trim(&self, extent: Extent, bytes: u64) -> Extent {
|
|
1256
|
+
let Ok(class) = class_for(bytes) else {
|
|
1257
|
+
return extent;
|
|
1258
|
+
};
|
|
1259
|
+
if class >= extent.size_class {
|
|
1260
|
+
return extent;
|
|
1261
|
+
}
|
|
1262
|
+
let trimmed = lock(&self.inner.alloc).shrink_live(extent, class);
|
|
1263
|
+
debug_assert!(
|
|
1264
|
+
trimmed,
|
|
1265
|
+
"trim of an extent that is not pending output: {extent:?}"
|
|
1266
|
+
);
|
|
1267
|
+
if !trimmed {
|
|
1268
|
+
return extent;
|
|
1269
|
+
}
|
|
1270
|
+
Extent {
|
|
1271
|
+
page: extent.page,
|
|
1272
|
+
size_class: class,
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
fn check_range(extent: Extent, offset: u64, len: usize) -> Result<u64> {
|
|
1277
|
+
match offset.checked_add(len as u64) {
|
|
1278
|
+
Some(end) if end <= extent.len() => Ok(extent.offset() + offset),
|
|
1279
|
+
_ => Err(io_err(ErrorKind::Other, "access past the end of an extent")),
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
/// Writes `data` at `offset` within `extent`.
|
|
1284
|
+
pub fn write(&self, extent: Extent, offset: u64, data: &[u8]) -> Result<()> {
|
|
1285
|
+
let at = Self::check_range(extent, offset, data.len())?;
|
|
1286
|
+
debug_assert!(
|
|
1287
|
+
lock(&self.inner.alloc).is_used(extent),
|
|
1288
|
+
"write to an unallocated extent: {extent:?}"
|
|
1289
|
+
);
|
|
1290
|
+
Ok(self.inner.file.write_at(data, at)?)
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
/// Reads `buf.len()` bytes at `offset` within `extent`.
|
|
1294
|
+
pub fn read(&self, extent: Extent, offset: u64, buf: &mut [u8]) -> Result<()> {
|
|
1295
|
+
let at = Self::check_range(extent, offset, buf.len())?;
|
|
1296
|
+
Ok(self.inner.file.read_at(buf, at)?)
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
/// Publishes `root`: syncs data written so far, writes the non-current superblock slot
|
|
1300
|
+
/// with a higher sequence, and syncs again. The only in-place write of live data in the
|
|
1301
|
+
/// main file. When this returns, a crash recovers to `root`; before it returns, to the
|
|
1302
|
+
/// previous root or `root`. Blocks; use [`Pager::submit_commit_root`] on a shard thread.
|
|
1303
|
+
///
|
|
1304
|
+
/// If a commit fails, or any sync of the file failed before (a growth in
|
|
1305
|
+
/// [`Pager::allocate`], a [`Pager::truncate_tail`]), the pager refuses every later commit
|
|
1306
|
+
/// (an fsync error may have dropped written data, so retrying could publish a root over
|
|
1307
|
+
/// lost bytes); reopen.
|
|
1308
|
+
pub fn commit_root(&self, root: Root) -> Result<()> {
|
|
1309
|
+
Ok(self.inner.commit(root, false)?)
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
/// [`Pager::commit_root`] run by the I/O backend: returns at once, so the manifest task
|
|
1313
|
+
/// never blocks a shard's foreground loop on the two fsyncs. Root commits must not
|
|
1314
|
+
/// overlap; submit the next only after this one resolves.
|
|
1315
|
+
pub fn submit_commit_root(&self, root: Root) -> Completion<()> {
|
|
1316
|
+
Arc::clone(&self.inner).submit_commit(root)
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
/// Re-reads both superblocks and returns the current root if it changed since the last
|
|
1320
|
+
/// call (read-only handles in reader processes, when the shared-memory header names a
|
|
1321
|
+
/// newer manifest version). Never writes. A writable pager already knows its root and
|
|
1322
|
+
/// returns `None`.
|
|
1323
|
+
pub fn reload_root(&self) -> Result<Option<Root>> {
|
|
1324
|
+
if self.inner.writable {
|
|
1325
|
+
return Ok(None);
|
|
1326
|
+
}
|
|
1327
|
+
let (sb, slot, _) = read_superblocks(&self.inner.file)?;
|
|
1328
|
+
let mut st = lock(&self.inner.state);
|
|
1329
|
+
if sb.sequence == st.sequence {
|
|
1330
|
+
return Ok(None);
|
|
1331
|
+
}
|
|
1332
|
+
st.sequence = sb.sequence;
|
|
1333
|
+
st.version = sb.version;
|
|
1334
|
+
st.slot = slot;
|
|
1335
|
+
st.root = Root::from_superblock(&sb);
|
|
1336
|
+
st.features = sb.features;
|
|
1337
|
+
Ok(Some(st.root))
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
/// Marks `extent` unreachable from the root committed at `superseded_at` and every later
|
|
1341
|
+
/// one. It is freed by [`Pager::reclaim`] once no view older than `superseded_at` lives.
|
|
1342
|
+
pub fn retire(&self, extent: Extent, superseded_at: ManifestVersion) {
|
|
1343
|
+
let retired = lock(&self.inner.alloc).retire(extent, superseded_at);
|
|
1344
|
+
debug_assert!(retired, "retire of an extent that is not live: {extent:?}");
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
/// Frees every retired extent whose `superseded_at <= oldest_live`, where `oldest_live`
|
|
1348
|
+
/// is the oldest manifest version any view (in-process or in a reader slot) still uses.
|
|
1349
|
+
///
|
|
1350
|
+
/// `oldest_live` is clamped to the manifest version of the last *completed* root commit:
|
|
1351
|
+
/// until the root that drops an extent is durable, a crash recovers to a root that still
|
|
1352
|
+
/// references it, so it is not freed even if no view uses it (a retire and reclaim may
|
|
1353
|
+
/// run while [`Pager::submit_commit_root`] is still in flight).
|
|
1354
|
+
pub fn reclaim(&self, oldest_live: ManifestVersion) -> usize {
|
|
1355
|
+
let durable = lock(&self.inner.state).root.manifest_version;
|
|
1356
|
+
lock(&self.inner.alloc).reclaim(oldest_live.min(durable))
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
/// As [`Pager::reclaim`], but never waits: `None` (nothing done) if another thread holds
|
|
1360
|
+
/// the allocator or the root state, which it may hold across a growth's `fallocate` and
|
|
1361
|
+
/// `sync_all` or a truncation's sync. For reclaims nobody waits on (the last view of
|
|
1362
|
+
/// an old version going): the holder's own commit or shrink reclaims anyway.
|
|
1363
|
+
pub fn try_reclaim(&self, oldest_live: ManifestVersion) -> Option<usize> {
|
|
1364
|
+
let durable = try_lock(&self.inner.state)?.root.manifest_version;
|
|
1365
|
+
Some(try_lock(&self.inner.alloc)?.reclaim(oldest_live.min(durable)))
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
/// Holds the allocator's lock until the guard drops (test hook: makes
|
|
1369
|
+
/// [`Pager::try_reclaim`] skip, as another thread's growth or commit would).
|
|
1370
|
+
#[doc(hidden)]
|
|
1371
|
+
pub fn hold_alloc_for_test(&self) -> impl Sized + '_ {
|
|
1372
|
+
lock(&self.inner.alloc)
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
/// Extents past the shrink point that must move before the file can shrink.
|
|
1376
|
+
///
|
|
1377
|
+
/// The shrink point is where the live (not retired) extents would end if packed toward
|
|
1378
|
+
/// the start of the file, largest first. The plan is best effort: relocating every
|
|
1379
|
+
/// extent it names, publishing the moves, retiring and reclaiming the old extents and
|
|
1380
|
+
/// then calling [`Pager::truncate_tail`] shrinks the file; if free space below the point
|
|
1381
|
+
/// is still held by retired extents, calling it again after they are reclaimed shrinks
|
|
1382
|
+
/// it further.
|
|
1383
|
+
pub fn shrink_plan(&self) -> Vec<Extent> {
|
|
1384
|
+
lock(&self.inner.alloc).shrink_plan()
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
/// Makes room for `big`, a live extent that [`Pager::relocate`] cannot move because
|
|
1388
|
+
/// small extents fragment every aligned hole of its class below it (#314).
|
|
1389
|
+
///
|
|
1390
|
+
/// Picks a region of `big`'s class below it whose occupants are all live, smaller and
|
|
1391
|
+
/// `movable`, and can each be relocated outside the region and below `big` (by
|
|
1392
|
+
/// [`Pager::relocate_below`], or for the manifest's, a snapshot rewrite's
|
|
1393
|
+
/// [`Pager::allocate_lowest`] or [`Pager::allocate_lowest_below`]: all take the lowest
|
|
1394
|
+
/// free block); of the first few such regions (among the lowest few hundred), the one
|
|
1395
|
+
/// with the least to move.
|
|
1396
|
+
///
|
|
1397
|
+
/// The region is then held: its free space, and the occupants' old extents once they
|
|
1398
|
+
/// are reclaimed, stay unallocatable (placeholders, never published, so free again at
|
|
1399
|
+
/// the next open). The caller moves the occupants out (`big` as the limit), publishes
|
|
1400
|
+
/// the moves and, once their old extents are reclaimed, moves `big` in with
|
|
1401
|
+
/// [`Pager::relocate_into`]; or gives up with [`Pager::release_region`]. `None` if no
|
|
1402
|
+
/// region qualifies; nothing is held then.
|
|
1403
|
+
pub fn clear_for(&self, big: Extent, movable: impl Fn(Extent) -> bool) -> Option<Clearing> {
|
|
1404
|
+
/// Candidate regions tried, and regions looked at, per call.
|
|
1405
|
+
const TRIES: usize = 16;
|
|
1406
|
+
const SCAN: usize = 512;
|
|
1407
|
+
let (region, occupants) = lock(&self.inner.alloc).clear_for(big, &movable, TRIES, SCAN)?;
|
|
1408
|
+
Some(Clearing { region, occupants })
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
/// Stops holding a region [`Pager::clear_for`] cleared: what it held becomes free
|
|
1412
|
+
/// space. Returns false if it was not held (taken by [`Pager::relocate_into`]).
|
|
1413
|
+
pub fn release_region(&self, region: Extent) -> bool {
|
|
1414
|
+
lock(&self.inner.alloc).release_region(region)
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
/// Copies `extent` into the held `region` ([`Pager::clear_for`]), which it takes whole,
|
|
1418
|
+
/// and returns the copy, as [`Pager::relocate`] does; the region is no longer held.
|
|
1419
|
+
/// Fails with [`Error::NoSpace`], changing nothing, while anything but held free space
|
|
1420
|
+
/// is still inside it (an occupant's old extent not reclaimed yet), and with
|
|
1421
|
+
/// [`Error::Io`] if `extent` is not live.
|
|
1422
|
+
pub fn relocate_into(&self, extent: Extent, region: Extent) -> Result<Extent> {
|
|
1423
|
+
if !self.inner.writable {
|
|
1424
|
+
return Err(io_err(
|
|
1425
|
+
ErrorKind::Unsupported,
|
|
1426
|
+
"relocate on a read-only pager",
|
|
1427
|
+
));
|
|
1428
|
+
}
|
|
1429
|
+
let target = {
|
|
1430
|
+
let mut alloc = lock(&self.inner.alloc);
|
|
1431
|
+
if !alloc.is_live(extent) {
|
|
1432
|
+
return Err(io_err(
|
|
1433
|
+
ErrorKind::Other,
|
|
1434
|
+
"relocate of an extent that is not live (unallocated or retired)",
|
|
1435
|
+
));
|
|
1436
|
+
}
|
|
1437
|
+
if region.size_class != extent.size_class || region.page >= extent.page {
|
|
1438
|
+
return Err(Error::NoSpace);
|
|
1439
|
+
}
|
|
1440
|
+
alloc.claim_region(region).ok_or(Error::NoSpace)?
|
|
1441
|
+
};
|
|
1442
|
+
if let Err(e) = self.copy_extent(extent, target) {
|
|
1443
|
+
self.abandon(target);
|
|
1444
|
+
return Err(e);
|
|
1445
|
+
}
|
|
1446
|
+
Ok(target)
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
/// Whether `extent` is exactly an allocated extent that is not retired. A caller that
|
|
1450
|
+
/// read the manifest earlier uses it to tell an extent retired since (a compaction
|
|
1451
|
+
/// replaced it) from a failure, for example after [`Pager::relocate`] refuses.
|
|
1452
|
+
pub fn is_live(&self, extent: Extent) -> bool {
|
|
1453
|
+
lock(&self.inner.alloc).is_live(extent)
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
/// Copies `extent` into a newly allocated extent nearer the start of the file and returns
|
|
1457
|
+
/// it. The caller publishes the move in the manifest, then retires the old extent.
|
|
1458
|
+
///
|
|
1459
|
+
/// Fails with [`Error::NoSpace`] if no free extent of that size lies below `extent`, and
|
|
1460
|
+
/// with [`Error::Io`] if `extent` is not live (see [`Pager::is_live`]).
|
|
1461
|
+
pub fn relocate(&self, extent: Extent) -> Result<Extent> {
|
|
1462
|
+
self.relocate_below(extent, extent)
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
/// As [`Pager::relocate`], into the lowest free extent that lies below `limit` rather
|
|
1466
|
+
/// than below `extent` itself: an occupant of a region [`Pager::clear_for`] reserved may
|
|
1467
|
+
/// move up, as long as it stays below the extent the region is cleared for.
|
|
1468
|
+
pub fn relocate_below(&self, extent: Extent, limit: Extent) -> Result<Extent> {
|
|
1469
|
+
if !self.inner.writable {
|
|
1470
|
+
return Err(io_err(
|
|
1471
|
+
ErrorKind::Unsupported,
|
|
1472
|
+
"relocate on a read-only pager",
|
|
1473
|
+
));
|
|
1474
|
+
}
|
|
1475
|
+
let target = {
|
|
1476
|
+
let mut alloc = lock(&self.inner.alloc);
|
|
1477
|
+
if !alloc.is_live(extent) {
|
|
1478
|
+
return Err(io_err(
|
|
1479
|
+
ErrorKind::Other,
|
|
1480
|
+
"relocate of an extent that is not live (unallocated or retired)",
|
|
1481
|
+
));
|
|
1482
|
+
}
|
|
1483
|
+
match alloc.alloc_lowest(extent.size_class) {
|
|
1484
|
+
Some(t) if t.page < limit.page => t,
|
|
1485
|
+
Some(t) => {
|
|
1486
|
+
alloc.release_live(t);
|
|
1487
|
+
return Err(Error::NoSpace);
|
|
1488
|
+
}
|
|
1489
|
+
None => return Err(Error::NoSpace),
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
1492
|
+
if let Err(e) = self.copy_extent(extent, target) {
|
|
1493
|
+
self.abandon(target);
|
|
1494
|
+
return Err(e);
|
|
1495
|
+
}
|
|
1496
|
+
Ok(target)
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
fn copy_extent(&self, from: Extent, to: Extent) -> Result<()> {
|
|
1500
|
+
const CHUNK: u64 = 1 << 20;
|
|
1501
|
+
let mut buf = vec![0u8; CHUNK.min(from.len()) as usize];
|
|
1502
|
+
let mut at = 0;
|
|
1503
|
+
while at < from.len() {
|
|
1504
|
+
self.read(from, at, &mut buf)?;
|
|
1505
|
+
self.write(to, at, &buf)?;
|
|
1506
|
+
at += buf.len() as u64;
|
|
1507
|
+
}
|
|
1508
|
+
Ok(())
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
/// Truncates the file after its last allocated extent. Returns bytes released.
|
|
1512
|
+
///
|
|
1513
|
+
/// Retired extents still count as allocated (an old view may read them), and free space
|
|
1514
|
+
/// only exists where the durable root references nothing (see [`Pager::reclaim`]). While
|
|
1515
|
+
/// a root commit is in flight this releases nothing and returns 0, so a truncation never
|
|
1516
|
+
/// races the commit's syncs; call it again afterwards. The truncation is synced before
|
|
1517
|
+
/// this returns. The superblock's `file_pages` is refreshed by the next root commit; open
|
|
1518
|
+
/// sizes the allocator from the file length, never from `file_pages`.
|
|
1519
|
+
pub fn truncate_tail(&self) -> Result<u64> {
|
|
1520
|
+
if !self.inner.writable {
|
|
1521
|
+
return Err(io_err(
|
|
1522
|
+
ErrorKind::Unsupported,
|
|
1523
|
+
"truncate on a read-only pager",
|
|
1524
|
+
));
|
|
1525
|
+
}
|
|
1526
|
+
let released = {
|
|
1527
|
+
let mut alloc = lock(&self.inner.alloc);
|
|
1528
|
+
if self.inner.committing.load(Ordering::Acquire) {
|
|
1529
|
+
return Ok(0);
|
|
1530
|
+
}
|
|
1531
|
+
let (end, frontier) = (alloc.used_end(), alloc.frontier());
|
|
1532
|
+
if end >= frontier {
|
|
1533
|
+
return Ok(0);
|
|
1534
|
+
}
|
|
1535
|
+
self.inner.file.set_len(end * UNIT_BYTES)?;
|
|
1536
|
+
alloc.truncate(end);
|
|
1537
|
+
self.inner.frontier.store(end, Ordering::Release);
|
|
1538
|
+
// Synced under the allocator lock, poisoning on failure, as in `allocate`: every
|
|
1539
|
+
// allocation waits for this sync meanwhile, and a commit's next step after it.
|
|
1540
|
+
self.inner.side.start();
|
|
1541
|
+
let synced = self.inner.file.sync_all();
|
|
1542
|
+
if synced.is_err() {
|
|
1543
|
+
lock(&self.inner.state).poisoned = true;
|
|
1544
|
+
}
|
|
1545
|
+
let parked = self.inner.side.finish();
|
|
1546
|
+
drop(alloc);
|
|
1547
|
+
parked.run();
|
|
1548
|
+
synced?;
|
|
1549
|
+
(frontier - end) * UNIT_BYTES
|
|
1550
|
+
};
|
|
1551
|
+
Ok(released)
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
/// Records a clean close in the superblock (bit 0 of flags) via one more root commit.
|
|
1555
|
+
/// Blocks like [`Pager::commit_root`]. The next root commit clears the flag.
|
|
1556
|
+
pub fn mark_clean(&self) -> Result<()> {
|
|
1557
|
+
let root = self.root();
|
|
1558
|
+
Ok(self.inner.commit(root, true)?)
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
/// Allocation statistics.
|
|
1562
|
+
pub fn stats(&self) -> PagerStats {
|
|
1563
|
+
let alloc = lock(&self.inner.alloc);
|
|
1564
|
+
PagerStats {
|
|
1565
|
+
file_bytes: alloc.frontier() * UNIT_BYTES,
|
|
1566
|
+
allocated_bytes: (alloc.used_units() - alloc.retired_units()) * UNIT_BYTES,
|
|
1567
|
+
retired_bytes: alloc.retired_units() * UNIT_BYTES,
|
|
1568
|
+
growths: self.inner.growths.load(Ordering::Relaxed),
|
|
1569
|
+
growth_nanos: self.inner.growth_nanos.load(Ordering::Relaxed),
|
|
1570
|
+
growths_ahead: self.inner.growths_ahead.load(Ordering::Relaxed),
|
|
1571
|
+
ahead_nanos: self.inner.ahead_nanos.load(Ordering::Relaxed),
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
/// Space accounting. `allocated_bytes + retired_bytes` never exceeds `file_bytes`; the rest
|
|
1577
|
+
/// of the file (less the 64 KiB of superblocks and reserved pages) is free.
|
|
1578
|
+
///
|
|
1579
|
+
/// ```
|
|
1580
|
+
/// use pigeonhole_io::VfsRef;
|
|
1581
|
+
/// use pigeonhole_io::sim::SimVfs;
|
|
1582
|
+
/// use pigeonhole_pager::Pager;
|
|
1583
|
+
///
|
|
1584
|
+
/// # fn main() -> pigeonhole_pager::Result<()> {
|
|
1585
|
+
/// let vfs: VfsRef = SimVfs::new(5);
|
|
1586
|
+
/// let pager = Pager::create(&vfs, "/db/data.phdb".as_ref())?;
|
|
1587
|
+
/// let e = pager.allocate(100 << 10)?; // rounds up to 128 KiB
|
|
1588
|
+
/// assert_eq!(pager.stats().allocated_bytes, 128 << 10);
|
|
1589
|
+
/// pager.retire(e, 1);
|
|
1590
|
+
/// assert_eq!(pager.stats().retired_bytes, 128 << 10);
|
|
1591
|
+
/// # Ok(())
|
|
1592
|
+
/// # }
|
|
1593
|
+
/// ```
|
|
1594
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
1595
|
+
#[non_exhaustive]
|
|
1596
|
+
pub struct PagerStats {
|
|
1597
|
+
/// File length in bytes.
|
|
1598
|
+
pub file_bytes: u64,
|
|
1599
|
+
/// Bytes in allocated extents that are not retired.
|
|
1600
|
+
pub allocated_bytes: u64,
|
|
1601
|
+
/// Bytes retired but not yet reclaimed.
|
|
1602
|
+
pub retired_bytes: u64,
|
|
1603
|
+
/// File growths since open: each held the allocator across a `fallocate` and a
|
|
1604
|
+
/// `sync_all` (#28, #182; ICR 0015).
|
|
1605
|
+
pub growths: u64,
|
|
1606
|
+
/// Wall-clock nanoseconds those growths held the allocator.
|
|
1607
|
+
pub growth_nanos: u64,
|
|
1608
|
+
/// File growths ahead of need since open (64 MiB each, outside the allocator lock, the
|
|
1609
|
+
/// sync submitted to the I/O backend), once no free block of that size was left.
|
|
1610
|
+
pub growths_ahead: u64,
|
|
1611
|
+
/// Wall-clock nanoseconds their `fallocate`s took on the allocating thread.
|
|
1612
|
+
pub ahead_nanos: u64,
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
#[cfg(test)]
|
|
1616
|
+
mod tests {
|
|
1617
|
+
use super::*;
|
|
1618
|
+
use pigeonhole_io::sim::SimVfs;
|
|
1619
|
+
|
|
1620
|
+
#[test]
|
|
1621
|
+
fn growths_are_counted() {
|
|
1622
|
+
let vfs: VfsRef = SimVfs::new(1);
|
|
1623
|
+
let pager = Pager::create(&vfs, "/db".as_ref()).unwrap();
|
|
1624
|
+
let before = pager.stats().growths;
|
|
1625
|
+
let e = pager.allocate(1 << 20).unwrap();
|
|
1626
|
+
let s = pager.stats();
|
|
1627
|
+
assert!(s.growths > before, "{s:?}");
|
|
1628
|
+
pager.abandon(e);
|
|
1629
|
+
// Freed space is reused without growing.
|
|
1630
|
+
let e = pager.allocate(1 << 20).unwrap();
|
|
1631
|
+
assert_eq!(pager.stats().growths, s.growths);
|
|
1632
|
+
pager.abandon(e);
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
#[test]
|
|
1636
|
+
fn try_reclaim_does_not_wait_for_a_held_allocator() {
|
|
1637
|
+
// A growth holds the allocator across a `fallocate` and a `sync_all`: a reclaim
|
|
1638
|
+
// nobody waits on gives up instead of blocking for them.
|
|
1639
|
+
let vfs: VfsRef = SimVfs::new(1);
|
|
1640
|
+
let pager = Arc::new(Pager::create(&vfs, "/db".as_ref()).unwrap());
|
|
1641
|
+
let e = pager.allocate(64 << 10).unwrap();
|
|
1642
|
+
pager.abandon(e);
|
|
1643
|
+
let held = lock(&pager.inner.alloc);
|
|
1644
|
+
let (tx, rx) = std::sync::mpsc::channel();
|
|
1645
|
+
let p = Arc::clone(&pager);
|
|
1646
|
+
let t = std::thread::spawn(move || tx.send(p.try_reclaim(u64::MAX)).unwrap());
|
|
1647
|
+
let got = rx
|
|
1648
|
+
.recv_timeout(std::time::Duration::from_secs(10))
|
|
1649
|
+
.expect("try_reclaim blocked on the held allocator");
|
|
1650
|
+
assert_eq!(got, None);
|
|
1651
|
+
drop(held);
|
|
1652
|
+
t.join().unwrap();
|
|
1653
|
+
assert_eq!(pager.try_reclaim(u64::MAX), Some(0));
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
fn page_of(vfs: &VfsRef, page: u64) -> Superblock {
|
|
1657
|
+
let f = vfs.open("/db".as_ref(), OpenOptions::read()).unwrap();
|
|
1658
|
+
let mut buf = [0u8; PAGE_SIZE];
|
|
1659
|
+
f.read_at(&mut buf, page * PAGE_SIZE as u64).unwrap();
|
|
1660
|
+
Superblock::decode(&buf).unwrap()
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
#[test]
|
|
1664
|
+
fn a_feature_change_keeps_a_root_committed_between_its_two_commits() {
|
|
1665
|
+
// perf287's S1 on #858: each of `set_features`' commits names the root current when
|
|
1666
|
+
// it starts, so a root committed between them is never replaced by an older one.
|
|
1667
|
+
let vfs: VfsRef = SimVfs::new(3);
|
|
1668
|
+
let pager = Pager::create(&vfs, "/db".as_ref()).unwrap();
|
|
1669
|
+
let root = |manifest_version| Root {
|
|
1670
|
+
manifest_version,
|
|
1671
|
+
..Root::default()
|
|
1672
|
+
};
|
|
1673
|
+
pager.commit_root(root(1)).unwrap();
|
|
1674
|
+
let f = Features {
|
|
1675
|
+
compat: 1 << 2,
|
|
1676
|
+
..Features::default()
|
|
1677
|
+
};
|
|
1678
|
+
// `set_features`' two steps, with the manifest writer's R2 between them.
|
|
1679
|
+
pager.inner.commit_features(f).unwrap();
|
|
1680
|
+
assert_eq!(pager.features(), f);
|
|
1681
|
+
pager.commit_root(root(2)).unwrap();
|
|
1682
|
+
pager.inner.commit_features(f).unwrap();
|
|
1683
|
+
assert_eq!(pager.root().manifest_version, 2, "R2 was replaced");
|
|
1684
|
+
let pages = [SUPERBLOCK_PAGE_A, SUPERBLOCK_PAGE_B].map(|p| page_of(&vfs, p));
|
|
1685
|
+
assert!(pages.iter().all(|sb| sb.features == f), "{pages:?}");
|
|
1686
|
+
let newest = pages.iter().max_by_key(|sb| sb.sequence).unwrap();
|
|
1687
|
+
assert_eq!(newest.manifest_version, 2, "the newest page names R2");
|
|
1688
|
+
assert!(
|
|
1689
|
+
pages.iter().all(|sb| sb.manifest_version == 2),
|
|
1690
|
+
"a page went back to R1: {pages:?}"
|
|
1691
|
+
);
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
#[test]
|
|
1695
|
+
fn a_failed_feature_commit_leaves_the_sets_as_they_were() {
|
|
1696
|
+
let sim = SimVfs::new(4);
|
|
1697
|
+
let vfs: VfsRef = sim.clone();
|
|
1698
|
+
let pager = Pager::create(&vfs, "/db".as_ref()).unwrap();
|
|
1699
|
+
// Every write from here on fails: the first commit's superblock write among them.
|
|
1700
|
+
let mut plan = pigeonhole_io::sim::FaultPlan::none();
|
|
1701
|
+
plan.enospc_after_bytes = Some(0);
|
|
1702
|
+
sim.set_faults(plan);
|
|
1703
|
+
let f = Features {
|
|
1704
|
+
compat: 1,
|
|
1705
|
+
..Features::default()
|
|
1706
|
+
};
|
|
1707
|
+
assert!(pager.set_features(f).is_err());
|
|
1708
|
+
assert_eq!(pager.features(), Features::default());
|
|
1709
|
+
}
|
|
1710
|
+
}
|