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,2463 @@
|
|
|
1
|
+
use std::borrow::Cow;
|
|
2
|
+
use std::ops::{Bound, Range, RangeBounds};
|
|
3
|
+
use std::sync::Arc;
|
|
4
|
+
|
|
5
|
+
use pigeonhole_engine::{
|
|
6
|
+
CellData, ColumnPosition, FamilyId, KeyCursor, KeySet, KnnSkips, KnnVisitor, QualifierFilter,
|
|
7
|
+
ReadInput, ReadSpec, ReduceSpec, ScanCursor, ScanSpec, TableInfo, TopK, ValuePredicate,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
use pigeonhole_format::vector::QueryBuf;
|
|
11
|
+
use smallvec::SmallVec;
|
|
12
|
+
|
|
13
|
+
use crate::cell::RowBuf;
|
|
14
|
+
use crate::table::TableCore;
|
|
15
|
+
use crate::{CellEntry, CellRef, Result, Row, RowRef, Snapshot};
|
|
16
|
+
|
|
17
|
+
/// A predicate on a cell value, evaluated inside the read path before materialization.
|
|
18
|
+
///
|
|
19
|
+
/// Byte predicates compare the value bytes (what [`CellRef::value`](crate::CellRef::value)
|
|
20
|
+
/// returns); `I64` matches `i64` (and varint) values only (decision D77).
|
|
21
|
+
///
|
|
22
|
+
/// ```
|
|
23
|
+
/// use std::cmp::Ordering;
|
|
24
|
+
/// use pigeonhole::{Family, Options, Pigeonhole, ValueFilter};
|
|
25
|
+
///
|
|
26
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
27
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
28
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
29
|
+
/// let t = db.table("t")?.family("f", Family::default()).create_if_missing()?;
|
|
30
|
+
/// t.mutate(b"a").put_i64("f", b"score", 10).commit()?;
|
|
31
|
+
/// t.mutate(b"b").put_i64("f", b"score", 200).commit()?;
|
|
32
|
+
///
|
|
33
|
+
/// let high: Vec<Vec<u8>> = t
|
|
34
|
+
/// .scan_prefix(b"")
|
|
35
|
+
/// .value_filter(ValueFilter::I64(Ordering::Greater, 100))
|
|
36
|
+
/// .iter()?
|
|
37
|
+
/// .map(|r| r.map(|r| r.key().to_vec()))
|
|
38
|
+
/// .collect::<pigeonhole::Result<_>>()?;
|
|
39
|
+
/// assert_eq!(high, [b"b".to_vec()]);
|
|
40
|
+
/// # db.close()?;
|
|
41
|
+
/// # Ok(())
|
|
42
|
+
/// # }
|
|
43
|
+
/// ```
|
|
44
|
+
#[derive(Debug, Clone, PartialEq)]
|
|
45
|
+
#[non_exhaustive]
|
|
46
|
+
pub enum ValueFilter {
|
|
47
|
+
/// Value bytes equal.
|
|
48
|
+
Equals(Vec<u8>),
|
|
49
|
+
/// Value bytes start with.
|
|
50
|
+
Prefix(Vec<u8>),
|
|
51
|
+
/// The value is an `i64` that compares to the operand as given.
|
|
52
|
+
I64(std::cmp::Ordering, i64),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
impl ValueFilter {
|
|
56
|
+
pub(crate) fn to_engine(&self) -> ValuePredicate {
|
|
57
|
+
self.clone().into_engine()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// [`ValueFilter::to_engine`] without the copy, for a filter the caller owns.
|
|
61
|
+
pub(crate) fn into_engine(self) -> ValuePredicate {
|
|
62
|
+
match self {
|
|
63
|
+
ValueFilter::Equals(v) => ValuePredicate::Equals(v),
|
|
64
|
+
ValueFilter::Prefix(v) => ValuePredicate::Prefix(v),
|
|
65
|
+
ValueFilter::I64(o, v) => ValuePredicate::I64(o, v),
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/// A condition for a conditional mutation ([`RowMutation::commit_if`](crate::RowMutation::commit_if)).
|
|
71
|
+
///
|
|
72
|
+
/// See [`RowMutation`](crate::RowMutation) for an example.
|
|
73
|
+
#[derive(Debug, Clone, PartialEq)]
|
|
74
|
+
#[non_exhaustive]
|
|
75
|
+
pub enum Condition {
|
|
76
|
+
/// The column has a visible version.
|
|
77
|
+
Exists {
|
|
78
|
+
/// Family.
|
|
79
|
+
family: String,
|
|
80
|
+
/// Qualifier.
|
|
81
|
+
qualifier: Vec<u8>,
|
|
82
|
+
},
|
|
83
|
+
/// The column has no visible version.
|
|
84
|
+
Absent {
|
|
85
|
+
/// Family.
|
|
86
|
+
family: String,
|
|
87
|
+
/// Qualifier.
|
|
88
|
+
qualifier: Vec<u8>,
|
|
89
|
+
},
|
|
90
|
+
/// The column's newest value matches.
|
|
91
|
+
Value {
|
|
92
|
+
/// Family.
|
|
93
|
+
family: String,
|
|
94
|
+
/// Qualifier.
|
|
95
|
+
qualifier: Vec<u8>,
|
|
96
|
+
/// Condition on the value.
|
|
97
|
+
filter: ValueFilter,
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
mod budget;
|
|
102
|
+
pub use budget::{KeysPage, KeysPosition, NearestPage, ScanPage, ScanPosition};
|
|
103
|
+
|
|
104
|
+
/// A read's selected families, resolved: inline for up to four.
|
|
105
|
+
pub(crate) type FamilyIds = SmallVec<[FamilyId; 4]>;
|
|
106
|
+
|
|
107
|
+
/// The selection shared by row reads and scans, with family names kept until the read
|
|
108
|
+
/// starts (builders never fail; errors surface at `read`/`iter`).
|
|
109
|
+
#[derive(Debug, Clone)]
|
|
110
|
+
struct Selection {
|
|
111
|
+
/// The selected families' names, one after another (`ends` marks where each ends):
|
|
112
|
+
/// inline for a couple of short names, so a read allocates nothing for them (#287).
|
|
113
|
+
names: SmallVec<[u8; 32]>,
|
|
114
|
+
ends: SmallVec<[u32; 4]>,
|
|
115
|
+
spec: ReadSpec,
|
|
116
|
+
snapshot: Option<Snapshot>,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
impl Selection {
|
|
120
|
+
fn new() -> Self {
|
|
121
|
+
let mut spec = ReadSpec::default();
|
|
122
|
+
spec.versions = 1;
|
|
123
|
+
Self {
|
|
124
|
+
names: SmallVec::new(),
|
|
125
|
+
ends: SmallVec::new(),
|
|
126
|
+
spec,
|
|
127
|
+
snapshot: None,
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
fn push_family(&mut self, name: &str) {
|
|
132
|
+
self.names.extend_from_slice(name.as_bytes());
|
|
133
|
+
let end = u32::try_from(self.names.len()).expect("family names under 4 GiB");
|
|
134
|
+
self.ends.push(end);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/// The selected families' names, in order.
|
|
138
|
+
fn family_names(&self) -> impl Iterator<Item = &str> {
|
|
139
|
+
let mut start = 0;
|
|
140
|
+
self.ends.iter().map(move |&end| {
|
|
141
|
+
let name = &self.names[start..end as usize];
|
|
142
|
+
start = end as usize;
|
|
143
|
+
std::str::from_utf8(name).expect("pushed from a str")
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
fn qualifier_bounds(&mut self, start: Bound<&[u8]>, end: Bound<&[u8]>) {
|
|
148
|
+
self.spec.qualifiers =
|
|
149
|
+
QualifierFilter::Range(start.map(<[u8]>::to_vec), end.map(<[u8]>::to_vec));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
fn time_range(&mut self, range: Range<u64>) {
|
|
153
|
+
self.spec.time_range = Some((range.start, range.end));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/// For a read as of now (no snapshot given): the table's info and the families to read,
|
|
157
|
+
/// resolved from the current catalog before the engine loads its view, so the view sees
|
|
158
|
+
/// every one of them. With no families selected, that is every family of this catalog
|
|
159
|
+
/// entry, named explicitly: a family added before the view loads is not read, as the
|
|
160
|
+
/// entry could not name its cells. `None` when a name does not resolve (or the table has
|
|
161
|
+
/// no family): the caller then takes the snapshot path, which reports it exactly as
|
|
162
|
+
/// before (a family created meanwhile is found there).
|
|
163
|
+
fn start_latest(&self, core: &TableCore) -> Result<Option<(Arc<TableInfo>, FamilyIds)>> {
|
|
164
|
+
core.db.check_open()?;
|
|
165
|
+
let info = core.current_info();
|
|
166
|
+
let mut ids = SmallVec::new();
|
|
167
|
+
for name in self.family_names() {
|
|
168
|
+
let Some(family) = info.family(name) else {
|
|
169
|
+
return Ok(None);
|
|
170
|
+
};
|
|
171
|
+
if !ids.contains(&family.id) {
|
|
172
|
+
ids.push(family.id);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if self.ends.is_empty() {
|
|
176
|
+
ids.extend(info.families.iter().map(|f| f.id));
|
|
177
|
+
}
|
|
178
|
+
if ids.is_empty() {
|
|
179
|
+
return Ok(None);
|
|
180
|
+
}
|
|
181
|
+
Ok(Some((info, ids)))
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/// Takes the snapshot, then resolves the projection against the catalog as of then: the
|
|
185
|
+
/// table's info, which names every family the read can return, the snapshot, and the
|
|
186
|
+
/// selected families' ids (empty: every family).
|
|
187
|
+
fn start(
|
|
188
|
+
&mut self,
|
|
189
|
+
core: &TableCore,
|
|
190
|
+
) -> Result<(Arc<TableInfo>, pigeonhole_engine::Snapshot, FamilyIds)> {
|
|
191
|
+
core.db.check_open()?;
|
|
192
|
+
let snapshot = match self.snapshot.take() {
|
|
193
|
+
Some(s) => {
|
|
194
|
+
core.db.check_snapshot(&s)?;
|
|
195
|
+
s.inner
|
|
196
|
+
}
|
|
197
|
+
// The retry only with a supervisor (`Db::supervised`).
|
|
198
|
+
None if core.db.supervised() => core.snapshot_supervised()?,
|
|
199
|
+
None => core.with(pigeonhole_engine::Engine::snapshot)?,
|
|
200
|
+
};
|
|
201
|
+
// The catalog as of the snapshot names every family it can return, and resolves a
|
|
202
|
+
// family dropped (or dropped and created again) since as the snapshot saw it; a name
|
|
203
|
+
// only the current catalog knows resolves there and reads nothing (#892).
|
|
204
|
+
let info = core.info_at(&snapshot);
|
|
205
|
+
let mut ids = SmallVec::new();
|
|
206
|
+
for name in self.family_names() {
|
|
207
|
+
let id = match info.family(name) {
|
|
208
|
+
Some(f) => f.id,
|
|
209
|
+
None => core.family_id(name)?,
|
|
210
|
+
};
|
|
211
|
+
if !ids.contains(&id) {
|
|
212
|
+
ids.push(id);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
Ok((info, snapshot, ids))
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/// Implements the builder methods `RowRead` and `Scan` share.
|
|
220
|
+
macro_rules! selection_methods {
|
|
221
|
+
() => {
|
|
222
|
+
/// Read only these families (default: all), in this order.
|
|
223
|
+
pub fn families<'f>(mut self, families: impl IntoIterator<Item = &'f str>) -> Self {
|
|
224
|
+
self.sel.names.clear();
|
|
225
|
+
self.sel.ends.clear();
|
|
226
|
+
for name in families {
|
|
227
|
+
self.sel.push_family(name);
|
|
228
|
+
}
|
|
229
|
+
self
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/// Add one family to the projection.
|
|
233
|
+
pub fn family(mut self, family: &str) -> Self {
|
|
234
|
+
self.sel.push_family(family);
|
|
235
|
+
self
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/// Only qualifiers starting with `prefix`.
|
|
239
|
+
pub fn qualifier_prefix(mut self, prefix: &[u8]) -> Self {
|
|
240
|
+
self.sel.spec.qualifiers = QualifierFilter::Prefix(prefix.to_vec());
|
|
241
|
+
self
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/// Only qualifiers within `range`.
|
|
245
|
+
pub fn qualifier_range<'k, K: AsRef<[u8]> + ?Sized + 'k>(
|
|
246
|
+
mut self,
|
|
247
|
+
range: impl RangeBounds<&'k K>,
|
|
248
|
+
) -> Self {
|
|
249
|
+
self.sel.qualifier_bounds(
|
|
250
|
+
range.start_bound().map(|k| k.as_ref()),
|
|
251
|
+
range.end_bound().map(|k| k.as_ref()),
|
|
252
|
+
);
|
|
253
|
+
self
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/// Only qualifiers within explicit bounds (the non-generic form a C ABI exports).
|
|
257
|
+
pub fn qualifier_bounds(mut self, start: Bound<&[u8]>, end: Bound<&[u8]>) -> Self {
|
|
258
|
+
self.sel.qualifier_bounds(start, end);
|
|
259
|
+
self
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/// Only the newest version of each column (the default).
|
|
263
|
+
pub fn latest(mut self) -> Self {
|
|
264
|
+
self.sel.spec.versions = 1;
|
|
265
|
+
self
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/// Only versions with timestamps in `range`.
|
|
269
|
+
pub fn time_range(mut self, range: Range<u64>) -> Self {
|
|
270
|
+
self.sel.time_range(range);
|
|
271
|
+
self
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/// Only cells whose value matches.
|
|
275
|
+
pub fn value_filter(mut self, filter: ValueFilter) -> Self {
|
|
276
|
+
self.sel.spec.value = Some(filter.into_engine());
|
|
277
|
+
self
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/// Read as of `snapshot` instead of now.
|
|
281
|
+
pub fn snapshot(mut self, snapshot: &Snapshot) -> Self {
|
|
282
|
+
self.sel.snapshot = Some(snapshot.clone());
|
|
283
|
+
self
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/// A row read under construction. Finish with [`RowRead::read`].
|
|
289
|
+
///
|
|
290
|
+
/// ```
|
|
291
|
+
/// use pigeonhole::{Family, Options, Pigeonhole};
|
|
292
|
+
///
|
|
293
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
294
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
295
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
296
|
+
/// let t = db.table("t")?.family("temp", Family::default()).create_if_missing()?;
|
|
297
|
+
/// for (ts, v) in [(10u64, b"20.5"), (20, b"21.0"), (30, b"21.5")] {
|
|
298
|
+
/// t.mutate(b"sensor:7").put_at("temp", b"c", ts, v).commit()?;
|
|
299
|
+
/// }
|
|
300
|
+
///
|
|
301
|
+
/// let row = t.row(b"sensor:7").family("temp").versions(2).read()?.unwrap();
|
|
302
|
+
/// let versions: Vec<u64> = row.iter().map(|e| e.cell.timestamp()).collect();
|
|
303
|
+
/// assert_eq!(versions, [30, 20]);
|
|
304
|
+
///
|
|
305
|
+
/// let window = t.row(b"sensor:7").versions(0).time_range(10..30).read()?.unwrap();
|
|
306
|
+
/// assert_eq!(window.len(), 2);
|
|
307
|
+
/// assert!(t.row(b"sensor:8").read()?.is_none());
|
|
308
|
+
/// # db.close()?;
|
|
309
|
+
/// # Ok(())
|
|
310
|
+
/// # }
|
|
311
|
+
/// ```
|
|
312
|
+
#[derive(Debug)]
|
|
313
|
+
#[must_use = "a row read does nothing until .read()"]
|
|
314
|
+
pub struct RowRead<'t> {
|
|
315
|
+
core: &'t TableCore,
|
|
316
|
+
row: Vec<u8>,
|
|
317
|
+
sel: Selection,
|
|
318
|
+
/// Where an earlier walk of the row stopped ([`RowRead::resume_after`]).
|
|
319
|
+
resume: Option<ColumnPosition>,
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
impl<'t> RowRead<'t> {
|
|
323
|
+
/// The latest-version read with a supervisor: run again on the recovered engine if it
|
|
324
|
+
/// got `Closed`. Out of line, so the plain arm keeps main's codegen (`TableCore::get_latest_supervised`).
|
|
325
|
+
#[cold]
|
|
326
|
+
#[inline(never)]
|
|
327
|
+
fn read_latest_supervised(
|
|
328
|
+
&self,
|
|
329
|
+
table: pigeonhole_engine::TableId,
|
|
330
|
+
families: &[pigeonhole_engine::FamilyId],
|
|
331
|
+
buf: &mut RowBuf,
|
|
332
|
+
) -> Result<bool> {
|
|
333
|
+
self.core.db.retry_closed(|| {
|
|
334
|
+
self.core
|
|
335
|
+
.engine()
|
|
336
|
+
.read_row_latest_into(table, &self.row, families, &self.sel.spec, buf)
|
|
337
|
+
.map_err(crate::Error::from)
|
|
338
|
+
})
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
pub(crate) fn new(core: &'t TableCore, row: &[u8]) -> Self {
|
|
342
|
+
Self {
|
|
343
|
+
core,
|
|
344
|
+
row: row.to_vec(),
|
|
345
|
+
sel: Selection::new(),
|
|
346
|
+
resume: None,
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
selection_methods!();
|
|
351
|
+
|
|
352
|
+
/// Resume after `position`, the column an earlier walk of a row of this table stopped
|
|
353
|
+
/// at ([`RowPages::position`], [`RowCells::position`]; D297): the families the selection
|
|
354
|
+
/// names before the position's family are skipped, the position's family starts after
|
|
355
|
+
/// its column (all its versions), and later families start at the selection's own
|
|
356
|
+
/// qualifier bound. A position whose family the read does not select (one dropped
|
|
357
|
+
/// since, or not named) fails the read with `InvalidArgument`.
|
|
358
|
+
///
|
|
359
|
+
/// A chain of calls is one consistent read of the row only under one
|
|
360
|
+
/// [`snapshot`](RowRead::snapshot); without one, each call reads as of its own start,
|
|
361
|
+
/// so a column written or deleted between calls may be seen twice or not at all. A
|
|
362
|
+
/// position from another table fails the read with `InvalidArgument`; one from another
|
|
363
|
+
/// row of the same table positions this row's walk at the same column (the caller's
|
|
364
|
+
/// responsibility).
|
|
365
|
+
pub fn resume_after(mut self, position: &RowPosition) -> Self {
|
|
366
|
+
self.resume = Some(position.0.clone());
|
|
367
|
+
self
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/// Up to `n` versions of each column (0: all retained).
|
|
371
|
+
pub fn versions(mut self, n: u32) -> Self {
|
|
372
|
+
self.sel.spec.versions = n;
|
|
373
|
+
self
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/// At most `n` columns per family. The same limit as [`Scan::column_limit`], which
|
|
377
|
+
/// applies it to each row.
|
|
378
|
+
pub fn column_limit(mut self, n: u32) -> Self {
|
|
379
|
+
self.sel.spec.columns_per_row = n;
|
|
380
|
+
self
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/// Performs the read. `None` if the row has no matching cell.
|
|
384
|
+
pub fn read(mut self) -> Result<Option<RowRef<'t>>> {
|
|
385
|
+
if self.resume.is_some() {
|
|
386
|
+
return self.read_resumed();
|
|
387
|
+
}
|
|
388
|
+
// As of now, a read takes no snapshot to create and drop (#287); one given, or a
|
|
389
|
+
// family the current catalog does not know yet, goes through a snapshot.
|
|
390
|
+
let latest = match self.sel.snapshot {
|
|
391
|
+
None => self.sel.start_latest(self.core)?,
|
|
392
|
+
Some(_) => None,
|
|
393
|
+
};
|
|
394
|
+
let (info, snapshot, families) = match latest {
|
|
395
|
+
Some((info, families)) => (info, None, families),
|
|
396
|
+
None => {
|
|
397
|
+
let (info, snapshot, families) = self.sel.start(self.core)?;
|
|
398
|
+
(info, Some(snapshot), families)
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
// The engine resolves the cells straight into the row this returns (#287): no
|
|
402
|
+
// intermediate row and no second copy of each cell.
|
|
403
|
+
let mut buf = RowBuf::new(info, 0);
|
|
404
|
+
let table = self.core.info.id;
|
|
405
|
+
let any = match &snapshot {
|
|
406
|
+
// The retry only with a supervisor (`Db::supervised`).
|
|
407
|
+
None if self.core.db.supervised() => {
|
|
408
|
+
self.read_latest_supervised(table, &families, &mut buf)?
|
|
409
|
+
}
|
|
410
|
+
None => self.core.with(|e| {
|
|
411
|
+
e.read_row_latest_into(table, &self.row, &families, &self.sel.spec, &mut buf)
|
|
412
|
+
})?,
|
|
413
|
+
Some(snapshot) => self.core.with(|e| {
|
|
414
|
+
e.read_row_into_families(
|
|
415
|
+
snapshot,
|
|
416
|
+
table,
|
|
417
|
+
&self.row,
|
|
418
|
+
&families,
|
|
419
|
+
&self.sel.spec,
|
|
420
|
+
&mut buf,
|
|
421
|
+
)
|
|
422
|
+
})?,
|
|
423
|
+
};
|
|
424
|
+
if !any {
|
|
425
|
+
return Ok(None);
|
|
426
|
+
}
|
|
427
|
+
buf.key = self.row;
|
|
428
|
+
Ok(Some(RowRef::owned(buf)))
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
#[cfg(feature = "async")]
|
|
433
|
+
impl RowRead<'_> {
|
|
434
|
+
/// [`read`](RowRead::read) as a future resolving to an owned [`Row`]: a memtable or cache
|
|
435
|
+
/// hit is read at the call and resolves on the first poll, and a block the cache does
|
|
436
|
+
/// not hold is read asynchronously (see [`nonblocking`](crate::nonblocking)).
|
|
437
|
+
pub fn read_async(mut self) -> crate::nonblocking::RowFuture {
|
|
438
|
+
// A resumed read is a walk of the row's cells (D297), read at the call.
|
|
439
|
+
if self.resume.is_some() {
|
|
440
|
+
return crate::nonblocking::RowFuture::done(
|
|
441
|
+
self.read_resumed().map(|r| r.map(|r| r.to_owned())),
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
let started = (|| {
|
|
445
|
+
let latest = match self.sel.snapshot {
|
|
446
|
+
None => self.sel.start_latest(self.core)?,
|
|
447
|
+
Some(_) => None,
|
|
448
|
+
};
|
|
449
|
+
let (engine, table) = (&self.core.engine(), self.core.info.id);
|
|
450
|
+
Ok(Ok(match latest {
|
|
451
|
+
Some((info, families)) => {
|
|
452
|
+
// First at the call, as the sync read (#709): a hit needs no future, so
|
|
453
|
+
// concurrent readers share no reference count beyond the sync read's.
|
|
454
|
+
let mut buf = RowBuf::new(info, 0);
|
|
455
|
+
let missed = match engine.try_read_row_latest(
|
|
456
|
+
table,
|
|
457
|
+
&self.row,
|
|
458
|
+
&families,
|
|
459
|
+
&self.sel.spec,
|
|
460
|
+
&mut buf,
|
|
461
|
+
) {
|
|
462
|
+
Ok(r) => {
|
|
463
|
+
return Ok(Err(r.map_err(crate::Error::from).map(|any| {
|
|
464
|
+
any.then(|| {
|
|
465
|
+
buf.key = std::mem::take(&mut self.row);
|
|
466
|
+
Row::new(buf)
|
|
467
|
+
})
|
|
468
|
+
})));
|
|
469
|
+
}
|
|
470
|
+
Err(missed) => missed,
|
|
471
|
+
};
|
|
472
|
+
// A miss may have left cells in `buf`: the future starts from an empty
|
|
473
|
+
// row for the same table entry, waiting on the read the miss submitted.
|
|
474
|
+
let info = buf.info.take().expect("set by RowBuf::new");
|
|
475
|
+
engine.read_row_latest_async_after(
|
|
476
|
+
missed,
|
|
477
|
+
table,
|
|
478
|
+
&self.row,
|
|
479
|
+
&families,
|
|
480
|
+
&self.sel.spec,
|
|
481
|
+
RowBuf::new(info, 0),
|
|
482
|
+
)
|
|
483
|
+
}
|
|
484
|
+
None => {
|
|
485
|
+
let (info, snapshot, families) = self.sel.start(self.core)?;
|
|
486
|
+
engine.read_row_async(
|
|
487
|
+
&snapshot,
|
|
488
|
+
table,
|
|
489
|
+
&self.row,
|
|
490
|
+
&families,
|
|
491
|
+
&self.sel.spec,
|
|
492
|
+
RowBuf::new(info, 0),
|
|
493
|
+
)
|
|
494
|
+
}
|
|
495
|
+
}))
|
|
496
|
+
})();
|
|
497
|
+
match started {
|
|
498
|
+
Ok(Err(done)) => crate::nonblocking::RowFuture::done(done),
|
|
499
|
+
Ok(Ok(f)) => crate::nonblocking::RowFuture::new(Ok(f), self.row),
|
|
500
|
+
Err(e) => crate::nonblocking::RowFuture::new(Err(e), self.row),
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/// A multi-get under construction ([`Table::keys`](crate::Table::keys), D299). Finish with
|
|
506
|
+
/// [`KeysRead::read`].
|
|
507
|
+
///
|
|
508
|
+
/// It reads the rows of a [`KeySet`] in key order, under one snapshot (the one given, or one
|
|
509
|
+
/// taken at `read`), with the selection applied to every row. Each tablet's read is set up
|
|
510
|
+
/// once for all of its keys, and each row's sources move forward from the previous key's:
|
|
511
|
+
/// sorted keys that share blocks share their decode. Keys whose row has no cell the
|
|
512
|
+
/// selection keeps are skipped. The row cache is not consulted.
|
|
513
|
+
///
|
|
514
|
+
/// ```
|
|
515
|
+
/// use pigeonhole::{Family, KeySet, Options, Pigeonhole};
|
|
516
|
+
///
|
|
517
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
518
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
519
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
520
|
+
/// let g = db.table("g")?.family("out", Family::default()).create_if_missing()?;
|
|
521
|
+
/// g.mutate(b"v:1").put("out", b"v:2", b"").put("out", b"v:3", b"").commit()?;
|
|
522
|
+
/// g.mutate(b"v:3").put("out", b"v:1", b"").commit()?;
|
|
523
|
+
///
|
|
524
|
+
/// // One hop of a BFS: the neighbours of every node in the frontier.
|
|
525
|
+
/// let frontier = KeySet::from_unsorted([&b"v:3"[..], b"v:1", b"v:9"]);
|
|
526
|
+
/// let mut next = Vec::new();
|
|
527
|
+
/// let mut rows = g.keys(&frontier).family("out").read()?;
|
|
528
|
+
/// while let Some((i, row)) = rows.next()? {
|
|
529
|
+
/// assert!(frontier.get(i) != b"v:9"); // no row: skipped
|
|
530
|
+
/// next.extend(row.iter().map(|e| e.qualifier.to_vec()));
|
|
531
|
+
/// }
|
|
532
|
+
/// assert_eq!(next.len(), 3);
|
|
533
|
+
/// # db.close()?;
|
|
534
|
+
/// # Ok(())
|
|
535
|
+
/// # }
|
|
536
|
+
/// ```
|
|
537
|
+
#[derive(Debug)]
|
|
538
|
+
#[must_use = "a multi-get does nothing until .read()"]
|
|
539
|
+
pub struct KeysRead<'t> {
|
|
540
|
+
core: &'t Arc<TableCore>,
|
|
541
|
+
keys: KeySet,
|
|
542
|
+
sel: Selection,
|
|
543
|
+
/// D308: where [`KeysRead::read_within`] resumes ([`KeysRead::resume_after`]).
|
|
544
|
+
after: Option<KeysPosition>,
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
impl<'t> KeysRead<'t> {
|
|
548
|
+
/// The `k` vectors nearest to the `f32` `query` in this read's one vector family (D296,
|
|
549
|
+
/// D303), as a [`Nearest`] to run: exact, ranked by the family's metric, ties by row
|
|
550
|
+
/// then qualifier. The read's selection applies (qualifiers, time range, value filter),
|
|
551
|
+
/// with the newest version of each cell.
|
|
552
|
+
pub fn nearest_f32(self, query: &[f32], k: usize) -> Nearest<'t> {
|
|
553
|
+
self.nearest(QueryBuf::F32(query.into()), k)
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/// [`nearest_f32`](Self::nearest_f32) for an `i8` vector family.
|
|
557
|
+
pub fn nearest_i8(self, query: &[i8], k: usize) -> Nearest<'t> {
|
|
558
|
+
self.nearest(QueryBuf::I8(query.into()), k)
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/// [`nearest_f32`](Self::nearest_f32) for a bit vector family (`query` packed eight bits
|
|
562
|
+
/// to a byte, least significant first).
|
|
563
|
+
pub fn nearest_bits(self, query: &[u8], k: usize) -> Nearest<'t> {
|
|
564
|
+
self.nearest(QueryBuf::Bits(query.into()), k)
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
fn nearest(self, query: QueryBuf, k: usize) -> Nearest<'t> {
|
|
568
|
+
Nearest {
|
|
569
|
+
core: Cow::Borrowed(self.core),
|
|
570
|
+
input: NearestInput::Keys(Arc::new(self.keys)),
|
|
571
|
+
sel: self.sel,
|
|
572
|
+
query,
|
|
573
|
+
k,
|
|
574
|
+
parallelism: 1,
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
pub(crate) fn new(core: &'t Arc<TableCore>, keys: &KeySet) -> Self {
|
|
579
|
+
Self {
|
|
580
|
+
core,
|
|
581
|
+
keys: keys.clone(),
|
|
582
|
+
sel: Selection::new(),
|
|
583
|
+
after: None,
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/// Resume after `position`, where an earlier [`read_within`](KeysRead::read_within)
|
|
588
|
+
/// page stopped ([`KeysPage::resume`], D308): at the first key of this set at or after
|
|
589
|
+
/// the position's key (inside its row, after the column, when the page cut it), or
|
|
590
|
+
/// after it when the page ended on its row. It names a key, not an index, so a set
|
|
591
|
+
/// rebuilt between pages resumes at the right key. Only `read_within` takes a position:
|
|
592
|
+
/// [`read`](KeysRead::read) refuses one (`InvalidArgument`).
|
|
593
|
+
pub fn resume_after(mut self, position: &KeysPosition) -> Self {
|
|
594
|
+
self.after = Some(position.clone());
|
|
595
|
+
self
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/// Reads the longest prefix of the key set's cells, in key order, whose size is at most
|
|
599
|
+
/// `bytes` (D308), as owned rows: [`Scan::read_within`] for a multi-get. Keys with no
|
|
600
|
+
/// cell the selection keeps return nothing.
|
|
601
|
+
pub fn read_within(mut self, bytes: u64) -> Result<KeysPage> {
|
|
602
|
+
budget::keys(
|
|
603
|
+
self.core,
|
|
604
|
+
&mut self.sel,
|
|
605
|
+
&self.keys,
|
|
606
|
+
self.after.as_ref(),
|
|
607
|
+
bytes,
|
|
608
|
+
)
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
selection_methods!();
|
|
612
|
+
|
|
613
|
+
/// Up to `n` versions of each column (0: all retained).
|
|
614
|
+
pub fn versions(mut self, n: u32) -> Self {
|
|
615
|
+
self.sel.spec.versions = n;
|
|
616
|
+
self
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/// At most `n` columns per family in each row (a hub in a frontier stays a page).
|
|
620
|
+
pub fn column_limit(mut self, n: u32) -> Self {
|
|
621
|
+
self.sel.spec.columns_per_row = n;
|
|
622
|
+
self
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/// Starts the read.
|
|
626
|
+
pub fn read(mut self) -> Result<KeyRows<'t>> {
|
|
627
|
+
if self.after.is_some() {
|
|
628
|
+
return Err(crate::Error::new(
|
|
629
|
+
crate::ErrorCode::InvalidArgument,
|
|
630
|
+
"a multi-get position resumes read_within only",
|
|
631
|
+
));
|
|
632
|
+
}
|
|
633
|
+
let generation = self.core.db.generation();
|
|
634
|
+
let (info, snapshot, families) = self.sel.start(self.core)?;
|
|
635
|
+
let mut spec = self.sel.spec;
|
|
636
|
+
spec.families = families.into_vec();
|
|
637
|
+
let cursor = self
|
|
638
|
+
.core
|
|
639
|
+
.with(|e| e.multi_get(&snapshot, self.core.info.id, self.keys, spec))?;
|
|
640
|
+
Ok(KeyRows {
|
|
641
|
+
cursor,
|
|
642
|
+
buf: RowBuf::new(info, 0),
|
|
643
|
+
core: Cow::Borrowed(self.core),
|
|
644
|
+
generation,
|
|
645
|
+
done: false,
|
|
646
|
+
})
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/// The rows of a multi-get, in key order ([`KeysRead::read`]): each lent with its index in
|
|
651
|
+
/// the [`KeySet`] until the next call. One buffer is reused for every row.
|
|
652
|
+
///
|
|
653
|
+
/// With the `async` feature, [`KeyRows::next_async`] and [`KeyRows::poll_next`] read the
|
|
654
|
+
/// same rows without blocking on the device, and [`KeyRows::into_owned_stream`] makes a
|
|
655
|
+
/// [`Stream`](futures_core::Stream) of owned rows. Each key is positioned from the block
|
|
656
|
+
/// cache only; the blocks it lacks, and those the next few keys' reads start from, are
|
|
657
|
+
/// fetched asynchronously, in flight together.
|
|
658
|
+
#[derive(Debug)]
|
|
659
|
+
pub struct KeyRows<'t> {
|
|
660
|
+
cursor: KeyCursor,
|
|
661
|
+
buf: RowBuf,
|
|
662
|
+
/// The table: borrowed, or held by an owned stream. Its database's closed flag stops
|
|
663
|
+
/// the read (#826).
|
|
664
|
+
core: Cow<'t, Arc<TableCore>>,
|
|
665
|
+
generation: u64,
|
|
666
|
+
done: bool,
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
impl<'t> KeyRows<'t> {
|
|
670
|
+
/// The next row with a cell the selection keeps, and its key's index in the key set;
|
|
671
|
+
/// `None` after the last. After an error the read is finished.
|
|
672
|
+
#[allow(clippy::should_implement_trait)] // A lending step: an `Iterator` cannot lend.
|
|
673
|
+
pub fn next(&mut self) -> Result<Option<(usize, RowRef<'_>)>> {
|
|
674
|
+
if self.done {
|
|
675
|
+
return Ok(None);
|
|
676
|
+
}
|
|
677
|
+
let r = self
|
|
678
|
+
.core
|
|
679
|
+
.db
|
|
680
|
+
.check_generation(self.generation)
|
|
681
|
+
.and_then(|()| self.fill());
|
|
682
|
+
self.finish(r)
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/// The row a step read, lent; the read is finished at its end or an error.
|
|
686
|
+
fn finish(&mut self, r: Result<Option<usize>>) -> Result<Option<(usize, RowRef<'_>)>> {
|
|
687
|
+
match r {
|
|
688
|
+
Ok(Some(i)) => Ok(Some((i, RowRef::borrowed(&self.buf)))),
|
|
689
|
+
Ok(None) => {
|
|
690
|
+
self.done = true;
|
|
691
|
+
Ok(None)
|
|
692
|
+
}
|
|
693
|
+
Err(e) => {
|
|
694
|
+
self.done = true;
|
|
695
|
+
Err(e)
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
fn fill(&mut self) -> Result<Option<usize>> {
|
|
701
|
+
let Some(i) = self.cursor.next_key()? else {
|
|
702
|
+
return Ok(None);
|
|
703
|
+
};
|
|
704
|
+
fill_key(&mut self.cursor, &mut self.buf)?;
|
|
705
|
+
Ok(Some(i))
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/// [`KeyRows::next`] without blocking: `Pending` while a block the next row needs is
|
|
709
|
+
/// being fetched.
|
|
710
|
+
#[cfg(feature = "async")]
|
|
711
|
+
pub fn poll_next(
|
|
712
|
+
&mut self,
|
|
713
|
+
cx: &mut std::task::Context<'_>,
|
|
714
|
+
) -> std::task::Poll<Result<Option<(usize, RowRef<'_>)>>> {
|
|
715
|
+
match self.poll_fill(cx) {
|
|
716
|
+
std::task::Poll::Pending => std::task::Poll::Pending,
|
|
717
|
+
std::task::Poll::Ready(r) => std::task::Poll::Ready(self.finish(r)),
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/// [`KeyRows::next`] as a future that never blocks on the device
|
|
722
|
+
/// ([`KeyRows::poll_next`]).
|
|
723
|
+
///
|
|
724
|
+
/// ```
|
|
725
|
+
/// use pigeonhole::{Family, KeySet, Options, Pigeonhole};
|
|
726
|
+
///
|
|
727
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
728
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
729
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
730
|
+
/// let g = db.table("g")?.family("out", Family::default()).create_if_missing()?;
|
|
731
|
+
/// g.mutate(b"v:1").put("out", b"v:2", b"").commit()?;
|
|
732
|
+
///
|
|
733
|
+
/// let frontier = KeySet::from_unsorted([&b"v:1"[..], b"v:2"]);
|
|
734
|
+
/// let mut rows = g.keys(&frontier).read()?;
|
|
735
|
+
/// let mut seen = 0;
|
|
736
|
+
/// # pigeonhole::doc_support::block_on(async {
|
|
737
|
+
/// while let Some((i, row)) = rows.next_async().await? {
|
|
738
|
+
/// assert_eq!(frontier.get(i), b"v:1");
|
|
739
|
+
/// seen += row.iter().count();
|
|
740
|
+
/// }
|
|
741
|
+
/// # Ok::<(), pigeonhole::Error>(())
|
|
742
|
+
/// # })?;
|
|
743
|
+
/// assert_eq!(seen, 1);
|
|
744
|
+
/// # db.close()?;
|
|
745
|
+
/// # Ok(())
|
|
746
|
+
/// # }
|
|
747
|
+
/// ```
|
|
748
|
+
#[cfg(feature = "async")]
|
|
749
|
+
pub async fn next_async(&mut self) -> Result<Option<(usize, RowRef<'_>)>> {
|
|
750
|
+
let r = std::future::poll_fn(|cx| self.poll_fill(cx)).await;
|
|
751
|
+
self.finish(r)
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/// The rows as a [`Stream`](futures_core::Stream) of owned [`Row`]s with their keys'
|
|
755
|
+
/// indexes, holding the table ([`KeyRows::poll_next`] reads them).
|
|
756
|
+
#[cfg(feature = "async")]
|
|
757
|
+
pub fn into_owned_stream(self) -> crate::nonblocking::KeyStream {
|
|
758
|
+
crate::nonblocking::KeyStream::new(KeyRows {
|
|
759
|
+
cursor: self.cursor,
|
|
760
|
+
buf: self.buf,
|
|
761
|
+
core: Cow::Owned(self.core.into_owned()),
|
|
762
|
+
generation: self.generation,
|
|
763
|
+
done: self.done,
|
|
764
|
+
})
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/// Polls the next row into the buffer: its key's index, or `None` after the last.
|
|
768
|
+
#[cfg(feature = "async")]
|
|
769
|
+
fn poll_fill(
|
|
770
|
+
&mut self,
|
|
771
|
+
cx: &mut std::task::Context<'_>,
|
|
772
|
+
) -> std::task::Poll<Result<Option<usize>>> {
|
|
773
|
+
use std::task::Poll;
|
|
774
|
+
if self.done {
|
|
775
|
+
return Poll::Ready(Ok(None));
|
|
776
|
+
}
|
|
777
|
+
// As `next`: nothing is read after `close` (#826), nor after a recovery onto a newer
|
|
778
|
+
// engine (D265).
|
|
779
|
+
if let Err(e) = self.core.db.check_generation(self.generation) {
|
|
780
|
+
return Poll::Ready(Err(e));
|
|
781
|
+
}
|
|
782
|
+
Poll::Ready(match self.cursor.poll_next_key(cx) {
|
|
783
|
+
Poll::Pending => return Poll::Pending,
|
|
784
|
+
Poll::Ready(Ok(Some(i))) => {
|
|
785
|
+
let buf = &mut self.buf;
|
|
786
|
+
self.cursor.counted(|c| fill_key(c, buf)).map(|()| Some(i))
|
|
787
|
+
}
|
|
788
|
+
Poll::Ready(Ok(None)) => Ok(None),
|
|
789
|
+
Poll::Ready(Err(e)) => Err(e.into()),
|
|
790
|
+
})
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
/// The next row, owned, for [`KeyStream`](crate::nonblocking::KeyStream).
|
|
794
|
+
#[cfg(feature = "async")]
|
|
795
|
+
pub(crate) fn poll_owned(
|
|
796
|
+
&mut self,
|
|
797
|
+
cx: &mut std::task::Context<'_>,
|
|
798
|
+
) -> std::task::Poll<Option<Result<(usize, Row)>>> {
|
|
799
|
+
use std::task::Poll;
|
|
800
|
+
let r = match self.poll_fill(cx) {
|
|
801
|
+
Poll::Pending => return Poll::Pending,
|
|
802
|
+
Poll::Ready(r) => r,
|
|
803
|
+
};
|
|
804
|
+
Poll::Ready(match r {
|
|
805
|
+
Ok(Some(i)) => {
|
|
806
|
+
let next = self.buf.empty_like();
|
|
807
|
+
Some(Ok((i, Row::new(std::mem::replace(&mut self.buf, next)))))
|
|
808
|
+
}
|
|
809
|
+
Ok(None) => {
|
|
810
|
+
self.done = true;
|
|
811
|
+
None
|
|
812
|
+
}
|
|
813
|
+
Err(e) => {
|
|
814
|
+
self.done = true;
|
|
815
|
+
Some(Err(e))
|
|
816
|
+
}
|
|
817
|
+
})
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/// A breadth-first traversal under construction ([`Table::traverse`](crate::Table::traverse),
|
|
822
|
+
/// D304). Finish with [`Traverse::run`].
|
|
823
|
+
///
|
|
824
|
+
/// A node is a row; its edges are the columns of one family, and an edge's qualifier is the
|
|
825
|
+
/// destination's row key. From the seeds, each hop reads the frontier's edges in key order
|
|
826
|
+
/// (by source row, then qualifier, the newest version of each), with the selection applied
|
|
827
|
+
/// to the edges, and keeps every destination not visited before, once. One snapshot covers
|
|
828
|
+
/// every hop. The hops run in the engine: no row is materialised, duplicates and visited
|
|
829
|
+
/// nodes never leave it, and a capped hub costs its first `per_node_limit` edges, not the
|
|
830
|
+
/// row.
|
|
831
|
+
///
|
|
832
|
+
/// - [`per_node_limit(m)`](Traverse::per_node_limit): at most the first `m` edges of each
|
|
833
|
+
/// node, in qualifier order (edges to visited nodes count); the rest of the row is skipped
|
|
834
|
+
/// with a seek.
|
|
835
|
+
/// - [`hop_limit(n)`](Traverse::hop_limit): at most `n` new nodes per hop, the ones whose
|
|
836
|
+
/// first edge comes first in that order. Deterministic, not a sample.
|
|
837
|
+
/// - [`max_nodes(t)`](Traverse::max_nodes): at most `t` nodes visited in all, the seeds
|
|
838
|
+
/// included; 10,000,000 by default. The visited set is held in memory, about (key length
|
|
839
|
+
/// + 48) bytes per node.
|
|
840
|
+
///
|
|
841
|
+
/// ```
|
|
842
|
+
/// use pigeonhole::{Family, KeySet, Options, Pigeonhole};
|
|
843
|
+
///
|
|
844
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
845
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
846
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
847
|
+
/// let g = db.table("g")?.family("out", Family::default()).create_if_missing()?;
|
|
848
|
+
/// g.mutate(b"a").put("out", b"b", b"").put("out", b"c", b"").commit()?;
|
|
849
|
+
/// g.mutate(b"b").put("out", b"a", b"").put("out", b"d", b"").commit()?;
|
|
850
|
+
/// g.mutate(b"c").put("out", b"d", b"").commit()?;
|
|
851
|
+
///
|
|
852
|
+
/// let t = g.traverse(&KeySet::from_unsorted([b"a"])).family("out").hops(2).parents(true).run()?;
|
|
853
|
+
/// let hops = t.hops();
|
|
854
|
+
/// assert_eq!(hops[0].nodes().iter().collect::<Vec<_>>(), [&b"b"[..], b"c"]);
|
|
855
|
+
/// // `a` was visited, and `d` is reached from `b` first (b sorts before c).
|
|
856
|
+
/// assert_eq!(hops[1].nodes().iter().collect::<Vec<_>>(), [&b"d"[..]]);
|
|
857
|
+
/// assert_eq!(hops[1].parents(), Some(&[0][..]));
|
|
858
|
+
/// # db.close()?;
|
|
859
|
+
/// # Ok(())
|
|
860
|
+
/// # }
|
|
861
|
+
/// ```
|
|
862
|
+
#[derive(Debug)]
|
|
863
|
+
#[must_use = "a traversal does nothing until .run()"]
|
|
864
|
+
pub struct Traverse<'t> {
|
|
865
|
+
core: &'t TableCore,
|
|
866
|
+
seeds: KeySet,
|
|
867
|
+
sel: Selection,
|
|
868
|
+
hops: u32,
|
|
869
|
+
per_node_limit: u32,
|
|
870
|
+
hop_limit: u64,
|
|
871
|
+
max_nodes: u64,
|
|
872
|
+
parents: bool,
|
|
873
|
+
byte_budget: u64,
|
|
874
|
+
parallelism: usize,
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
impl<'t> Traverse<'t> {
|
|
878
|
+
pub(crate) fn new(core: &'t TableCore, seeds: &KeySet) -> Self {
|
|
879
|
+
Self {
|
|
880
|
+
core,
|
|
881
|
+
seeds: seeds.clone(),
|
|
882
|
+
sel: Selection::new(),
|
|
883
|
+
hops: 1,
|
|
884
|
+
per_node_limit: 0,
|
|
885
|
+
hop_limit: 0,
|
|
886
|
+
byte_budget: 0,
|
|
887
|
+
max_nodes: pigeonhole_engine::DEFAULT_MAX_NODES,
|
|
888
|
+
parents: false,
|
|
889
|
+
parallelism: 1,
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
selection_methods!();
|
|
894
|
+
|
|
895
|
+
/// Hops to take, 1 to 64 (default 1).
|
|
896
|
+
pub fn hops(mut self, n: u32) -> Self {
|
|
897
|
+
self.hops = n;
|
|
898
|
+
self
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/// At most `m` edges read from each node per hop, in qualifier order (0: all, the
|
|
902
|
+
/// default).
|
|
903
|
+
pub fn per_node_limit(mut self, m: u32) -> Self {
|
|
904
|
+
self.per_node_limit = m;
|
|
905
|
+
self
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/// At most `n` new nodes per hop (0: all, the default).
|
|
909
|
+
pub fn hop_limit(mut self, n: u64) -> Self {
|
|
910
|
+
self.hop_limit = n;
|
|
911
|
+
self
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/// At most `t` nodes visited in all, the seeds included (default 10,000,000;
|
|
915
|
+
/// `u64::MAX` for no limit).
|
|
916
|
+
pub fn max_nodes(mut self, t: u64) -> Self {
|
|
917
|
+
self.max_nodes = t;
|
|
918
|
+
self
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/// At most `bytes` of nodes in all, over the hops in order (D308): a node counts its key
|
|
922
|
+
/// and 16 bytes, plus 4 with [`parents`](Traverse::parents); the seeds aren't counted.
|
|
923
|
+
/// The hop the budget cuts keeps the in-budget prefix of its ranking (the nodes
|
|
924
|
+
/// [`hop_limit`](Traverse::hop_limit) would keep first), and the traversal ends with it
|
|
925
|
+
/// ([`TraverseStats::cut_by_budget`]). 0, the default, sets no budget.
|
|
926
|
+
pub fn byte_budget(mut self, bytes: u64) -> Self {
|
|
927
|
+
self.byte_budget = bytes;
|
|
928
|
+
self
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
/// Record, for each node, which node of the previous hop reached it ([`Hop::parents`]).
|
|
932
|
+
pub fn parents(mut self, on: bool) -> Self {
|
|
933
|
+
self.parents = on;
|
|
934
|
+
self
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
/// Read each hop on up to `n` threads owned by the call, when the frontier spans
|
|
938
|
+
/// several tablets and has at least 1,000 keys per thread (default 1).
|
|
939
|
+
pub fn parallel(mut self, n: usize) -> Self {
|
|
940
|
+
self.parallelism = n.max(1);
|
|
941
|
+
self
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
/// Runs the traversal. The edge family must be selected, and only it
|
|
945
|
+
/// (`InvalidArgument` otherwise); empty seeds give no hops.
|
|
946
|
+
pub fn run(mut self) -> Result<Traversal> {
|
|
947
|
+
let (snapshot, seeds, spec) = self.start()?;
|
|
948
|
+
let t = self
|
|
949
|
+
.core
|
|
950
|
+
.with(|e| e.traverse(&snapshot, self.core.info.id, seeds, &spec))?;
|
|
951
|
+
Ok(Traversal::from_engine(t, self.parents))
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/// [`Traverse::run`] as a future that never blocks on the device: each hop's keys are
|
|
955
|
+
/// positioned from the block cache, with the blocks they and the next keys need fetched
|
|
956
|
+
/// asynchronously, and a poll yields after 4,096 edges read, so a hub never holds the
|
|
957
|
+
/// executor's thread for long (edges the selection drops on the way are not counted) (cap hubs with [`per_node_limit`](Traverse::per_node_limit)
|
|
958
|
+
/// all the same: edges past a key's first block are read synchronously where the cache
|
|
959
|
+
/// misses). Hops run on the polling task, never fanned out; the result equals `run`'s.
|
|
960
|
+
///
|
|
961
|
+
/// ```
|
|
962
|
+
/// use pigeonhole::{Family, KeySet, Options, Pigeonhole};
|
|
963
|
+
///
|
|
964
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
965
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
966
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
967
|
+
/// let g = db.table("g")?.family("out", Family::default()).create_if_missing()?;
|
|
968
|
+
/// g.mutate(b"a").put("out", b"b", b"").commit()?;
|
|
969
|
+
/// g.mutate(b"b").put("out", b"c", b"").commit()?;
|
|
970
|
+
///
|
|
971
|
+
/// let seeds = KeySet::from_unsorted([b"a"]);
|
|
972
|
+
/// let t = pigeonhole::doc_support::block_on(g.traverse(&seeds).family("out").hops(2).run_async())?;
|
|
973
|
+
/// assert_eq!(t.hops().len(), 2);
|
|
974
|
+
/// # db.close()?;
|
|
975
|
+
/// # Ok(())
|
|
976
|
+
/// # }
|
|
977
|
+
/// ```
|
|
978
|
+
#[cfg(feature = "async")]
|
|
979
|
+
pub async fn run_async(mut self) -> Result<Traversal> {
|
|
980
|
+
let (snapshot, seeds, spec) = self.start()?;
|
|
981
|
+
let pending = self
|
|
982
|
+
.core
|
|
983
|
+
.with(|e| e.traverse_async(&snapshot, self.core.info.id, seeds, spec))?;
|
|
984
|
+
Ok(Traversal::from_engine(pending.await?, self.parents))
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
/// The snapshot, the seeds and the engine's spec.
|
|
988
|
+
fn start(
|
|
989
|
+
&mut self,
|
|
990
|
+
) -> Result<(
|
|
991
|
+
pigeonhole_engine::Snapshot,
|
|
992
|
+
Arc<KeySet>,
|
|
993
|
+
pigeonhole_engine::TraverseSpec,
|
|
994
|
+
)> {
|
|
995
|
+
if self.sel.ends.len() != 1 {
|
|
996
|
+
return Err(crate::Error::new(
|
|
997
|
+
crate::ErrorCode::InvalidArgument,
|
|
998
|
+
"a traversal reads exactly one edge family: select it with .family()",
|
|
999
|
+
));
|
|
1000
|
+
}
|
|
1001
|
+
let (_, snapshot, families) = self.sel.start(self.core)?;
|
|
1002
|
+
let seeds = Arc::new(std::mem::take(&mut self.seeds));
|
|
1003
|
+
let mut spec = pigeonhole_engine::TraverseSpec::new(families[0]);
|
|
1004
|
+
spec.hops = self.hops;
|
|
1005
|
+
spec.per_node_limit = self.per_node_limit;
|
|
1006
|
+
spec.hop_limit = self.hop_limit;
|
|
1007
|
+
spec.max_nodes = self.max_nodes;
|
|
1008
|
+
spec.byte_budget = self.byte_budget;
|
|
1009
|
+
spec.parents_in_budget = self.parents;
|
|
1010
|
+
spec.read = self.sel.spec.clone();
|
|
1011
|
+
spec.parallelism = self.parallelism;
|
|
1012
|
+
Ok((snapshot, seeds, spec))
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
impl Traversal {
|
|
1017
|
+
fn from_engine(t: pigeonhole_engine::Traversal, parents: bool) -> Self {
|
|
1018
|
+
Traversal {
|
|
1019
|
+
hops: t
|
|
1020
|
+
.hops
|
|
1021
|
+
.into_iter()
|
|
1022
|
+
.map(|h| Hop {
|
|
1023
|
+
nodes: h.nodes,
|
|
1024
|
+
parents: parents.then_some(h.parents),
|
|
1025
|
+
})
|
|
1026
|
+
.collect(),
|
|
1027
|
+
stats: TraverseStats {
|
|
1028
|
+
rows: t.stats.rows,
|
|
1029
|
+
edges: t.stats.edges,
|
|
1030
|
+
hops_cut: t.stats.hops_cut,
|
|
1031
|
+
cut_by_max_nodes: t.stats.cut_by_max_nodes,
|
|
1032
|
+
cut_by_budget: t.stats.cut_by_budget,
|
|
1033
|
+
},
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/// A traversal's result ([`Traverse::run`]): its hops, in order. There are fewer than asked
|
|
1039
|
+
/// when a frontier ran empty or `max_nodes` was reached.
|
|
1040
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
1041
|
+
#[non_exhaustive]
|
|
1042
|
+
pub struct Traversal {
|
|
1043
|
+
hops: Vec<Hop>,
|
|
1044
|
+
stats: TraverseStats,
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
impl Traversal {
|
|
1048
|
+
/// The hops: hop 1 first.
|
|
1049
|
+
pub fn hops(&self) -> &[Hop] {
|
|
1050
|
+
&self.hops
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/// Counts.
|
|
1054
|
+
pub fn stats(&self) -> TraverseStats {
|
|
1055
|
+
self.stats
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
/// One hop's new nodes ([`Traversal::hops`]).
|
|
1060
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
1061
|
+
#[non_exhaustive]
|
|
1062
|
+
pub struct Hop {
|
|
1063
|
+
nodes: KeySet,
|
|
1064
|
+
parents: Option<Vec<u32>>,
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
impl Hop {
|
|
1068
|
+
/// The nodes first reached at this hop, sorted: ready for the next read
|
|
1069
|
+
/// ([`Table::keys`](crate::Table::keys), say).
|
|
1070
|
+
pub fn nodes(&self) -> &KeySet {
|
|
1071
|
+
&self.nodes
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/// With [`Traverse::parents`]: for each node, the index in the previous hop's nodes (the
|
|
1075
|
+
/// seeds for the first hop) of the source of the first edge that reached it, enough to
|
|
1076
|
+
/// rebuild one shortest path per node.
|
|
1077
|
+
pub fn parents(&self) -> Option<&[u32]> {
|
|
1078
|
+
self.parents.as_deref()
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/// Counts of a traversal ([`Traversal::stats`]).
|
|
1083
|
+
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
|
1084
|
+
#[non_exhaustive]
|
|
1085
|
+
pub struct TraverseStats {
|
|
1086
|
+
/// Frontier rows with an edge the selection keeps.
|
|
1087
|
+
pub rows: u64,
|
|
1088
|
+
/// Edges read.
|
|
1089
|
+
pub edges: u64,
|
|
1090
|
+
/// Hops that `hop_limit` or `max_nodes` cut short.
|
|
1091
|
+
pub hops_cut: u32,
|
|
1092
|
+
/// Whether `max_nodes` was reached with hops left to take: a hop cut short by it, or the
|
|
1093
|
+
/// remaining hops skipped (they may have found nothing new).
|
|
1094
|
+
pub cut_by_max_nodes: bool,
|
|
1095
|
+
/// Whether [`byte_budget`](Traverse::byte_budget) cut a hop short (the traversal ended
|
|
1096
|
+
/// with it).
|
|
1097
|
+
pub cut_by_budget: bool,
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/// Reads the cells of the key `cursor` is on into `buf` (cleared first).
|
|
1101
|
+
fn fill_key(cursor: &mut KeyCursor, buf: &mut RowBuf) -> Result<()> {
|
|
1102
|
+
buf.clear();
|
|
1103
|
+
buf.key.extend_from_slice(cursor.row());
|
|
1104
|
+
while cursor.push_next_cell(buf)? {}
|
|
1105
|
+
Ok(())
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
/// A position within a row: the column (family and qualifier) a walk of the row handed out
|
|
1109
|
+
/// last ([`RowPages::position`], [`RowCells::position`]), from which a later read of a row of
|
|
1110
|
+
/// the same table resumes ([`RowRead::resume_after`], D297).
|
|
1111
|
+
///
|
|
1112
|
+
/// It names its table but not its row. [`RowPosition::to_bytes`] is a stable form (its first
|
|
1113
|
+
/// byte is the encoding version, 1) to keep a position across processes or hand it over an
|
|
1114
|
+
/// API boundary.
|
|
1115
|
+
///
|
|
1116
|
+
/// ```
|
|
1117
|
+
/// use pigeonhole::{Family, Options, Pigeonhole, RowPosition};
|
|
1118
|
+
///
|
|
1119
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
1120
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
1121
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
1122
|
+
/// let g = db.table("g")?.family("out", Family::default()).create_if_missing()?;
|
|
1123
|
+
/// let mut m = g.mutate(b"hub");
|
|
1124
|
+
/// for i in 0u32..10 {
|
|
1125
|
+
/// m = m.put("out", &i.to_be_bytes(), b"");
|
|
1126
|
+
/// }
|
|
1127
|
+
/// m.commit()?;
|
|
1128
|
+
///
|
|
1129
|
+
/// // The first page, then the rest in a later call.
|
|
1130
|
+
/// let mut pages = g.row(b"hub").family("out").pages(4)?;
|
|
1131
|
+
/// assert_eq!(pages.next()?.unwrap().len(), 4);
|
|
1132
|
+
/// let at = pages.position().unwrap();
|
|
1133
|
+
/// drop(pages);
|
|
1134
|
+
/// let token = at.to_bytes();
|
|
1135
|
+
///
|
|
1136
|
+
/// let at = RowPosition::from_bytes(&token)?;
|
|
1137
|
+
/// let rest = g.row(b"hub").family("out").resume_after(&at).read()?.unwrap();
|
|
1138
|
+
/// assert_eq!(rest.len(), 6);
|
|
1139
|
+
/// # db.close()?;
|
|
1140
|
+
/// # Ok(())
|
|
1141
|
+
/// # }
|
|
1142
|
+
/// ```
|
|
1143
|
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
|
1144
|
+
pub struct RowPosition(ColumnPosition);
|
|
1145
|
+
|
|
1146
|
+
impl RowPosition {
|
|
1147
|
+
/// The stable byte form: the encoding version (1), the table and family ids, the
|
|
1148
|
+
/// qualifier.
|
|
1149
|
+
pub fn to_bytes(&self) -> Vec<u8> {
|
|
1150
|
+
self.0.to_bytes()
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
/// Decodes [`RowPosition::to_bytes`]'s form; anything else fails with
|
|
1154
|
+
/// `InvalidArgument`.
|
|
1155
|
+
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
|
1156
|
+
Ok(Self(ColumnPosition::from_bytes(bytes)?))
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
/// The scans one walk of a row reads, in order, from one snapshot: one over every selected
|
|
1161
|
+
/// family, or for a resumed walk one over the position's family (past its column) and one
|
|
1162
|
+
/// over the families after it.
|
|
1163
|
+
fn row_walk(
|
|
1164
|
+
core: &TableCore,
|
|
1165
|
+
row: &[u8],
|
|
1166
|
+
mut sel: Selection,
|
|
1167
|
+
resume: Option<&ColumnPosition>,
|
|
1168
|
+
) -> Result<(Arc<TableInfo>, Vec<ScanCursor>)> {
|
|
1169
|
+
let (info, snapshot, families) = sel.start(core)?;
|
|
1170
|
+
let table = core.info.id;
|
|
1171
|
+
let scan = |families: Vec<FamilyId>, qualifiers: QualifierFilter| -> Result<ScanCursor> {
|
|
1172
|
+
let mut spec = ScanSpec::new(Bound::Included(row.to_vec()), Bound::Included(row.to_vec()));
|
|
1173
|
+
spec.read = sel.spec.clone();
|
|
1174
|
+
spec.read.families = families;
|
|
1175
|
+
spec.read.qualifiers = qualifiers;
|
|
1176
|
+
spec.limit = 1;
|
|
1177
|
+
core.with(|e| e.scan(&snapshot, table, spec))
|
|
1178
|
+
.map_err(crate::Error::from)
|
|
1179
|
+
};
|
|
1180
|
+
let Some(at) = resume else {
|
|
1181
|
+
return Ok((
|
|
1182
|
+
info,
|
|
1183
|
+
vec![scan(families.into_vec(), sel.spec.qualifiers.clone())?],
|
|
1184
|
+
));
|
|
1185
|
+
};
|
|
1186
|
+
if at.table() != table {
|
|
1187
|
+
return Err(crate::Error::from(
|
|
1188
|
+
pigeonhole_engine::Error::InvalidArgument(
|
|
1189
|
+
"the row position is from another table".to_owned(),
|
|
1190
|
+
),
|
|
1191
|
+
));
|
|
1192
|
+
}
|
|
1193
|
+
// The families in the order the walk reads them.
|
|
1194
|
+
let order: Vec<FamilyId> = if families.is_empty() {
|
|
1195
|
+
info.families.iter().map(|f| f.id).collect()
|
|
1196
|
+
} else {
|
|
1197
|
+
families.into_vec()
|
|
1198
|
+
};
|
|
1199
|
+
let mut cursors = Vec::with_capacity(2);
|
|
1200
|
+
let rest = match order.iter().position(|&f| f == at.family()) {
|
|
1201
|
+
Some(i) => {
|
|
1202
|
+
let past = past_column(&sel.spec.qualifiers, at.qualifier());
|
|
1203
|
+
cursors.push(scan(vec![at.family()], past)?);
|
|
1204
|
+
i + 1
|
|
1205
|
+
}
|
|
1206
|
+
// The walk's order is the selection's (or the table's), not the ids': a position
|
|
1207
|
+
// in a family this read does not select has no place in it (cli692's B1 on #1210).
|
|
1208
|
+
None => {
|
|
1209
|
+
return Err(crate::Error::from(
|
|
1210
|
+
pigeonhole_engine::Error::InvalidArgument(
|
|
1211
|
+
"the row position's family is not one this read selects".to_owned(),
|
|
1212
|
+
),
|
|
1213
|
+
));
|
|
1214
|
+
}
|
|
1215
|
+
};
|
|
1216
|
+
if rest < order.len() {
|
|
1217
|
+
cursors.push(scan(order[rest..].to_vec(), sel.spec.qualifiers.clone())?);
|
|
1218
|
+
}
|
|
1219
|
+
Ok((info, cursors))
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
/// `selection` with its lower bound raised past `qualifier`: whichever starts later.
|
|
1223
|
+
fn past_column(selection: &QualifierFilter, qualifier: &[u8]) -> QualifierFilter {
|
|
1224
|
+
let (lo, hi) = match selection {
|
|
1225
|
+
QualifierFilter::Range(lo, hi) => (lo.clone(), hi.clone()),
|
|
1226
|
+
QualifierFilter::Prefix(p) => (Bound::Included(p.clone()), prefix_end(p)),
|
|
1227
|
+
_ => (Bound::Unbounded, Bound::Unbounded),
|
|
1228
|
+
};
|
|
1229
|
+
let after = Bound::Excluded(qualifier.to_vec());
|
|
1230
|
+
let lo = match &lo {
|
|
1231
|
+
Bound::Included(b) if b.as_slice() > qualifier => lo,
|
|
1232
|
+
Bound::Excluded(b) if b.as_slice() >= qualifier => lo,
|
|
1233
|
+
_ => after,
|
|
1234
|
+
};
|
|
1235
|
+
QualifierFilter::Range(lo, hi)
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
/// The first qualifier past every one starting with `prefix` (unbounded when none is).
|
|
1239
|
+
fn prefix_end(prefix: &[u8]) -> Bound<Vec<u8>> {
|
|
1240
|
+
let mut end = prefix.to_vec();
|
|
1241
|
+
while let Some(last) = end.pop() {
|
|
1242
|
+
if last < u8::MAX {
|
|
1243
|
+
end.push(last + 1);
|
|
1244
|
+
return Bound::Excluded(end);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
Bound::Unbounded
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
/// The cell-by-cell walk behind [`RowCells`] and [`RowPages`]: the walk's scans in order,
|
|
1251
|
+
/// the current cell's family and qualifier, and its version in one reused cell.
|
|
1252
|
+
#[derive(Debug)]
|
|
1253
|
+
struct CellWalk<'t> {
|
|
1254
|
+
core: &'t TableCore,
|
|
1255
|
+
generation: u64,
|
|
1256
|
+
info: Arc<TableInfo>,
|
|
1257
|
+
/// Scans still to start, in reverse order (the next is the last).
|
|
1258
|
+
pending: Vec<ScanCursor>,
|
|
1259
|
+
/// The scan on the row, if one is.
|
|
1260
|
+
cursor: Option<ScanCursor>,
|
|
1261
|
+
qualifier: Vec<u8>,
|
|
1262
|
+
data: CellData,
|
|
1263
|
+
family: Option<FamilyId>,
|
|
1264
|
+
/// The index in `info` of `family` (cells come grouped by family).
|
|
1265
|
+
family_index: Option<(FamilyId, usize)>,
|
|
1266
|
+
done: bool,
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
impl<'t> CellWalk<'t> {
|
|
1270
|
+
fn new(
|
|
1271
|
+
core: &'t TableCore,
|
|
1272
|
+
row: &[u8],
|
|
1273
|
+
sel: Selection,
|
|
1274
|
+
resume: Option<&ColumnPosition>,
|
|
1275
|
+
) -> Result<Self> {
|
|
1276
|
+
let generation = core.db.generation();
|
|
1277
|
+
let (info, mut cursors) = row_walk(core, row, sel, resume)?;
|
|
1278
|
+
cursors.reverse();
|
|
1279
|
+
Ok(Self {
|
|
1280
|
+
core,
|
|
1281
|
+
generation,
|
|
1282
|
+
info,
|
|
1283
|
+
pending: cursors,
|
|
1284
|
+
cursor: None,
|
|
1285
|
+
qualifier: Vec::new(),
|
|
1286
|
+
data: CellData::EMPTY,
|
|
1287
|
+
family: None,
|
|
1288
|
+
family_index: None,
|
|
1289
|
+
done: false,
|
|
1290
|
+
})
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
/// Steps to the next cell: `false` at the end of the walk. After an error the walk is
|
|
1294
|
+
/// done.
|
|
1295
|
+
fn step(&mut self) -> Result<bool> {
|
|
1296
|
+
if self.done {
|
|
1297
|
+
return Ok(false);
|
|
1298
|
+
}
|
|
1299
|
+
let r = self
|
|
1300
|
+
.core
|
|
1301
|
+
.db
|
|
1302
|
+
.check_generation(self.generation)
|
|
1303
|
+
.and_then(|()| self.step_inner());
|
|
1304
|
+
if !matches!(r, Ok(true)) {
|
|
1305
|
+
self.done = true;
|
|
1306
|
+
}
|
|
1307
|
+
r
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
fn step_inner(&mut self) -> Result<bool> {
|
|
1311
|
+
loop {
|
|
1312
|
+
let Some(cursor) = self.cursor.as_mut() else {
|
|
1313
|
+
let Some(mut next) = self.pending.pop() else {
|
|
1314
|
+
return Ok(false);
|
|
1315
|
+
};
|
|
1316
|
+
if next.next_row()? {
|
|
1317
|
+
self.cursor = Some(next);
|
|
1318
|
+
}
|
|
1319
|
+
continue;
|
|
1320
|
+
};
|
|
1321
|
+
let Some(cell) = cursor.next_cell()? else {
|
|
1322
|
+
self.cursor = None;
|
|
1323
|
+
continue;
|
|
1324
|
+
};
|
|
1325
|
+
self.qualifier.clear();
|
|
1326
|
+
self.qualifier.extend_from_slice(cell.qualifier);
|
|
1327
|
+
self.family = Some(cell.family);
|
|
1328
|
+
// A small value is copied into the reused cell; a large one stays pinned.
|
|
1329
|
+
let small = cell.stored.len() <= CellData::INLINE_MAX;
|
|
1330
|
+
if small {
|
|
1331
|
+
self.data.set_inline(cell.ts, cell.stored);
|
|
1332
|
+
} else {
|
|
1333
|
+
self.data = cursor.current_data();
|
|
1334
|
+
}
|
|
1335
|
+
return Ok(true);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
/// [`CellWalk::step`] straight into `buf` (the cell's qualifier unescaped into its
|
|
1340
|
+
/// qualifiers, a small value copied, a large one pinned): `false` at the end of the walk.
|
|
1341
|
+
/// `qualifier`, `data` and `family` are not set.
|
|
1342
|
+
fn push_step(&mut self, buf: &mut RowBuf) -> Result<bool> {
|
|
1343
|
+
if self.done {
|
|
1344
|
+
return Ok(false);
|
|
1345
|
+
}
|
|
1346
|
+
let r = self
|
|
1347
|
+
.core
|
|
1348
|
+
.db
|
|
1349
|
+
.check_generation(self.generation)
|
|
1350
|
+
.and_then(|()| {
|
|
1351
|
+
loop {
|
|
1352
|
+
let Some(cursor) = self.cursor.as_mut() else {
|
|
1353
|
+
let Some(mut next) = self.pending.pop() else {
|
|
1354
|
+
return Ok(false);
|
|
1355
|
+
};
|
|
1356
|
+
if next.next_row()? {
|
|
1357
|
+
self.cursor = Some(next);
|
|
1358
|
+
}
|
|
1359
|
+
continue;
|
|
1360
|
+
};
|
|
1361
|
+
// `next_cell` and the sink's pushes, not `ScanCursor::push_next_cell`: a
|
|
1362
|
+
// third caller of that changed how it inlines into the scan's row fill
|
|
1363
|
+
// (+2-3% on the scan shapes, #1227's first callgrind run).
|
|
1364
|
+
let Some(cell) = cursor.next_cell()? else {
|
|
1365
|
+
self.cursor = None;
|
|
1366
|
+
continue;
|
|
1367
|
+
};
|
|
1368
|
+
let start = buf.qualifiers.len();
|
|
1369
|
+
buf.qualifiers.extend_from_slice(cell.qualifier);
|
|
1370
|
+
let qualifier = start..buf.qualifiers.len();
|
|
1371
|
+
if cell.stored.len() <= CellData::INLINE_MAX {
|
|
1372
|
+
pigeonhole_engine::RowSink::push_inline(
|
|
1373
|
+
buf,
|
|
1374
|
+
cell.family,
|
|
1375
|
+
qualifier,
|
|
1376
|
+
cell.ts,
|
|
1377
|
+
cell.stored,
|
|
1378
|
+
);
|
|
1379
|
+
} else {
|
|
1380
|
+
let family = cell.family;
|
|
1381
|
+
buf.push(family, qualifier, cursor.current_data());
|
|
1382
|
+
}
|
|
1383
|
+
return Ok(true);
|
|
1384
|
+
}
|
|
1385
|
+
});
|
|
1386
|
+
if !matches!(r, Ok(true)) {
|
|
1387
|
+
self.done = true;
|
|
1388
|
+
}
|
|
1389
|
+
r
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
/// The current cell's family name.
|
|
1393
|
+
fn family_name(&mut self) -> &str {
|
|
1394
|
+
let Some(id) = self.family else {
|
|
1395
|
+
return "";
|
|
1396
|
+
};
|
|
1397
|
+
let i = match self.family_index {
|
|
1398
|
+
Some((f, i)) if f == id => i,
|
|
1399
|
+
_ => {
|
|
1400
|
+
let i = self
|
|
1401
|
+
.info
|
|
1402
|
+
.families
|
|
1403
|
+
.iter()
|
|
1404
|
+
.position(|f| f.id == id)
|
|
1405
|
+
.unwrap_or(usize::MAX);
|
|
1406
|
+
self.family_index = Some((id, i));
|
|
1407
|
+
i
|
|
1408
|
+
}
|
|
1409
|
+
};
|
|
1410
|
+
self.info.families.get(i).map_or("", |f| f.name.as_str())
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
fn position(&self) -> Option<RowPosition> {
|
|
1414
|
+
self.family.map(|f| {
|
|
1415
|
+
RowPosition(ColumnPosition::new(
|
|
1416
|
+
self.core.info.id,
|
|
1417
|
+
f,
|
|
1418
|
+
self.qualifier.clone(),
|
|
1419
|
+
))
|
|
1420
|
+
})
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
/// The cells of one row, one at a time ([`RowRead::cells`], D297): for a row too wide to
|
|
1425
|
+
/// read whole, such as a graph hub with millions of edges. Each cell is lent until the next
|
|
1426
|
+
/// call, so the walk allocates nothing per cell, and a large value stays pinned rather than
|
|
1427
|
+
/// copied. Cells come in [`RowRead::read`]'s order: by family, then qualifier, then newest
|
|
1428
|
+
/// version first.
|
|
1429
|
+
///
|
|
1430
|
+
/// The walk holds its snapshot, and with it the files it reads, until it is dropped. After
|
|
1431
|
+
/// the database is closed, the next step fails with `Closed` (#826).
|
|
1432
|
+
///
|
|
1433
|
+
/// ```
|
|
1434
|
+
/// use pigeonhole::{Family, Options, Pigeonhole};
|
|
1435
|
+
///
|
|
1436
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
1437
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
1438
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
1439
|
+
/// let g = db.table("g")?.family("out", Family::default()).create_if_missing()?;
|
|
1440
|
+
/// let mut m = g.mutate(b"hub");
|
|
1441
|
+
/// for i in 0u64..1000 {
|
|
1442
|
+
/// m = m.put("out", &i.to_be_bytes(), b"");
|
|
1443
|
+
/// }
|
|
1444
|
+
/// m.commit()?;
|
|
1445
|
+
///
|
|
1446
|
+
/// let mut degree = 0;
|
|
1447
|
+
/// let mut cells = g.row(b"hub").family("out").cells()?;
|
|
1448
|
+
/// while let Some(e) = cells.next()? {
|
|
1449
|
+
/// assert_eq!(e.family, "out");
|
|
1450
|
+
/// degree += 1;
|
|
1451
|
+
/// }
|
|
1452
|
+
/// assert_eq!(degree, 1000);
|
|
1453
|
+
/// # db.close()?;
|
|
1454
|
+
/// # Ok(())
|
|
1455
|
+
/// # }
|
|
1456
|
+
/// ```
|
|
1457
|
+
#[derive(Debug)]
|
|
1458
|
+
#[must_use = "a cell walk reads nothing until .next()"]
|
|
1459
|
+
pub struct RowCells<'t> {
|
|
1460
|
+
walk: CellWalk<'t>,
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
impl RowCells<'_> {
|
|
1464
|
+
/// The next cell, lent until the next call; `None` at the end of the row. After an
|
|
1465
|
+
/// error the walk is finished.
|
|
1466
|
+
#[allow(clippy::should_implement_trait)] // A lending step: an `Iterator` cannot lend.
|
|
1467
|
+
pub fn next(&mut self) -> Result<Option<CellEntry<'_>>> {
|
|
1468
|
+
if !self.walk.step()? {
|
|
1469
|
+
return Ok(None);
|
|
1470
|
+
}
|
|
1471
|
+
let walk = &mut self.walk;
|
|
1472
|
+
let _ = walk.family_name();
|
|
1473
|
+
let family = walk
|
|
1474
|
+
.family_index
|
|
1475
|
+
.and_then(|(_, i)| walk.info.families.get(i))
|
|
1476
|
+
.map_or("", |f| f.name.as_str());
|
|
1477
|
+
Ok(Some(CellEntry {
|
|
1478
|
+
family,
|
|
1479
|
+
qualifier: &walk.qualifier,
|
|
1480
|
+
cell: CellRef::borrowed(&walk.data),
|
|
1481
|
+
}))
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
/// The column of the cell handed out last, to resume after
|
|
1485
|
+
/// ([`RowRead::resume_after`]). Resuming after it skips that column's remaining
|
|
1486
|
+
/// versions: [`RowRead::pages`] ends its pages on column boundaries for that reason.
|
|
1487
|
+
pub fn position(&self) -> Option<RowPosition> {
|
|
1488
|
+
self.walk.position()
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
/// Pages of one row's cells, of at most `n` cells each ([`RowRead::pages`], D297), from one
|
|
1493
|
+
/// walk under one snapshot. A page holds whole columns only, so all the versions of a column
|
|
1494
|
+
/// the selection keeps are on one page; a column whose versions alone exceed `n` is a page
|
|
1495
|
+
/// of its own. One buffer is reused for every page: past the first page a page
|
|
1496
|
+
/// allocates nothing.
|
|
1497
|
+
///
|
|
1498
|
+
/// ```
|
|
1499
|
+
/// use pigeonhole::{Family, Options, Pigeonhole};
|
|
1500
|
+
///
|
|
1501
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
1502
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
1503
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
1504
|
+
/// let g = db.table("g")?.family("out", Family::default()).create_if_missing()?;
|
|
1505
|
+
/// let mut m = g.mutate(b"hub");
|
|
1506
|
+
/// for i in 0u64..2500 {
|
|
1507
|
+
/// m = m.put("out", &i.to_be_bytes(), b"");
|
|
1508
|
+
/// }
|
|
1509
|
+
/// m.commit()?;
|
|
1510
|
+
///
|
|
1511
|
+
/// let mut sizes = Vec::new();
|
|
1512
|
+
/// let mut pages = g.row(b"hub").family("out").pages(1000)?;
|
|
1513
|
+
/// while let Some(page) = pages.next()? {
|
|
1514
|
+
/// sizes.push(page.len());
|
|
1515
|
+
/// }
|
|
1516
|
+
/// assert_eq!(sizes, [1000, 1000, 500]);
|
|
1517
|
+
/// # db.close()?;
|
|
1518
|
+
/// # Ok(())
|
|
1519
|
+
/// # }
|
|
1520
|
+
/// ```
|
|
1521
|
+
#[derive(Debug)]
|
|
1522
|
+
#[must_use = "a page walk reads nothing until .next()"]
|
|
1523
|
+
pub struct RowPages<'t> {
|
|
1524
|
+
walk: CellWalk<'t>,
|
|
1525
|
+
row: Vec<u8>,
|
|
1526
|
+
n: usize,
|
|
1527
|
+
buf: RowBuf,
|
|
1528
|
+
/// The versions of the column that starts the next page (its family as an index into
|
|
1529
|
+
/// the table's families) and its qualifier: a column that did not fit this one.
|
|
1530
|
+
carry: Vec<(usize, CellData)>,
|
|
1531
|
+
carry_qualifier: Vec<u8>,
|
|
1532
|
+
/// The last column on the pages handed out.
|
|
1533
|
+
last: Option<FamilyId>,
|
|
1534
|
+
last_qualifier: Vec<u8>,
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
impl RowPages<'_> {
|
|
1538
|
+
/// The next page, lent until the next call; `None` at the end of the row. After an
|
|
1539
|
+
/// error the walk is finished.
|
|
1540
|
+
#[allow(clippy::should_implement_trait)] // A lending step: an `Iterator` cannot lend.
|
|
1541
|
+
pub fn next(&mut self) -> Result<Option<RowRef<'_>>> {
|
|
1542
|
+
self.buf.clear();
|
|
1543
|
+
self.buf.key.extend_from_slice(&self.row);
|
|
1544
|
+
self.buf.push_column(&mut self.carry, &self.carry_qualifier);
|
|
1545
|
+
// Cells go straight into the page. A column boundary shows as a cell whose column
|
|
1546
|
+
// differs from the one before; the column it starts goes to the next page when this
|
|
1547
|
+
// one is full, and so does a column that grows past `n` on a page it did not start.
|
|
1548
|
+
let mut col_start = 0;
|
|
1549
|
+
loop {
|
|
1550
|
+
let before = self.buf.len();
|
|
1551
|
+
if !self.walk.push_step(&mut self.buf)? {
|
|
1552
|
+
break;
|
|
1553
|
+
}
|
|
1554
|
+
if before == 0 {
|
|
1555
|
+
continue;
|
|
1556
|
+
}
|
|
1557
|
+
if !self.buf.same_column(before - 1, before) {
|
|
1558
|
+
if before >= self.n {
|
|
1559
|
+
self.buf
|
|
1560
|
+
.split_off_column(before, &mut self.carry, &mut self.carry_qualifier);
|
|
1561
|
+
break;
|
|
1562
|
+
}
|
|
1563
|
+
col_start = before;
|
|
1564
|
+
} else if col_start > 0 && self.buf.len() > self.n {
|
|
1565
|
+
self.buf
|
|
1566
|
+
.split_off_column(col_start, &mut self.carry, &mut self.carry_qualifier);
|
|
1567
|
+
break;
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
if let Some((family, qualifier)) = self.buf.last_column() {
|
|
1571
|
+
self.last = Some(family);
|
|
1572
|
+
self.last_qualifier.clear();
|
|
1573
|
+
self.last_qualifier.extend_from_slice(qualifier);
|
|
1574
|
+
}
|
|
1575
|
+
Ok((self.buf.len() > 0).then(|| RowRef::borrowed(&self.buf)))
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
/// The last column on the pages handed out so far, to resume after in a later read
|
|
1579
|
+
/// ([`RowRead::resume_after`]).
|
|
1580
|
+
pub fn position(&self) -> Option<RowPosition> {
|
|
1581
|
+
self.last.map(|f| {
|
|
1582
|
+
RowPosition(ColumnPosition::new(
|
|
1583
|
+
self.walk.core.info.id,
|
|
1584
|
+
f,
|
|
1585
|
+
self.last_qualifier.clone(),
|
|
1586
|
+
))
|
|
1587
|
+
})
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
fn push_cell(buf: &mut RowBuf, family: FamilyId, qualifier: &[u8], data: CellData) {
|
|
1592
|
+
let start = buf.qualifiers.len();
|
|
1593
|
+
buf.qualifiers.extend_from_slice(qualifier);
|
|
1594
|
+
let end = buf.qualifiers.len();
|
|
1595
|
+
buf.push(family, start..end, data);
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
impl<'t> RowRead<'t> {
|
|
1599
|
+
/// The row's cells, one at a time ([`RowCells`], D297): for a row too wide to read
|
|
1600
|
+
/// whole. It reads like a scan of one row (the row cache is not consulted), with this
|
|
1601
|
+
/// read's selection, versions and column limit. The column limit counts columns per
|
|
1602
|
+
/// family, per call: a walk resumed in a later call counts afresh.
|
|
1603
|
+
pub fn cells(self) -> Result<RowCells<'t>> {
|
|
1604
|
+
let walk = CellWalk::new(self.core, &self.row, self.sel, self.resume.as_ref())?;
|
|
1605
|
+
Ok(RowCells { walk })
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
/// The row's cells in pages of at most `n` cells, each ending at a column boundary
|
|
1609
|
+
/// ([`RowPages`], D297). `n` of 0 is taken as 1. The column limit counts columns per
|
|
1610
|
+
/// family over the whole walk (not per page), and afresh in each resumed call.
|
|
1611
|
+
pub fn pages(self, n: usize) -> Result<RowPages<'t>> {
|
|
1612
|
+
let walk = CellWalk::new(self.core, &self.row, self.sel, self.resume.as_ref())?;
|
|
1613
|
+
let buf = RowBuf::new(Arc::clone(&walk.info), 0);
|
|
1614
|
+
Ok(RowPages {
|
|
1615
|
+
walk,
|
|
1616
|
+
row: self.row,
|
|
1617
|
+
n: n.max(1),
|
|
1618
|
+
buf,
|
|
1619
|
+
carry: Vec::new(),
|
|
1620
|
+
carry_qualifier: Vec::new(),
|
|
1621
|
+
last: None,
|
|
1622
|
+
last_qualifier: Vec::new(),
|
|
1623
|
+
})
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
/// [`RowRead::read`] after [`RowRead::resume_after`]: the walk's cells into one row.
|
|
1627
|
+
fn read_resumed(self) -> Result<Option<RowRef<'t>>> {
|
|
1628
|
+
let row = self.row.clone();
|
|
1629
|
+
let mut walk = CellWalk::new(self.core, &self.row, self.sel, self.resume.as_ref())?;
|
|
1630
|
+
let mut buf = RowBuf::new(Arc::clone(&walk.info), 0);
|
|
1631
|
+
while walk.step()? {
|
|
1632
|
+
let family = walk.family.expect("set by a step");
|
|
1633
|
+
let data = std::mem::replace(&mut walk.data, CellData::EMPTY);
|
|
1634
|
+
push_cell(&mut buf, family, &walk.qualifier, data);
|
|
1635
|
+
}
|
|
1636
|
+
if buf.len() == 0 {
|
|
1637
|
+
return Ok(None);
|
|
1638
|
+
}
|
|
1639
|
+
buf.key = row;
|
|
1640
|
+
Ok(Some(RowRef::owned(buf)))
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
/// An ordered scan under construction. Finish with [`Scan::iter`].
|
|
1645
|
+
///
|
|
1646
|
+
/// ```
|
|
1647
|
+
/// use std::ops::Bound;
|
|
1648
|
+
/// use pigeonhole::{Family, Options, Pigeonhole};
|
|
1649
|
+
///
|
|
1650
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
1651
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
1652
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
1653
|
+
/// let t = db.table("t")?.family("f", Family::default()).create_if_missing()?;
|
|
1654
|
+
/// for k in [&b"user:1"[..], b"user:2", b"user:3", b"vendor:1"] {
|
|
1655
|
+
/// t.mutate(k).put("f", b"q", b"v").commit()?;
|
|
1656
|
+
/// }
|
|
1657
|
+
///
|
|
1658
|
+
/// let mut it = t.scan_prefix(b"user:").limit(2).iter()?;
|
|
1659
|
+
/// let mut keys = Vec::new();
|
|
1660
|
+
/// while let Some(row) = it.next_ref()? {
|
|
1661
|
+
/// keys.push(row.key().to_vec());
|
|
1662
|
+
/// }
|
|
1663
|
+
/// assert_eq!(keys, [b"user:1".to_vec(), b"user:2".to_vec()]);
|
|
1664
|
+
///
|
|
1665
|
+
/// // Resume after the last key.
|
|
1666
|
+
/// let rest = t
|
|
1667
|
+
/// .scan_bounds(Bound::Excluded(b"user:2"), Bound::Excluded(b"user;"))
|
|
1668
|
+
/// .iter()?
|
|
1669
|
+
/// .count();
|
|
1670
|
+
/// assert_eq!(rest, 1);
|
|
1671
|
+
/// # db.close()?;
|
|
1672
|
+
/// # Ok(())
|
|
1673
|
+
/// # }
|
|
1674
|
+
/// ```
|
|
1675
|
+
#[derive(Debug)]
|
|
1676
|
+
#[must_use = "a scan does nothing until .iter()"]
|
|
1677
|
+
pub struct Scan<'t> {
|
|
1678
|
+
/// Borrowed from the table handle, or held ([`Scan::into_owned`]).
|
|
1679
|
+
core: Cow<'t, Arc<TableCore>>,
|
|
1680
|
+
start: Bound<Vec<u8>>,
|
|
1681
|
+
end: Bound<Vec<u8>>,
|
|
1682
|
+
sel: Selection,
|
|
1683
|
+
limit: Option<u64>,
|
|
1684
|
+
/// D308: where [`Scan::read_within`] resumes ([`Scan::resume_after`]).
|
|
1685
|
+
after: Option<ScanPosition>,
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
impl<'t> Scan<'t> {
|
|
1689
|
+
/// The `k` vectors nearest to the `f32` `query` in this read's one vector family (D296,
|
|
1690
|
+
/// D303), as a [`Nearest`] to run: exact, ranked by the family's metric, ties by row
|
|
1691
|
+
/// then qualifier. The read's selection applies (qualifiers, time range, value filter),
|
|
1692
|
+
/// with the newest version of each cell.
|
|
1693
|
+
pub fn nearest_f32(self, query: &[f32], k: usize) -> Nearest<'t> {
|
|
1694
|
+
self.nearest(QueryBuf::F32(query.into()), k)
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
/// [`nearest_f32`](Self::nearest_f32) for an `i8` vector family.
|
|
1698
|
+
pub fn nearest_i8(self, query: &[i8], k: usize) -> Nearest<'t> {
|
|
1699
|
+
self.nearest(QueryBuf::I8(query.into()), k)
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
/// [`nearest_f32`](Self::nearest_f32) for a bit vector family (`query` packed eight bits
|
|
1703
|
+
/// to a byte, least significant first).
|
|
1704
|
+
pub fn nearest_bits(self, query: &[u8], k: usize) -> Nearest<'t> {
|
|
1705
|
+
self.nearest(QueryBuf::Bits(query.into()), k)
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
fn nearest(self, query: QueryBuf, k: usize) -> Nearest<'t> {
|
|
1709
|
+
Nearest {
|
|
1710
|
+
core: self.core,
|
|
1711
|
+
input: NearestInput::Range(self.start, self.end),
|
|
1712
|
+
sel: self.sel,
|
|
1713
|
+
query,
|
|
1714
|
+
k,
|
|
1715
|
+
parallelism: 1,
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
pub(crate) fn new(
|
|
1720
|
+
core: &'t Arc<TableCore>,
|
|
1721
|
+
start: Bound<Vec<u8>>,
|
|
1722
|
+
end: Bound<Vec<u8>>,
|
|
1723
|
+
) -> Self {
|
|
1724
|
+
Self {
|
|
1725
|
+
core: Cow::Borrowed(core),
|
|
1726
|
+
start,
|
|
1727
|
+
end,
|
|
1728
|
+
sel: Selection::new(),
|
|
1729
|
+
limit: None,
|
|
1730
|
+
after: None,
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
selection_methods!();
|
|
1735
|
+
|
|
1736
|
+
/// Resume after `position`, where an earlier [`read_within`](Scan::read_within) page
|
|
1737
|
+
/// stopped ([`ScanPage::resume`], D308): the read starts at the later of the range's
|
|
1738
|
+
/// start and the position, so a position before the range starts at the range and one
|
|
1739
|
+
/// past its end reads nothing. Without an explicit [`snapshot`](Scan::snapshot), a
|
|
1740
|
+
/// chain of pages is not one consistent read. Only `read_within` takes a position:
|
|
1741
|
+
/// [`iter`](Scan::iter), [`cells`](Scan::cells) and `stream` refuse one
|
|
1742
|
+
/// (`InvalidArgument`), as they cannot resume inside a row.
|
|
1743
|
+
pub fn resume_after(mut self, position: &ScanPosition) -> Self {
|
|
1744
|
+
self.after = Some(position.clone());
|
|
1745
|
+
self
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
/// Reads the longest prefix of the scan's cells, in scan order, whose size is at most
|
|
1749
|
+
/// `bytes` (D308), as owned rows: each cell counts its qualifier, its value (as
|
|
1750
|
+
/// [`CellRef::value`] gives it) and 16 bytes, and each row its key once. A column (all
|
|
1751
|
+
/// the versions the read selects) is kept whole or not at all; a row may be cut between
|
|
1752
|
+
/// columns. If the first column doesn't fit, the page is empty and
|
|
1753
|
+
/// [`next_bytes`](ScanPage::next_bytes) says what it needs.
|
|
1754
|
+
///
|
|
1755
|
+
/// [`limit`](Scan::limit) applies too, inside the read: whichever of the budget and the
|
|
1756
|
+
/// limit comes first stops it, and nothing past that is read. [`ScanPage::resume`] is
|
|
1757
|
+
/// `Some` whenever it stopped early. The read runs in the
|
|
1758
|
+
/// engine's bounded-read path (D296): sequentially it reads about the budget and one
|
|
1759
|
+
/// column more.
|
|
1760
|
+
///
|
|
1761
|
+
/// ```
|
|
1762
|
+
/// use pigeonhole::{Family, Options, Pigeonhole};
|
|
1763
|
+
///
|
|
1764
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
1765
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
1766
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
1767
|
+
/// let t = db.table("docs")?.family("text", Family::default()).create_if_missing()?;
|
|
1768
|
+
/// for i in 0..100u32 {
|
|
1769
|
+
/// t.mutate(format!("doc:{i:03}").as_bytes()).put("text", b"body", &[b'x'; 200]).commit()?;
|
|
1770
|
+
/// }
|
|
1771
|
+
/// // A page of at most 2 KiB, then the next from where it stopped.
|
|
1772
|
+
/// let page = t.scan_prefix(b"doc:").read_within(2048)?;
|
|
1773
|
+
/// assert!(page.bytes() <= 2048 && page.cut_by_budget());
|
|
1774
|
+
/// let next = t
|
|
1775
|
+
/// .scan_prefix(b"doc:")
|
|
1776
|
+
/// .resume_after(page.resume().expect("more to read"))
|
|
1777
|
+
/// .read_within(2048)?;
|
|
1778
|
+
/// assert_eq!(next.rows()[0].key(), b"doc:009");
|
|
1779
|
+
/// # db.close()?;
|
|
1780
|
+
/// # Ok(())
|
|
1781
|
+
/// # }
|
|
1782
|
+
/// ```
|
|
1783
|
+
pub fn read_within(mut self, bytes: u64) -> Result<ScanPage> {
|
|
1784
|
+
let range = (self.start, self.end);
|
|
1785
|
+
budget::scan(
|
|
1786
|
+
&self.core,
|
|
1787
|
+
&mut self.sel,
|
|
1788
|
+
range,
|
|
1789
|
+
self.limit,
|
|
1790
|
+
self.after.as_ref(),
|
|
1791
|
+
bytes,
|
|
1792
|
+
)
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
/// `InvalidArgument` when a [`resume_after`](Scan::resume_after) position is set: only
|
|
1796
|
+
/// `read_within` takes one.
|
|
1797
|
+
fn refuse_position(&self) -> Result<()> {
|
|
1798
|
+
if self.after.is_some() {
|
|
1799
|
+
return Err(crate::Error::new(
|
|
1800
|
+
crate::ErrorCode::InvalidArgument,
|
|
1801
|
+
"a scan position resumes read_within only",
|
|
1802
|
+
));
|
|
1803
|
+
}
|
|
1804
|
+
Ok(())
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
/// Up to `n` versions of each column.
|
|
1808
|
+
pub fn versions(mut self, n: u32) -> Self {
|
|
1809
|
+
self.sel.spec.versions = n;
|
|
1810
|
+
self
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
/// At most `n` columns per family in each row; the rest of each row is skipped without
|
|
1814
|
+
/// decoding. The same limit as [`RowRead::column_limit`] (ICR 0086).
|
|
1815
|
+
pub fn column_limit(mut self, n: u32) -> Self {
|
|
1816
|
+
self.sel.spec.columns_per_row = n;
|
|
1817
|
+
self
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
/// Stop after `n` rows.
|
|
1821
|
+
pub fn limit(mut self, n: u64) -> Self {
|
|
1822
|
+
self.limit = Some(n);
|
|
1823
|
+
self
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
/// The scan, holding its table instead of borrowing it (ICR 0052): its [`RowIter`] is
|
|
1827
|
+
/// `Send + 'static`, so it can move to another thread or into a consumer that keeps it,
|
|
1828
|
+
/// such as an Arrow stream handed to DuckDB or Polars. It holds the table as a clone of
|
|
1829
|
+
/// the [`Table`](crate::Table) handle would, and keeps the database open as long.
|
|
1830
|
+
///
|
|
1831
|
+
/// ```
|
|
1832
|
+
/// use pigeonhole::{Family, Options, Pigeonhole};
|
|
1833
|
+
///
|
|
1834
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
1835
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
1836
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
1837
|
+
/// let t = db.table("t")?.family("f", Family::default()).create_if_missing()?;
|
|
1838
|
+
/// t.mutate(b"a").put("f", b"q", b"v").commit()?;
|
|
1839
|
+
///
|
|
1840
|
+
/// let it = t.scan_prefix(b"").into_owned().iter()?;
|
|
1841
|
+
/// drop(t);
|
|
1842
|
+
/// let rows = std::thread::spawn(move || it.count()).join().unwrap();
|
|
1843
|
+
/// assert_eq!(rows, 1);
|
|
1844
|
+
/// # db.close()?;
|
|
1845
|
+
/// # Ok(())
|
|
1846
|
+
/// # }
|
|
1847
|
+
/// ```
|
|
1848
|
+
pub fn into_owned(self) -> Scan<'static> {
|
|
1849
|
+
Scan {
|
|
1850
|
+
core: Cow::Owned(self.core.into_owned()),
|
|
1851
|
+
start: self.start,
|
|
1852
|
+
end: self.end,
|
|
1853
|
+
sel: self.sel,
|
|
1854
|
+
limit: self.limit,
|
|
1855
|
+
after: self.after,
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
/// Starts the scan.
|
|
1860
|
+
pub fn iter(mut self) -> Result<RowIter<'t>> {
|
|
1861
|
+
self.refuse_position()?;
|
|
1862
|
+
let generation = self.core.db.generation();
|
|
1863
|
+
let (info, snapshot, families) = self.sel.start(&self.core)?;
|
|
1864
|
+
let mut spec = ScanSpec::new(self.start, self.end);
|
|
1865
|
+
spec.read = self.sel.spec;
|
|
1866
|
+
spec.read.families = families.into_vec();
|
|
1867
|
+
// `ScanSpec::limit` uses 0 for "unlimited"; `limit(0)` asks for no rows.
|
|
1868
|
+
spec.limit = self.limit.unwrap_or(0);
|
|
1869
|
+
let cursor = self
|
|
1870
|
+
.core
|
|
1871
|
+
.with(|e| e.scan(&snapshot, self.core.info.id, spec))?;
|
|
1872
|
+
Ok(RowIter {
|
|
1873
|
+
cursor,
|
|
1874
|
+
buf: RowBuf::new(info, 0),
|
|
1875
|
+
done: self.limit == Some(0),
|
|
1876
|
+
table: self.core,
|
|
1877
|
+
generation,
|
|
1878
|
+
})
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
/// The scan's cells one at a time, row after row ([`ScanCells`], D297): a scan over rows
|
|
1882
|
+
/// that may be too wide to read whole. Each cell is lent until the next call.
|
|
1883
|
+
pub fn cells(mut self) -> Result<ScanCells<'t>> {
|
|
1884
|
+
self.refuse_position()?;
|
|
1885
|
+
let generation = self.core.db.generation();
|
|
1886
|
+
let (info, snapshot, families) = self.sel.start(&self.core)?;
|
|
1887
|
+
let mut spec = ScanSpec::new(self.start, self.end);
|
|
1888
|
+
spec.read = self.sel.spec;
|
|
1889
|
+
spec.read.families = families.into_vec();
|
|
1890
|
+
spec.limit = self.limit.unwrap_or(0);
|
|
1891
|
+
let cursor = self
|
|
1892
|
+
.core
|
|
1893
|
+
.with(|e| e.scan(&snapshot, self.core.info.id, spec))?;
|
|
1894
|
+
Ok(ScanCells {
|
|
1895
|
+
cursor,
|
|
1896
|
+
info,
|
|
1897
|
+
table: self.core,
|
|
1898
|
+
generation,
|
|
1899
|
+
in_row: false,
|
|
1900
|
+
done: self.limit == Some(0),
|
|
1901
|
+
qualifier: Vec::new(),
|
|
1902
|
+
data: CellData::EMPTY,
|
|
1903
|
+
family: None,
|
|
1904
|
+
})
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
/// The scan as a [`Stream`](futures_core::Stream) of owned [`Row`]s, in key order (see
|
|
1908
|
+
/// [`nonblocking`](crate::nonblocking)): each tablet is positioned without blocking, and
|
|
1909
|
+
/// the blocks each step will read are fetched asynchronously first, only as the stream
|
|
1910
|
+
/// is polled. A block a step reads that was not predicted is read synchronously and
|
|
1911
|
+
/// counted ([`EngineMetrics::async_sync_reads`](crate::EngineMetrics::async_sync_reads); D196,
|
|
1912
|
+
/// #398). An error setting the scan up is the stream's first item.
|
|
1913
|
+
#[cfg(feature = "async")]
|
|
1914
|
+
pub fn stream(mut self) -> crate::nonblocking::RowStream<'t> {
|
|
1915
|
+
let limit_zero = self.limit == Some(0);
|
|
1916
|
+
let generation = self.core.db.generation();
|
|
1917
|
+
let refused = self.refuse_position();
|
|
1918
|
+
let started = (|| {
|
|
1919
|
+
refused?;
|
|
1920
|
+
let (info, snapshot, families) = self.sel.start(&self.core)?;
|
|
1921
|
+
let mut spec = ScanSpec::new(self.start, self.end);
|
|
1922
|
+
spec.read = self.sel.spec;
|
|
1923
|
+
spec.read.families = families.into_vec();
|
|
1924
|
+
spec.limit = self.limit.unwrap_or(0);
|
|
1925
|
+
let cursor = self
|
|
1926
|
+
.core
|
|
1927
|
+
.with(|e| e.scan_async(&snapshot, self.core.info.id, spec))?;
|
|
1928
|
+
Ok((cursor, RowBuf::new(info, 0)))
|
|
1929
|
+
})();
|
|
1930
|
+
crate::nonblocking::RowStream::new(started, limit_zero, self.core, generation)
|
|
1931
|
+
}
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
/// A scan's cells one at a time, row after row ([`Scan::cells`], D297). Each cell and its
|
|
1935
|
+
/// row key are lent until the next call, so the walk allocates nothing per cell; a large
|
|
1936
|
+
/// value stays pinned rather than copied. Rows come in key order; within a row, cells come
|
|
1937
|
+
/// by family, then qualifier, then newest version first.
|
|
1938
|
+
///
|
|
1939
|
+
/// ```
|
|
1940
|
+
/// use pigeonhole::{Family, Options, Pigeonhole};
|
|
1941
|
+
///
|
|
1942
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
1943
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
1944
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default().shards(1))?;
|
|
1945
|
+
/// let g = db.table("g")?.family("out", Family::default()).create_if_missing()?;
|
|
1946
|
+
/// g.mutate(b"a").put("out", b"b", b"").put("out", b"c", b"").commit()?;
|
|
1947
|
+
/// g.mutate(b"b").put("out", b"c", b"").commit()?;
|
|
1948
|
+
///
|
|
1949
|
+
/// let mut edges = Vec::new();
|
|
1950
|
+
/// let mut cells = g.scan_prefix(b"").family("out").cells()?;
|
|
1951
|
+
/// while let Some((row, e)) = cells.next()? {
|
|
1952
|
+
/// edges.push((row.to_vec(), e.qualifier.to_vec()));
|
|
1953
|
+
/// }
|
|
1954
|
+
/// assert_eq!(edges.len(), 3);
|
|
1955
|
+
/// assert_eq!(edges[2], (b"b".to_vec(), b"c".to_vec()));
|
|
1956
|
+
/// # db.close()?;
|
|
1957
|
+
/// # Ok(())
|
|
1958
|
+
/// # }
|
|
1959
|
+
/// ```
|
|
1960
|
+
#[derive(Debug)]
|
|
1961
|
+
#[must_use = "a cell walk reads nothing until .next()"]
|
|
1962
|
+
pub struct ScanCells<'t> {
|
|
1963
|
+
cursor: ScanCursor,
|
|
1964
|
+
info: Arc<TableInfo>,
|
|
1965
|
+
table: Cow<'t, Arc<TableCore>>,
|
|
1966
|
+
generation: u64,
|
|
1967
|
+
in_row: bool,
|
|
1968
|
+
done: bool,
|
|
1969
|
+
qualifier: Vec<u8>,
|
|
1970
|
+
data: CellData,
|
|
1971
|
+
/// The current cell's family, and its index in `info`.
|
|
1972
|
+
family: Option<(FamilyId, usize)>,
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
impl ScanCells<'_> {
|
|
1976
|
+
/// The next cell and its row key, lent until the next call; `None` at the end of the
|
|
1977
|
+
/// scan. After an error the walk is finished.
|
|
1978
|
+
#[allow(clippy::should_implement_trait)] // A lending step: an `Iterator` cannot lend.
|
|
1979
|
+
pub fn next(&mut self) -> Result<Option<(&[u8], CellEntry<'_>)>> {
|
|
1980
|
+
if self.done {
|
|
1981
|
+
return Ok(None);
|
|
1982
|
+
}
|
|
1983
|
+
let r = self
|
|
1984
|
+
.table
|
|
1985
|
+
.db
|
|
1986
|
+
.check_generation(self.generation)
|
|
1987
|
+
.and_then(|()| self.step());
|
|
1988
|
+
if !matches!(r, Ok(true)) {
|
|
1989
|
+
self.done = true;
|
|
1990
|
+
}
|
|
1991
|
+
if !r? {
|
|
1992
|
+
return Ok(None);
|
|
1993
|
+
}
|
|
1994
|
+
let family = self
|
|
1995
|
+
.family
|
|
1996
|
+
.and_then(|(_, i)| self.info.families.get(i))
|
|
1997
|
+
.map_or("", |f| f.name.as_str());
|
|
1998
|
+
Ok(Some((
|
|
1999
|
+
self.cursor.row(),
|
|
2000
|
+
CellEntry {
|
|
2001
|
+
family,
|
|
2002
|
+
qualifier: &self.qualifier,
|
|
2003
|
+
cell: CellRef::borrowed(&self.data),
|
|
2004
|
+
},
|
|
2005
|
+
)))
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
fn step(&mut self) -> Result<bool> {
|
|
2009
|
+
loop {
|
|
2010
|
+
if !self.in_row {
|
|
2011
|
+
if !self.cursor.next_row()? {
|
|
2012
|
+
return Ok(false);
|
|
2013
|
+
}
|
|
2014
|
+
self.in_row = true;
|
|
2015
|
+
}
|
|
2016
|
+
let Some(cell) = self.cursor.next_cell()? else {
|
|
2017
|
+
self.in_row = false;
|
|
2018
|
+
continue;
|
|
2019
|
+
};
|
|
2020
|
+
self.qualifier.clear();
|
|
2021
|
+
self.qualifier.extend_from_slice(cell.qualifier);
|
|
2022
|
+
let id = cell.family;
|
|
2023
|
+
let small = cell.stored.len() <= CellData::INLINE_MAX;
|
|
2024
|
+
if small {
|
|
2025
|
+
self.data.set_inline(cell.ts, cell.stored);
|
|
2026
|
+
} else {
|
|
2027
|
+
self.data = self.cursor.current_data();
|
|
2028
|
+
}
|
|
2029
|
+
if self.family.is_none_or(|(f, _)| f != id) {
|
|
2030
|
+
let i = self
|
|
2031
|
+
.info
|
|
2032
|
+
.families
|
|
2033
|
+
.iter()
|
|
2034
|
+
.position(|f| f.id == id)
|
|
2035
|
+
.unwrap_or(usize::MAX);
|
|
2036
|
+
self.family = Some((id, i));
|
|
2037
|
+
}
|
|
2038
|
+
return Ok(true);
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
/// Reads the cells of the row `cursor` is on into `buf` (cleared first).
|
|
2044
|
+
#[cfg(feature = "async")]
|
|
2045
|
+
pub(crate) fn fill_row(cursor: &mut ScanCursor, buf: &mut RowBuf) -> Result<()> {
|
|
2046
|
+
buf.clear();
|
|
2047
|
+
buf.key.extend_from_slice(cursor.row());
|
|
2048
|
+
while cursor.push_next_cell(buf)? {}
|
|
2049
|
+
Ok(())
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
/// Rows of a scan, in key order. As an [`Iterator`] it yields owned [`Row`]s (cheap: values
|
|
2053
|
+
/// stay pinned, not copied); [`RowIter::next_ref`] lends zero-copy [`RowRef`]s instead.
|
|
2054
|
+
///
|
|
2055
|
+
/// Once the database is closed through any handle, the next step fails with `Closed` and
|
|
2056
|
+
/// the iterator is finished (#826), owned ones ([`Scan::into_owned`]) included.
|
|
2057
|
+
///
|
|
2058
|
+
/// See [`Scan`] for an example.
|
|
2059
|
+
#[derive(Debug)]
|
|
2060
|
+
pub struct RowIter<'t> {
|
|
2061
|
+
cursor: ScanCursor,
|
|
2062
|
+
buf: RowBuf,
|
|
2063
|
+
done: bool,
|
|
2064
|
+
/// The table: borrowed, or held by an owned scan. Its database's closed flag stops
|
|
2065
|
+
/// the iterator (#826).
|
|
2066
|
+
table: Cow<'t, Arc<TableCore>>,
|
|
2067
|
+
/// The engine generation the scan started in (D265): a step after the database
|
|
2068
|
+
/// recovered onto a newer engine fails with `SnapshotExpired`.
|
|
2069
|
+
generation: u64,
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
impl RowIter<'_> {
|
|
2073
|
+
/// Reads the next row into `buf`. Returns `false` at the end. After an error the
|
|
2074
|
+
/// iterator is finished.
|
|
2075
|
+
fn fill(&mut self) -> Result<bool> {
|
|
2076
|
+
if self.done {
|
|
2077
|
+
return Ok(false);
|
|
2078
|
+
}
|
|
2079
|
+
// After `close` the engine's files may already belong to a new writer, which can
|
|
2080
|
+
// reuse the pages this cursor would read next (#826): fail with `Closed`, as every
|
|
2081
|
+
// handle does; after a recovery onto a newer engine, `SnapshotExpired` (D265). One
|
|
2082
|
+
// check, one load: the closed flag lives in the generation word.
|
|
2083
|
+
let r = self
|
|
2084
|
+
.table
|
|
2085
|
+
.db
|
|
2086
|
+
.check_generation(self.generation)
|
|
2087
|
+
.and_then(|()| self.fill_inner());
|
|
2088
|
+
if !matches!(r, Ok(true)) {
|
|
2089
|
+
self.done = true;
|
|
2090
|
+
}
|
|
2091
|
+
r
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
fn fill_inner(&mut self) -> Result<bool> {
|
|
2095
|
+
self.buf.clear();
|
|
2096
|
+
if !self.cursor.next_row()? {
|
|
2097
|
+
return Ok(false);
|
|
2098
|
+
}
|
|
2099
|
+
self.buf.key.extend_from_slice(self.cursor.row());
|
|
2100
|
+
while self.cursor.push_next_cell(&mut self.buf)? {}
|
|
2101
|
+
Ok(true)
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
/// The next row, borrowed from the iterator until the next call.
|
|
2105
|
+
pub fn next_ref(&mut self) -> Result<Option<RowRef<'_>>> {
|
|
2106
|
+
Ok(if self.fill()? {
|
|
2107
|
+
Some(RowRef::borrowed(&self.buf))
|
|
2108
|
+
} else {
|
|
2109
|
+
None
|
|
2110
|
+
})
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
impl Iterator for RowIter<'_> {
|
|
2115
|
+
type Item = Result<Row>;
|
|
2116
|
+
|
|
2117
|
+
fn next(&mut self) -> Option<Self::Item> {
|
|
2118
|
+
match self.fill() {
|
|
2119
|
+
Ok(true) => {
|
|
2120
|
+
let next = self.buf.empty_like();
|
|
2121
|
+
Some(Ok(Row::new(std::mem::replace(&mut self.buf, next))))
|
|
2122
|
+
}
|
|
2123
|
+
Ok(false) => None,
|
|
2124
|
+
Err(e) => Some(Err(e)),
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
#[cfg(test)]
|
|
2130
|
+
mod tests {
|
|
2131
|
+
use std::sync::Arc;
|
|
2132
|
+
|
|
2133
|
+
use pigeonhole_engine::{FamilyOptions, ValueRef, WriteBatch};
|
|
2134
|
+
|
|
2135
|
+
use super::Selection;
|
|
2136
|
+
use crate::{Family, Options, Pigeonhole};
|
|
2137
|
+
|
|
2138
|
+
/// #392 review: a read as of now resolves its families from the catalog before the
|
|
2139
|
+
/// engine loads its view. A family added (and written) in between must not come back as
|
|
2140
|
+
/// a cell the catalog entry cannot name (family `""`): without a selection, the read
|
|
2141
|
+
/// names the entry's families.
|
|
2142
|
+
#[test]
|
|
2143
|
+
fn a_family_added_before_the_view_loads_is_not_read_unnamed() {
|
|
2144
|
+
let dir = crate::doc_support::temp_dir();
|
|
2145
|
+
let db = Pigeonhole::open(dir.join("t.phdb"), Options::default().shards(1)).unwrap();
|
|
2146
|
+
let t = db
|
|
2147
|
+
.table("t")
|
|
2148
|
+
.unwrap()
|
|
2149
|
+
.family("f", Family::default())
|
|
2150
|
+
.create_if_missing()
|
|
2151
|
+
.unwrap();
|
|
2152
|
+
t.mutate(b"r").put("f", b"q", b"v").commit().unwrap();
|
|
2153
|
+
let engine = t.core.engine().to_arc();
|
|
2154
|
+
let table = t.core.info.id;
|
|
2155
|
+
engine.on_next(
|
|
2156
|
+
pigeonhole_engine::HookSite::LatestViewLoad,
|
|
2157
|
+
Box::new({
|
|
2158
|
+
let engine = Arc::clone(&engine);
|
|
2159
|
+
move || {
|
|
2160
|
+
let info = engine
|
|
2161
|
+
.add_family(table, "x", FamilyOptions::default())
|
|
2162
|
+
.unwrap();
|
|
2163
|
+
let x = info.family("x").unwrap().id;
|
|
2164
|
+
let mut wb = WriteBatch::new();
|
|
2165
|
+
wb.put(table, x, b"r", b"q", None, ValueRef::Bytes(b"new"))
|
|
2166
|
+
.unwrap();
|
|
2167
|
+
engine.commit(wb, None).unwrap();
|
|
2168
|
+
}
|
|
2169
|
+
}),
|
|
2170
|
+
);
|
|
2171
|
+
let row = t.row(b"r").read().unwrap().unwrap();
|
|
2172
|
+
let families: Vec<&str> = row.iter().map(|e| e.family).collect();
|
|
2173
|
+
assert_eq!(
|
|
2174
|
+
families,
|
|
2175
|
+
["f"],
|
|
2176
|
+
"a cell of a family the read could not name"
|
|
2177
|
+
);
|
|
2178
|
+
// The next read's catalog has `x`.
|
|
2179
|
+
let row = t.row(b"r").read().unwrap().unwrap();
|
|
2180
|
+
let families: Vec<&str> = row.iter().map(|e| e.family).collect();
|
|
2181
|
+
assert_eq!(families, ["f", "x"]);
|
|
2182
|
+
db.close().unwrap();
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
#[test]
|
|
2186
|
+
fn family_names_come_back_in_order_inline_or_spilled() {
|
|
2187
|
+
let mut sel = Selection::new();
|
|
2188
|
+
assert_eq!(sel.family_names().count(), 0);
|
|
2189
|
+
sel.push_family("f");
|
|
2190
|
+
sel.push_family("");
|
|
2191
|
+
sel.push_family("été");
|
|
2192
|
+
assert_eq!(sel.family_names().collect::<Vec<_>>(), ["f", "", "été"]);
|
|
2193
|
+
assert!(!sel.names.spilled());
|
|
2194
|
+
// Past the inline bytes and the inline count: the same names, now on the heap.
|
|
2195
|
+
let long = "a-family-name-longer-than-the-inline-buffer";
|
|
2196
|
+
for _ in 0..5 {
|
|
2197
|
+
sel.push_family(long);
|
|
2198
|
+
}
|
|
2199
|
+
assert!(sel.names.spilled());
|
|
2200
|
+
let names: Vec<&str> = sel.family_names().collect();
|
|
2201
|
+
assert_eq!(names.len(), 8);
|
|
2202
|
+
assert_eq!(&names[..3], ["f", "", "été"]);
|
|
2203
|
+
assert!(names[3..].iter().all(|n| *n == long));
|
|
2204
|
+
// `families` replaces the selection.
|
|
2205
|
+
sel.names.clear();
|
|
2206
|
+
sel.ends.clear();
|
|
2207
|
+
sel.push_family("g");
|
|
2208
|
+
assert_eq!(sel.family_names().collect::<Vec<_>>(), ["g"]);
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
/// One vector of a nearest-neighbour search ([`Nearest::run`]): the cell's row, qualifier
|
|
2213
|
+
/// and timestamp, and its distance to the query under the family's metric (smaller is
|
|
2214
|
+
/// nearer; exact for `i8` and bit vectors).
|
|
2215
|
+
#[derive(Debug, Clone, PartialEq)]
|
|
2216
|
+
#[non_exhaustive]
|
|
2217
|
+
pub struct Neighbour {
|
|
2218
|
+
/// The row key.
|
|
2219
|
+
pub row: Vec<u8>,
|
|
2220
|
+
/// The qualifier.
|
|
2221
|
+
pub qualifier: Vec<u8>,
|
|
2222
|
+
/// The distance, as [`VectorSpec::distance_f32`](crate::VectorSpec::distance_f32) and
|
|
2223
|
+
/// the other forms give it.
|
|
2224
|
+
pub distance: f64,
|
|
2225
|
+
/// The version's timestamp.
|
|
2226
|
+
pub ts: u64,
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
/// What a nearest-neighbour search reads.
|
|
2230
|
+
#[derive(Debug)]
|
|
2231
|
+
enum NearestInput {
|
|
2232
|
+
Range(Bound<Vec<u8>>, Bound<Vec<u8>>),
|
|
2233
|
+
Keys(Arc<KeySet>),
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2236
|
+
/// An exact nearest-neighbour search under construction ([`Scan::nearest_f32`],
|
|
2237
|
+
/// [`KeysRead::nearest_f32`] and their `i8` and bit forms; D296 PR 4, D303). Finish with
|
|
2238
|
+
/// [`run`](Nearest::run).
|
|
2239
|
+
///
|
|
2240
|
+
/// It reads every selected cell of the one vector family the read names and keeps the `k`
|
|
2241
|
+
/// nearest, in the engine, without materialising rows. The order is total: distance, then
|
|
2242
|
+
/// row key, then qualifier, the same at any [`parallel`](Nearest::parallel). The query
|
|
2243
|
+
/// must have the family's element type and dimension, with finite components (at most
|
|
2244
|
+
/// 2^56 in magnitude) and, under cosine, a nonzero norm; otherwise `InvalidArgument`.
|
|
2245
|
+
///
|
|
2246
|
+
/// ```
|
|
2247
|
+
/// use pigeonhole::{Element, Family, KeySet, Metric, Options, Pigeonhole, VectorSpec};
|
|
2248
|
+
///
|
|
2249
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
2250
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
2251
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default())?;
|
|
2252
|
+
/// let spec = VectorSpec::new(2, Element::F32, Metric::L2)?;
|
|
2253
|
+
/// let t = db.table("docs")?.family("emb", Family::vector(spec)).create_if_missing()?;
|
|
2254
|
+
/// for (row, v) in [(b"a", [0.0, 0.0]), (b"b", [1.0, 0.0]), (b"c", [5.0, 5.0])] {
|
|
2255
|
+
/// t.mutate(row).put_vector_f32("emb", b"", &v).commit()?;
|
|
2256
|
+
/// }
|
|
2257
|
+
/// let near = t.scan_prefix(b"").family("emb").nearest_f32(&[0.9, 0.0], 2).run()?;
|
|
2258
|
+
/// let rows: Vec<&[u8]> = near.iter().map(|n| n.row.as_slice()).collect();
|
|
2259
|
+
/// assert_eq!(rows, [&b"b"[..], b"a"]);
|
|
2260
|
+
///
|
|
2261
|
+
/// // Over chosen rows: a key-set read.
|
|
2262
|
+
/// let some = KeySet::from_unsorted([b"a", b"c"]);
|
|
2263
|
+
/// let near = t.keys(&some).family("emb").nearest_f32(&[4.0, 4.0], 1).run()?;
|
|
2264
|
+
/// assert_eq!(near[0].row, b"c");
|
|
2265
|
+
/// # db.close()?;
|
|
2266
|
+
/// # Ok(())
|
|
2267
|
+
/// # }
|
|
2268
|
+
/// ```
|
|
2269
|
+
#[derive(Debug)]
|
|
2270
|
+
#[must_use = "a search does nothing until .run()"]
|
|
2271
|
+
pub struct Nearest<'t> {
|
|
2272
|
+
core: Cow<'t, Arc<TableCore>>,
|
|
2273
|
+
input: NearestInput,
|
|
2274
|
+
sel: Selection,
|
|
2275
|
+
query: QueryBuf,
|
|
2276
|
+
k: usize,
|
|
2277
|
+
parallelism: usize,
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
impl Nearest<'_> {
|
|
2281
|
+
/// Search on up to `n` threads owned by the call (default 1), over the input's tablets:
|
|
2282
|
+
/// a range fans out past the engine's work floor, and a key set (a few wide rows, as an
|
|
2283
|
+
/// IVF index's lists) whenever its keys span more than one tablet. The result is the
|
|
2284
|
+
/// same at any `n`.
|
|
2285
|
+
pub fn parallel(mut self, n: usize) -> Self {
|
|
2286
|
+
self.parallelism = n.max(1);
|
|
2287
|
+
self
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
/// Runs the search: at most `k` neighbours, nearest first. The read must name exactly
|
|
2291
|
+
/// one family, a vector family, and the query must fit it (`InvalidArgument`).
|
|
2292
|
+
pub fn run(mut self) -> Result<Vec<Neighbour>> {
|
|
2293
|
+
let Some(go) = self.start()? else {
|
|
2294
|
+
return Ok(Vec::new());
|
|
2295
|
+
};
|
|
2296
|
+
let core: &TableCore = &self.core;
|
|
2297
|
+
let (k, skips) = (self.k, Arc::new(KnnSkips::default()));
|
|
2298
|
+
let reduced = core.with(|e| {
|
|
2299
|
+
e.reduce(
|
|
2300
|
+
&go.snapshot,
|
|
2301
|
+
core.info.id,
|
|
2302
|
+
&go.spec,
|
|
2303
|
+
|| KnnVisitor::typed(go.prepared.clone(), Arc::clone(&skips)),
|
|
2304
|
+
|| TopK::new(k),
|
|
2305
|
+
)
|
|
2306
|
+
})?;
|
|
2307
|
+
Ok(neighbours(reduced.items))
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
/// [`run`](Nearest::run), cut to a byte budget (D308 PR 3, #1302): the nearest
|
|
2311
|
+
/// neighbours, in `run`'s order, while their sizes fit `bytes`. A neighbour counts its
|
|
2312
|
+
/// row key, its qualifier and 16 bytes (D308 §2).
|
|
2313
|
+
///
|
|
2314
|
+
/// The search ranks as `run` does and reads as much, then cuts the ranked list. A first
|
|
2315
|
+
/// neighbour larger than the budget, or a budget of 0, gives an empty page marked
|
|
2316
|
+
/// [`cut_by_budget`](NearestPage::cut_by_budget) with its
|
|
2317
|
+
/// [`next_bytes`](NearestPage::next_bytes). There's no resume position: a larger
|
|
2318
|
+
/// budget, or a larger `k`, returns more.
|
|
2319
|
+
///
|
|
2320
|
+
/// ```
|
|
2321
|
+
/// use pigeonhole::{Element, Family, Metric, Options, Pigeonhole, VectorSpec};
|
|
2322
|
+
///
|
|
2323
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
2324
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
2325
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default())?;
|
|
2326
|
+
/// let spec = VectorSpec::new(2, Element::F32, Metric::L2)?;
|
|
2327
|
+
/// let t = db.table("docs")?.family("emb", Family::vector(spec)).create_if_missing()?;
|
|
2328
|
+
/// for (row, v) in [(&b"a"[..], [0.0, 1.0]), (b"b", [0.0, 2.0]), (b"c", [0.0, 3.0])] {
|
|
2329
|
+
/// t.mutate(row).put_vector_f32("emb", b"", &v).commit()?;
|
|
2330
|
+
/// }
|
|
2331
|
+
/// // Each neighbour is its 1-byte row key, an empty qualifier and 16 bytes: 17.
|
|
2332
|
+
/// let page = t.scan_prefix(b"").family("emb").nearest_f32(&[0.0, 0.0], 3).run_within(40)?;
|
|
2333
|
+
/// assert_eq!(page.neighbours().len(), 2);
|
|
2334
|
+
/// assert_eq!((page.bytes(), page.cut_by_budget(), page.next_bytes()), (34, true, Some(17)));
|
|
2335
|
+
/// # db.close()?;
|
|
2336
|
+
/// # Ok(())
|
|
2337
|
+
/// # }
|
|
2338
|
+
/// ```
|
|
2339
|
+
pub fn run_within(self, bytes: u64) -> Result<NearestPage> {
|
|
2340
|
+
Ok(NearestPage::cut(self.run()?, bytes))
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
/// [`run_within`](Nearest::run_within) on [`run_async`](Nearest::run_async): the same
|
|
2344
|
+
/// page.
|
|
2345
|
+
#[cfg(feature = "async")]
|
|
2346
|
+
pub async fn run_within_async(self, bytes: u64) -> Result<NearestPage> {
|
|
2347
|
+
Ok(NearestPage::cut(self.run_async().await?, bytes))
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
/// [`Nearest::run`] as a future that never blocks on a block it can fetch: the input is
|
|
2351
|
+
/// read on the polling task (rows positioned from the block cache, with the blocks they
|
|
2352
|
+
/// and the next rows need fetched asynchronously), and a poll yields after 4,096 cells,
|
|
2353
|
+
/// so a wide row (an IVF list) never holds the executor's thread for long. A row's cells
|
|
2354
|
+
/// past its first block are read synchronously where the cache misses. It never fans out
|
|
2355
|
+
/// ([`parallel`](Nearest::parallel) is ignored); the result equals `run`'s.
|
|
2356
|
+
///
|
|
2357
|
+
/// ```
|
|
2358
|
+
/// use pigeonhole::{Element, Family, Metric, Options, Pigeonhole, VectorSpec};
|
|
2359
|
+
///
|
|
2360
|
+
/// # fn main() -> pigeonhole::Result<()> {
|
|
2361
|
+
/// # let dir = pigeonhole::doc_support::temp_dir();
|
|
2362
|
+
/// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default())?;
|
|
2363
|
+
/// let spec = VectorSpec::new(2, Element::F32, Metric::L2)?;
|
|
2364
|
+
/// let t = db.table("docs")?.family("emb", Family::vector(spec)).create_if_missing()?;
|
|
2365
|
+
/// t.mutate(b"a").put_vector_f32("emb", b"", &[0.0, 1.0]).commit()?;
|
|
2366
|
+
/// let search = t.scan_prefix(b"").family("emb").nearest_f32(&[0.0, 0.9], 1);
|
|
2367
|
+
/// let near = pigeonhole::doc_support::block_on(search.run_async())?;
|
|
2368
|
+
/// assert_eq!(near[0].row, b"a");
|
|
2369
|
+
/// # db.close()?;
|
|
2370
|
+
/// # Ok(())
|
|
2371
|
+
/// # }
|
|
2372
|
+
/// ```
|
|
2373
|
+
#[cfg(feature = "async")]
|
|
2374
|
+
pub async fn run_async(mut self) -> Result<Vec<Neighbour>> {
|
|
2375
|
+
let Some(go) = self.start()? else {
|
|
2376
|
+
return Ok(Vec::new());
|
|
2377
|
+
};
|
|
2378
|
+
let core: &TableCore = &self.core;
|
|
2379
|
+
let k = self.k;
|
|
2380
|
+
let pending =
|
|
2381
|
+
core.with(|e| e.nearest_async(&go.snapshot, core.info.id, &go.spec, go.prepared, k))?;
|
|
2382
|
+
Ok(neighbours(pending.await?))
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
/// The checks, the snapshot, the prepared query and the engine's spec; `None` for
|
|
2386
|
+
/// `k == 0` once the arguments are checked.
|
|
2387
|
+
fn start(&mut self) -> Result<Option<Started>> {
|
|
2388
|
+
let invalid = |m: String| crate::Error::new(crate::ErrorCode::InvalidArgument, m);
|
|
2389
|
+
if self.sel.ends.len() != 1 {
|
|
2390
|
+
return Err(invalid(
|
|
2391
|
+
"nearest reads exactly one vector family: select it with .family()".into(),
|
|
2392
|
+
));
|
|
2393
|
+
}
|
|
2394
|
+
let core: &TableCore = &self.core;
|
|
2395
|
+
let (info, snapshot, families) = self.sel.start(core)?;
|
|
2396
|
+
let family = families[0];
|
|
2397
|
+
let options = &info
|
|
2398
|
+
.families
|
|
2399
|
+
.iter()
|
|
2400
|
+
.find(|f| f.id == family)
|
|
2401
|
+
.ok_or_else(|| invalid("the family is not in the table".into()))?
|
|
2402
|
+
.options;
|
|
2403
|
+
let name = self
|
|
2404
|
+
.sel
|
|
2405
|
+
.family_names()
|
|
2406
|
+
.next()
|
|
2407
|
+
.unwrap_or_default()
|
|
2408
|
+
.to_owned();
|
|
2409
|
+
let params = (options.kind == pigeonhole_engine::FamilyKind::Vector)
|
|
2410
|
+
.then(|| pigeonhole_format::vector::Params::parse(&options.kind_params).ok())
|
|
2411
|
+
.flatten()
|
|
2412
|
+
.ok_or_else(|| invalid(format!("family {name:?} is not a vector family")))?;
|
|
2413
|
+
// Checked and prepared once (the query's norm too); every group's visitor shares it.
|
|
2414
|
+
let prepared = params
|
|
2415
|
+
.prepare(self.query.clone())
|
|
2416
|
+
.map_err(|e| invalid(format!("family {name:?}: the query: {e}")))?;
|
|
2417
|
+
if self.k == 0 {
|
|
2418
|
+
return Ok(None);
|
|
2419
|
+
}
|
|
2420
|
+
let keys = matches!(self.input, NearestInput::Keys(_));
|
|
2421
|
+
let input = match std::mem::replace(&mut self.input, NearestInput::Keys(Arc::default())) {
|
|
2422
|
+
NearestInput::Range(lo, hi) => ReadInput::Ranges(vec![(lo, hi)]),
|
|
2423
|
+
NearestInput::Keys(k) => ReadInput::Keys(k),
|
|
2424
|
+
};
|
|
2425
|
+
let mut spec = ReduceSpec::new(input);
|
|
2426
|
+
let mut read = self.sel.spec.clone();
|
|
2427
|
+
read.families = vec![family];
|
|
2428
|
+
read.versions = 1;
|
|
2429
|
+
spec.read = read;
|
|
2430
|
+
spec.parallelism = self.parallelism;
|
|
2431
|
+
if keys && self.parallelism > 1 {
|
|
2432
|
+
// A key set's floor counts keys; an IVF query reads a few wide rows (#490 D).
|
|
2433
|
+
spec.parallel_floor = 0;
|
|
2434
|
+
}
|
|
2435
|
+
Ok(Some(Started {
|
|
2436
|
+
snapshot,
|
|
2437
|
+
spec,
|
|
2438
|
+
prepared,
|
|
2439
|
+
}))
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
/// What [`Nearest::start`] hands a run.
|
|
2444
|
+
struct Started {
|
|
2445
|
+
snapshot: pigeonhole_engine::Snapshot,
|
|
2446
|
+
spec: ReduceSpec,
|
|
2447
|
+
prepared: pigeonhole_format::vector::Prepared,
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
/// A ranking's cells as neighbours.
|
|
2451
|
+
fn neighbours(
|
|
2452
|
+
items: Vec<(pigeonhole_engine::CellKey, pigeonhole_engine::Score)>,
|
|
2453
|
+
) -> Vec<Neighbour> {
|
|
2454
|
+
items
|
|
2455
|
+
.into_iter()
|
|
2456
|
+
.map(|(cell, score)| Neighbour {
|
|
2457
|
+
row: cell.row,
|
|
2458
|
+
qualifier: cell.qualifier,
|
|
2459
|
+
distance: score.0,
|
|
2460
|
+
ts: cell.ts,
|
|
2461
|
+
})
|
|
2462
|
+
.collect()
|
|
2463
|
+
}
|