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.
Files changed (1256) hide show
  1. checksums.yaml +7 -0
  2. data/Cargo.lock +899 -0
  3. data/Cargo.toml +45 -0
  4. data/LICENSE +21 -0
  5. data/README.md +22 -0
  6. data/extconf.rb +12 -0
  7. data/lib/pigeonhole/api.rb +615 -0
  8. data/lib/pigeonhole/index.rb +208 -0
  9. data/lib/pigeonhole/memory.rb +507 -0
  10. data/lib/pigeonhole/version.rb +6 -0
  11. data/lib/pigeonhole-db.rb +6 -0
  12. data/lib/pigeonhole.rb +47 -0
  13. data/sig/pigeonhole.rbs +1484 -0
  14. data/src/budget.rs +205 -0
  15. data/src/classes.rs +279 -0
  16. data/src/convert.rs +192 -0
  17. data/src/db.rs +685 -0
  18. data/src/error.rs +151 -0
  19. data/src/feed.rs +316 -0
  20. data/src/fork.rs +64 -0
  21. data/src/gvl.rs +112 -0
  22. data/src/index.rs +1157 -0
  23. data/src/lib.rs +534 -0
  24. data/src/memory.rs +2178 -0
  25. data/src/read.rs +312 -0
  26. data/src/table.rs +1161 -0
  27. data/src/vector.rs +262 -0
  28. data/src/walk.rs +406 -0
  29. data/vendor/bundle/ruby/3.4.0/bin/minitest +29 -0
  30. data/vendor/bundle/ruby/3.4.0/bin/rake +29 -0
  31. data/vendor/bundle/ruby/3.4.0/bin/rake-compiler +29 -0
  32. data/vendor/bundle/ruby/3.4.0/bin/rake-compiler-dock +29 -0
  33. data/vendor/bundle/ruby/3.4.0/bin/rb-sys-dock +29 -0
  34. data/vendor/bundle/ruby/3.4.0/bin/rbs +29 -0
  35. data/vendor/bundle/ruby/3.4.0/cache/drb-2.2.3.gem +0 -0
  36. data/vendor/bundle/ruby/3.4.0/cache/logger-1.7.0.gem +0 -0
  37. data/vendor/bundle/ruby/3.4.0/cache/minitest-6.0.6.gem +0 -0
  38. data/vendor/bundle/ruby/3.4.0/cache/prism-1.9.0.gem +0 -0
  39. data/vendor/bundle/ruby/3.4.0/cache/rake-13.4.2.gem +0 -0
  40. data/vendor/bundle/ruby/3.4.0/cache/rake-compiler-1.3.2.gem +0 -0
  41. data/vendor/bundle/ruby/3.4.0/cache/rake-compiler-dock-1.12.0.gem +0 -0
  42. data/vendor/bundle/ruby/3.4.0/cache/rb_sys-0.9.130.gem +0 -0
  43. data/vendor/bundle/ruby/3.4.0/cache/rbs-4.2.0.gem +0 -0
  44. data/vendor/bundle/ruby/3.4.0/cache/toml-rb-6.0.0.gem +0 -0
  45. data/vendor/bundle/ruby/3.4.0/cache/tsort-0.2.0.gem +0 -0
  46. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.9.0/gem.build_complete +0 -0
  47. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.9.0/gem_make.out +44 -0
  48. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.9.0/mkmf.log +74 -0
  49. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.9.0/prism/prism.so +0 -0
  50. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/rbs-4.2.0/gem.build_complete +0 -0
  51. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/rbs-4.2.0/gem_make.out +41 -0
  52. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/rbs-4.2.0/mkmf.log +102 -0
  53. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/rbs-4.2.0/rbs_extension.so +0 -0
  54. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/LICENSE.txt +22 -0
  55. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/drb.gemspec +42 -0
  56. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/acl.rb +239 -0
  57. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/drb.rb +1993 -0
  58. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/eq.rb +15 -0
  59. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extserv.rb +44 -0
  60. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extservm.rb +94 -0
  61. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/gw.rb +161 -0
  62. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/observer.rb +26 -0
  63. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/ssl.rb +354 -0
  64. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/timeridconv.rb +97 -0
  65. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/unix.rb +118 -0
  66. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/version.rb +3 -0
  67. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/weakidconv.rb +31 -0
  68. data/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb.rb +3 -0
  69. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL +22 -0
  70. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING +56 -0
  71. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md +104 -0
  72. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/errors.rb +9 -0
  73. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/formatter.rb +36 -0
  74. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/log_device.rb +265 -0
  75. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/period.rb +47 -0
  76. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/severity.rb +38 -0
  77. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/version.rb +5 -0
  78. data/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb +789 -0
  79. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/History.rdoc +1860 -0
  80. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/Manifest.txt +41 -0
  81. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/README.rdoc +763 -0
  82. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/Rakefile +89 -0
  83. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/bin/minitest +5 -0
  84. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/design_rationale.rb +54 -0
  85. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/hoe/minitest.rb +30 -0
  86. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/assertions.rb +821 -0
  87. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/autorun.rb +5 -0
  88. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/benchmark.rb +452 -0
  89. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/bisect.rb +304 -0
  90. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/complete.rb +56 -0
  91. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/compress.rb +94 -0
  92. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/error_on_warning.rb +11 -0
  93. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/expectations.rb +321 -0
  94. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/find_minimal_combination.rb +127 -0
  95. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/hell.rb +11 -0
  96. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/manual_plugins.rb +4 -0
  97. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/parallel.rb +72 -0
  98. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/path_expander.rb +432 -0
  99. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/pride.rb +4 -0
  100. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/pride_plugin.rb +135 -0
  101. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/server.rb +49 -0
  102. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/server_plugin.rb +88 -0
  103. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/spec.rb +324 -0
  104. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/sprint.rb +105 -0
  105. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/sprint_plugin.rb +39 -0
  106. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/test.rb +232 -0
  107. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest/test_task.rb +331 -0
  108. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/lib/minitest.rb +1232 -0
  109. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/metametameta.rb +150 -0
  110. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_bisect.rb +249 -0
  111. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_find_minimal_combination.rb +138 -0
  112. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_assertions.rb +1729 -0
  113. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_benchmark.rb +151 -0
  114. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_reporter.rb +437 -0
  115. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_spec.rb +1095 -0
  116. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_test.rb +1295 -0
  117. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_minitest_test_task.rb +57 -0
  118. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_path_expander.rb +229 -0
  119. data/vendor/bundle/ruby/3.4.0/gems/minitest-6.0.6/test/minitest/test_server.rb +146 -0
  120. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/BSDmakefile +58 -0
  121. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/CHANGELOG.md +786 -0
  122. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/CODE_OF_CONDUCT.md +76 -0
  123. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/CONTRIBUTING.md +58 -0
  124. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/LICENSE.md +7 -0
  125. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/Makefile +116 -0
  126. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/README.md +143 -0
  127. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/config.yml +4739 -0
  128. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/build_system.md +119 -0
  129. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/configuration.md +68 -0
  130. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/cruby_compilation.md +27 -0
  131. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/design.md +53 -0
  132. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/encoding.md +121 -0
  133. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/fuzzing.md +88 -0
  134. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/heredocs.md +36 -0
  135. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/javascript.md +118 -0
  136. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/local_variable_depth.md +229 -0
  137. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/mapping.md +117 -0
  138. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/parser_translation.md +24 -0
  139. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/parsing_rules.md +22 -0
  140. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/releasing.md +75 -0
  141. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/relocation.md +34 -0
  142. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/ripper_translation.md +63 -0
  143. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/ruby_api.md +45 -0
  144. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/ruby_parser_translation.md +19 -0
  145. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/serialization.md +233 -0
  146. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/docs/testing.md +55 -0
  147. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/Makefile +273 -0
  148. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/api_node.c +6945 -0
  149. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/api_pack.c +276 -0
  150. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/extconf.rb +127 -0
  151. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/extension.c +1427 -0
  152. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/ext/prism/extension.h +19 -0
  153. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/ast.h +8254 -0
  154. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/defines.h +260 -0
  155. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/diagnostic.h +458 -0
  156. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/encoding.h +283 -0
  157. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/node.h +129 -0
  158. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/options.h +488 -0
  159. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/pack.h +163 -0
  160. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/parser.h +936 -0
  161. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/prettyprint.h +34 -0
  162. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/regexp.h +43 -0
  163. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/static_literals.h +121 -0
  164. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_buffer.h +236 -0
  165. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_char.h +204 -0
  166. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_constant_pool.h +218 -0
  167. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_integer.h +130 -0
  168. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_list.h +103 -0
  169. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_memchr.h +29 -0
  170. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_newline_list.h +113 -0
  171. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_string.h +200 -0
  172. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_strncasecmp.h +32 -0
  173. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/util/pm_strpbrk.h +46 -0
  174. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism/version.h +29 -0
  175. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/include/prism.h +408 -0
  176. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/compiler.rb +801 -0
  177. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/desugar_compiler.rb +392 -0
  178. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/dispatcher.rb +2210 -0
  179. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/dot_visitor.rb +4767 -0
  180. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/dsl.rb +1003 -0
  181. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/ffi.rb +578 -0
  182. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/inspect_visitor.rb +2393 -0
  183. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/lex_compat.rb +911 -0
  184. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/mutation_compiler.rb +772 -0
  185. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/node.rb +19966 -0
  186. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/node_ext.rb +511 -0
  187. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/pack.rb +230 -0
  188. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/parse_result/comments.rb +188 -0
  189. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/parse_result/errors.rb +66 -0
  190. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/parse_result/newlines.rb +155 -0
  191. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/parse_result.rb +907 -0
  192. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/pattern.rb +269 -0
  193. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/append_as_bytes.rb +15 -0
  194. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/byteindex.rb +13 -0
  195. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/scan_byte.rb +14 -0
  196. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/unpack1.rb +14 -0
  197. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/polyfill/warn.rb +36 -0
  198. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/prism.so +0 -0
  199. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/reflection.rb +416 -0
  200. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/relocation.rb +505 -0
  201. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/serialize.rb +2400 -0
  202. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/string_query.rb +31 -0
  203. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser/builder.rb +62 -0
  204. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser/compiler.rb +2234 -0
  205. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser/lexer.rb +820 -0
  206. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser.rb +376 -0
  207. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser_current.rb +26 -0
  208. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/parser_versions.rb +36 -0
  209. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper/filter.rb +53 -0
  210. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper/lexer.rb +135 -0
  211. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper/sexp.rb +126 -0
  212. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper/shim.rb +5 -0
  213. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ripper.rb +3520 -0
  214. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation/ruby_parser.rb +1964 -0
  215. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/translation.rb +18 -0
  216. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism/visitor.rb +813 -0
  217. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/lib/prism.rb +98 -0
  218. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/prism.gemspec +172 -0
  219. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/compiler.rbi +12 -0
  220. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/dsl.rbi +524 -0
  221. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/inspect_visitor.rbi +12 -0
  222. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/node.rbi +8750 -0
  223. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/node_ext.rbi +107 -0
  224. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/parse_result.rbi +404 -0
  225. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/reflection.rbi +58 -0
  226. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/string_query.rbi +12 -0
  227. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/translation/parser.rbi +11 -0
  228. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/translation/parser_versions.rbi +23 -0
  229. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/translation/ripper.rbi +15 -0
  230. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism/visitor.rbi +473 -0
  231. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/rbi/prism.rbi +63 -0
  232. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/compiler.rbs +9 -0
  233. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/dispatcher.rbs +19 -0
  234. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/dot_visitor.rbs +6 -0
  235. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/dsl.rbs +351 -0
  236. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/inspect_visitor.rbs +22 -0
  237. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/lex_compat.rbs +10 -0
  238. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/mutation_compiler.rbs +159 -0
  239. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/node.rbs +4042 -0
  240. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/node_ext.rbs +149 -0
  241. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/pack.rbs +43 -0
  242. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/parse_result/comments.rbs +38 -0
  243. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/parse_result.rbs +197 -0
  244. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/pattern.rbs +13 -0
  245. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/reflection.rbs +50 -0
  246. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/relocation.rbs +185 -0
  247. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/serialize.rbs +8 -0
  248. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/string_query.rbs +11 -0
  249. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism/visitor.rbs +169 -0
  250. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/sig/prism.rbs +272 -0
  251. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/diagnostic.c +854 -0
  252. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/encoding.c +5340 -0
  253. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/node.c +8685 -0
  254. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/options.c +338 -0
  255. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/pack.c +509 -0
  256. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/prettyprint.c +8957 -0
  257. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/prism.c +22679 -0
  258. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/regexp.c +790 -0
  259. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/serialize.c +2274 -0
  260. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/static_literals.c +617 -0
  261. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/token_type.c +703 -0
  262. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_buffer.c +357 -0
  263. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_char.c +318 -0
  264. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_constant_pool.c +342 -0
  265. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_integer.c +670 -0
  266. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_list.c +49 -0
  267. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_memchr.c +35 -0
  268. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_newline_list.c +125 -0
  269. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_string.c +381 -0
  270. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_strncasecmp.c +36 -0
  271. data/vendor/bundle/ruby/3.4.0/gems/prism-1.9.0/src/util/pm_strpbrk.c +206 -0
  272. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/History.rdoc +2454 -0
  273. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/MIT-LICENSE +21 -0
  274. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/README.rdoc +155 -0
  275. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/command_line_usage.rdoc +171 -0
  276. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile1 +38 -0
  277. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/Rakefile2 +35 -0
  278. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/a.c +6 -0
  279. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/b.c +6 -0
  280. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/example/main.c +11 -0
  281. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/glossary.rdoc +42 -0
  282. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/jamis.rb +592 -0
  283. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/proto_rake.rdoc +127 -0
  284. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rake.1 +156 -0
  285. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rakefile.rdoc +635 -0
  286. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/doc/rational.rdoc +151 -0
  287. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/exe/rake +27 -0
  288. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/application.rb +847 -0
  289. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/backtrace.rb +25 -0
  290. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/clean.rb +78 -0
  291. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cloneable.rb +17 -0
  292. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/cpu_counter.rb +122 -0
  293. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/default_loader.rb +15 -0
  294. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/dsl_definition.rb +196 -0
  295. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/early_time.rb +22 -0
  296. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/core.rb +26 -0
  297. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/ext/string.rb +176 -0
  298. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_creation_task.rb +25 -0
  299. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_list.rb +435 -0
  300. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_task.rb +58 -0
  301. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils.rb +137 -0
  302. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/file_utils_ext.rb +135 -0
  303. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_chain.rb +57 -0
  304. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/invocation_exception_mixin.rb +17 -0
  305. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/late_time.rb +18 -0
  306. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/linked_list.rb +112 -0
  307. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/loaders/makefile.rb +54 -0
  308. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/multi_task.rb +14 -0
  309. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/name_space.rb +38 -0
  310. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/options.rb +31 -0
  311. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/packagetask.rb +222 -0
  312. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/phony.rb +16 -0
  313. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/private_reader.rb +21 -0
  314. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/promise.rb +100 -0
  315. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/pseudo_status.rb +30 -0
  316. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_module.rb +67 -0
  317. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rake_test_loader.rb +27 -0
  318. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/rule_recursion_overflow_error.rb +20 -0
  319. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/scope.rb +43 -0
  320. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task.rb +434 -0
  321. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_argument_error.rb +8 -0
  322. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_arguments.rb +113 -0
  323. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/task_manager.rb +333 -0
  324. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/tasklib.rb +12 -0
  325. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/testtask.rb +192 -0
  326. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_history_display.rb +49 -0
  327. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/thread_pool.rb +157 -0
  328. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/trace_output.rb +23 -0
  329. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/version.rb +10 -0
  330. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake/win32.rb +17 -0
  331. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/lib/rake.rb +69 -0
  332. data/vendor/bundle/ruby/3.4.0/gems/rake-13.4.2/rake.gemspec +102 -0
  333. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/Gemfile +8 -0
  334. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/History.md +708 -0
  335. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/LICENSE.txt +20 -0
  336. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/README.md +505 -0
  337. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/Rakefile +15 -0
  338. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/appveyor.yml +22 -0
  339. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/bin/rake-compiler +24 -0
  340. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/cucumber.yml +4 -0
  341. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/compile.feature +79 -0
  342. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/cross-compile.feature +23 -0
  343. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/cross-package-multi.feature +15 -0
  344. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/cross-package.feature +14 -0
  345. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/java-compile.feature +22 -0
  346. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/java-no-native-compile.feature +33 -0
  347. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/java-package.feature +24 -0
  348. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/package.feature +40 -0
  349. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/compilation.rb +70 -0
  350. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/cross_compilation.rb +27 -0
  351. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/execution.rb +52 -0
  352. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/folders.rb +32 -0
  353. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/gem.rb +46 -0
  354. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/step_definitions/java_compilation.rb +7 -0
  355. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/support/env.rb +10 -0
  356. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/support/file_template_helpers.rb +137 -0
  357. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/support/generator_helpers.rb +123 -0
  358. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/features/support/platform_extension_helpers.rb +27 -0
  359. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/baseextensiontask.rb +90 -0
  360. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/compiler_config.rb +38 -0
  361. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/extensioncompiler.rb +51 -0
  362. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/extensiontask.rb +621 -0
  363. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/lib/rake/javaextensiontask.rb +321 -0
  364. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/bin/cross-ruby.rake +189 -0
  365. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/bootstrap.rake +11 -0
  366. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/common.rake +10 -0
  367. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/cucumber.rake +23 -0
  368. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/gem.rake +15 -0
  369. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-1.3.2/tasks/rspec.rake +9 -0
  370. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/CHANGELOG.md +446 -0
  371. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/CONTRIBUTING.md +109 -0
  372. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/Dockerfile.jruby +79 -0
  373. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/Dockerfile.mri.erb +282 -0
  374. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/Gemfile +8 -0
  375. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/LICENSE.txt +22 -0
  376. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/README.md +447 -0
  377. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/Rakefile +246 -0
  378. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/bin/rake-compiler-dock +18 -0
  379. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/buildkitd.toml +2 -0
  380. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/gem_helper.rb +54 -0
  381. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/mk_i686.rb +18 -0
  382. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/mk_musl_cross.sh +37 -0
  383. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/mk_osxcross.sh +45 -0
  384. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/mk_pkg_config.sh +24 -0
  385. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/parallel_docker_build.rb +169 -0
  386. 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
  387. 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
  388. 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
  389. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/rcd-env.sh +6 -0
  390. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/runas +7 -0
  391. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/sigfw.c +45 -0
  392. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_codesign +17 -0
  393. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/strip_wrapper_vbox +30 -0
  394. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/build/sudoers +1 -0
  395. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/colors.rb +43 -0
  396. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/docker_check.rb +356 -0
  397. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/predefined_user_group.rb +5 -0
  398. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/starter.rb +206 -0
  399. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock/version.rb +4 -0
  400. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/lib/rake_compiler_dock.rb +151 -0
  401. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/Dockerfile +66 -0
  402. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/README.md +14 -0
  403. 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
  404. 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
  405. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/mingw64-ucrt/mingw-w64-enable-ucrt.patch +22 -0
  406. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/rake-compiler-dock.gemspec +34 -0
  407. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.alpine +17 -0
  408. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/env/Dockerfile.debian +24 -0
  409. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/fixtures/mig_test_rpc.defs +8 -0
  410. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Gemfile +11 -0
  411. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/Rakefile +97 -0
  412. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RcdTestExtService.java +19 -0
  413. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/java/RubyRcdTest.java +16 -0
  414. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/ext/mri/extconf.rb +111 -0
  415. 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
  416. 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
  417. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/lib/rcd_test.rb +6 -0
  418. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/rcd_test.gemspec +28 -0
  419. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/rcd_test/test/test_basic.rb +49 -0
  420. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_environment_variables.rb +108 -0
  421. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_mig.rb +18 -0
  422. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_parallel_docker_build.rb +95 -0
  423. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_rubygems_plugins.rb +12 -0
  424. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_starter.rb +158 -0
  425. data/vendor/bundle/ruby/3.4.0/gems/rake-compiler-dock-1.12.0/test/test_versions.rb +82 -0
  426. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/LICENSE-APACHE +190 -0
  427. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/LICENSE-MIT +21 -0
  428. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/README.md +42 -0
  429. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/certs/ianks.pem +21 -0
  430. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/exe/rb-sys-dock +495 -0
  431. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo/config.rb +72 -0
  432. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo/metadata.rb +158 -0
  433. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo.rb +9 -0
  434. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo_builder/link_flag_converter.rb +37 -0
  435. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/cargo_builder.rb +370 -0
  436. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/error.rb +43 -0
  437. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/extensiontask.rb +188 -0
  438. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/mkmf/config.rb +75 -0
  439. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/mkmf.rb +413 -0
  440. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/toolchain_info/data.rb +10 -0
  441. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/toolchain_info.rb +82 -0
  442. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/util/logger.rb +73 -0
  443. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys/version.rb +5 -0
  444. data/vendor/bundle/ruby/3.4.0/gems/rb_sys-0.9.130/lib/rb_sys.rb +8 -0
  445. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/BSDL +22 -0
  446. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/CHANGELOG.md +2463 -0
  447. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/COPYING +56 -0
  448. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/Dockerfile.jruby +53 -0
  449. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/README.md +240 -0
  450. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/Rakefile +1213 -0
  451. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/Steepfile +55 -0
  452. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/config.yml +920 -0
  453. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/array.rbs +4205 -0
  454. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/basic_object.rbs +376 -0
  455. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/binding.rbs +148 -0
  456. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/builtin.rbs +278 -0
  457. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/class.rbs +223 -0
  458. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/comparable.rbs +192 -0
  459. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/complex.rbs +812 -0
  460. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/constants.rbs +96 -0
  461. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/data.rbs +415 -0
  462. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/dir.rbs +993 -0
  463. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/encoding.rbs +1368 -0
  464. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/enumerable.rbs +2506 -0
  465. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/enumerator/arithmetic_sequence.rbs +70 -0
  466. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/enumerator/product.rbs +92 -0
  467. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/enumerator.rbs +705 -0
  468. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/env.rbs +6 -0
  469. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/errno.rbs +682 -0
  470. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/errors.rbs +789 -0
  471. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/exception.rbs +485 -0
  472. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/false_class.rbs +82 -0
  473. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/fiber.rbs +570 -0
  474. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/fiber_error.rbs +11 -0
  475. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/file.rbs +2045 -0
  476. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/file_constants.rbs +463 -0
  477. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/file_stat.rbs +534 -0
  478. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/file_test.rbs +331 -0
  479. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/float.rbs +1292 -0
  480. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/gc.rbs +788 -0
  481. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/global_variables.rbs +184 -0
  482. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/hash.rbs +2183 -0
  483. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/integer.rbs +1374 -0
  484. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/io/buffer.rbs +995 -0
  485. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/io/wait.rbs +48 -0
  486. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/io.rbs +3473 -0
  487. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/kernel.rbs +3172 -0
  488. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/marshal.rbs +207 -0
  489. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/match_data.rbs +637 -0
  490. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/math.rbs +770 -0
  491. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/method.rbs +422 -0
  492. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/module.rbs +1856 -0
  493. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/nil_class.rbs +210 -0
  494. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/numeric.rbs +832 -0
  495. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/object.rbs +108 -0
  496. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/object_space/weak_key_map.rbs +166 -0
  497. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/object_space.rbs +197 -0
  498. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/pathname.rbs +1312 -0
  499. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/proc.rbs +905 -0
  500. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/process.rbs +2316 -0
  501. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/ractor.rbs +914 -0
  502. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/random.rbs +255 -0
  503. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/range.rbs +1209 -0
  504. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rational.rbs +502 -0
  505. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rb_config.rbs +88 -0
  506. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/ops.rbs +154 -0
  507. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/unnamed/argf.rbs +1236 -0
  508. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/unnamed/env_class.rbs +1214 -0
  509. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/unnamed/main_class.rbs +123 -0
  510. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rbs/unnamed/random.rbs +186 -0
  511. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/refinement.rbs +59 -0
  512. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/regexp.rbs +1974 -0
  513. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/ruby.rbs +53 -0
  514. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/ruby_vm.rbs +809 -0
  515. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/basic_specification.rbs +6 -0
  516. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/config_file.rbs +38 -0
  517. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/dependency_installer.rbs +6 -0
  518. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/errors.rbs +112 -0
  519. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/installer.rbs +15 -0
  520. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/path_support.rbs +6 -0
  521. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/platform.rbs +7 -0
  522. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/request_set.rbs +49 -0
  523. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/requirement.rbs +138 -0
  524. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/rubygems.rbs +1108 -0
  525. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/source_list.rbs +15 -0
  526. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/specification.rbs +31 -0
  527. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/stream_ui.rbs +5 -0
  528. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/uninstaller.rbs +10 -0
  529. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/rubygems/version.rbs +133 -0
  530. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/set.rbs +751 -0
  531. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/signal.rbs +110 -0
  532. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/string.rbs +5532 -0
  533. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/struct.rbs +668 -0
  534. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/symbol.rbs +482 -0
  535. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/thread.rbs +1821 -0
  536. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/thread_group.rbs +79 -0
  537. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/time.rbs +1793 -0
  538. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/trace_point.rbs +483 -0
  539. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/true_class.rbs +98 -0
  540. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/unbound_method.rbs +337 -0
  541. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/core/warning.rbs +87 -0
  542. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/CONTRIBUTING.md +107 -0
  543. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/aliases.md +79 -0
  544. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/architecture.md +110 -0
  545. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/collection.md +192 -0
  546. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/config.md +171 -0
  547. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/data_and_struct.md +86 -0
  548. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/encoding.md +56 -0
  549. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/gem.md +56 -0
  550. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/inline.md +634 -0
  551. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/rbs_by_example.md +309 -0
  552. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/release.md +303 -0
  553. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/repo.md +125 -0
  554. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/rust.md +96 -0
  555. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/sigs.md +167 -0
  556. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/stdlib.md +155 -0
  557. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/syntax.md +952 -0
  558. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/tools.md +17 -0
  559. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/type_fingerprint.md +21 -0
  560. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/docs/wasm_serialization.md +80 -0
  561. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/exe/rbs +7 -0
  562. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/Makefile +273 -0
  563. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/ast_translation.c +1870 -0
  564. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/ast_translation.h +41 -0
  565. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/class_constants.c +189 -0
  566. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/class_constants.h +105 -0
  567. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/compat.h +10 -0
  568. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/extconf.rb +40 -0
  569. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/legacy_location.c +299 -0
  570. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/legacy_location.h +82 -0
  571. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/main.c +649 -0
  572. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/rbs_extension.h +16 -0
  573. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/rbs_string_bridging.c +9 -0
  574. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/ext/rbs_extension/rbs_string_bridging.h +24 -0
  575. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/goodcheck.yml +91 -0
  576. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/ast.h +1055 -0
  577. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/defines.h +104 -0
  578. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/lexer.h +208 -0
  579. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/location.h +40 -0
  580. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/parser.h +187 -0
  581. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/serialize.h +39 -0
  582. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/string.h +47 -0
  583. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_allocator.h +59 -0
  584. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_assert.h +20 -0
  585. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_buffer.h +83 -0
  586. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_constant_pool.h +155 -0
  587. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_encoding.h +282 -0
  588. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs/util/rbs_unescape.h +24 -0
  589. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/include/rbs.h +14 -0
  590. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ancestor_graph.rb +92 -0
  591. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate/annotations.rb +199 -0
  592. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate/formatter.rb +82 -0
  593. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate/rdoc_annotator.rb +398 -0
  594. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate/rdoc_source.rb +131 -0
  595. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/annotate.rb +8 -0
  596. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/annotation.rb +29 -0
  597. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/comment.rb +29 -0
  598. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/declarations.rb +472 -0
  599. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/directives.rb +49 -0
  600. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/members.rb +451 -0
  601. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/annotations.rb +451 -0
  602. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/comment_block.rb +247 -0
  603. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/declarations.rb +291 -0
  604. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/helpers/constant_helper.rb +28 -0
  605. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
  606. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/ruby/members.rb +762 -0
  607. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/type_param.rb +235 -0
  608. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/ast/visitor.rb +137 -0
  609. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/buffer.rb +189 -0
  610. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/builtin_names.rb +58 -0
  611. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/cli/colored_io.rb +48 -0
  612. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/cli/diff.rb +84 -0
  613. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/cli/validate.rb +294 -0
  614. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/cli.rb +1253 -0
  615. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/cleaner.rb +38 -0
  616. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/config/lockfile.rb +92 -0
  617. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/config/lockfile_generator.rb +269 -0
  618. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/config.rb +81 -0
  619. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/installer.rb +32 -0
  620. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/base.rb +14 -0
  621. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/git.rb +265 -0
  622. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/local.rb +81 -0
  623. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/rubygems.rb +48 -0
  624. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources/stdlib.rb +50 -0
  625. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection/sources.rb +38 -0
  626. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/collection.rb +16 -0
  627. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/constant.rb +28 -0
  628. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/definition.rb +415 -0
  629. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/definition_builder/ancestor_builder.rb +681 -0
  630. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/definition_builder/method_builder.rb +295 -0
  631. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/definition_builder.rb +1057 -0
  632. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/diff.rb +131 -0
  633. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment/class_entry.rb +81 -0
  634. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment/module_entry.rb +91 -0
  635. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment/use_map.rb +77 -0
  636. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment.rb +1028 -0
  637. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment_loader.rb +167 -0
  638. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/environment_walker.rb +155 -0
  639. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/errors.rb +634 -0
  640. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/factory.rb +18 -0
  641. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/file_finder.rb +28 -0
  642. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/inline_parser/comment_association.rb +117 -0
  643. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/inline_parser.rb +568 -0
  644. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/location_aux.rb +170 -0
  645. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/locator.rb +247 -0
  646. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/method_type.rb +145 -0
  647. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/namespace.rb +154 -0
  648. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/parser/lex_result.rb +15 -0
  649. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/parser/token.rb +23 -0
  650. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/parser_aux.rb +144 -0
  651. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/helpers.rb +164 -0
  652. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/node_usage.rb +99 -0
  653. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/rb.rb +816 -0
  654. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/rbi.rb +793 -0
  655. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/runtime/helpers.rb +59 -0
  656. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/runtime/reflection.rb +19 -0
  657. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/runtime/value_object_generator.rb +278 -0
  658. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/prototype/runtime.rb +680 -0
  659. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/repository.rb +127 -0
  660. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/resolver/constant_resolver.rb +219 -0
  661. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/resolver/type_name_resolver.rb +167 -0
  662. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/rewriter.rb +70 -0
  663. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/sorter.rb +198 -0
  664. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/source.rb +99 -0
  665. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/substitution.rb +83 -0
  666. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/subtractor.rb +204 -0
  667. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/errors.rb +80 -0
  668. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/guaranteed.rb +30 -0
  669. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/hook.rb +212 -0
  670. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/observer.rb +19 -0
  671. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/setup.rb +84 -0
  672. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/setup_helper.rb +50 -0
  673. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/tester.rb +167 -0
  674. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test/type_check.rb +457 -0
  675. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/test.rb +112 -0
  676. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/type_alias_dependency.rb +100 -0
  677. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/type_alias_regularity.rb +126 -0
  678. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/type_name.rb +122 -0
  679. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/types.rb +1646 -0
  680. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test/convertibles.rb +177 -0
  681. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test/spy.rb +138 -0
  682. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test/type_assertions.rb +383 -0
  683. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test/with_aliases.rb +145 -0
  684. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/unit_test.rb +6 -0
  685. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/validator.rb +186 -0
  686. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/variance_calculator.rb +189 -0
  687. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/vendorer.rb +71 -0
  688. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/version.rb +5 -0
  689. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/deserializer.rb +213 -0
  690. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/location.rb +61 -0
  691. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/parser.rb +174 -0
  692. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/runtime.rb +211 -0
  693. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/wasm/serialization_schema.rb +111 -0
  694. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs/writer.rb +424 -0
  695. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs.rb +117 -0
  696. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs_extension.so +0 -0
  697. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rbs_jars.rb +39 -0
  698. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rdoc/discover.rb +20 -0
  699. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/lib/rdoc_plugin/parser.rb +168 -0
  700. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/rbs.gemspec +77 -0
  701. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/annotation.json +14 -0
  702. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/comment.json +26 -0
  703. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/decls.json +326 -0
  704. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/function.json +98 -0
  705. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/location.json +56 -0
  706. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/members.json +266 -0
  707. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/methodType.json +50 -0
  708. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/typeParam.json +52 -0
  709. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/schema/types.json +317 -0
  710. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ancestor_builder.rbs +163 -0
  711. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ancestor_graph.rbs +60 -0
  712. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotate/annotations.rbs +102 -0
  713. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotate/formatter.rbs +24 -0
  714. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotate/rdoc_annotater.rbs +85 -0
  715. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotate/rdoc_source.rbs +32 -0
  716. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/annotation.rbs +27 -0
  717. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/annotations.rbs +470 -0
  718. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/comment_block.rbs +127 -0
  719. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/declarations.rbs +158 -0
  720. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
  721. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/helpers/location_helper.rbs +15 -0
  722. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/ast/ruby/members.rbs +198 -0
  723. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/buffer.rbs +108 -0
  724. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/builtin_names.rbs +44 -0
  725. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/cli/colored_io.rbs +15 -0
  726. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/cli/diff.rbs +15 -0
  727. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/cli/validate.rbs +47 -0
  728. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/cli.rbs +89 -0
  729. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/cleaner.rbs +13 -0
  730. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/config/lockfile.rbs +74 -0
  731. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/config/lockfile_generator.rbs +68 -0
  732. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/config.rbs +46 -0
  733. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/installer.rbs +17 -0
  734. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection/sources.rbs +214 -0
  735. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/collection.rbs +4 -0
  736. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/comment.rbs +26 -0
  737. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/constant.rbs +21 -0
  738. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/declarations.rbs +274 -0
  739. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/definition.rbs +232 -0
  740. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/definition_builder.rbs +181 -0
  741. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/diff.rbs +28 -0
  742. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/directives.rbs +77 -0
  743. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment/class_entry.rbs +56 -0
  744. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment/module_entry.rbs +65 -0
  745. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment.rbs +286 -0
  746. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment_loader.rbs +111 -0
  747. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/environment_walker.rbs +65 -0
  748. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/errors.rbs +408 -0
  749. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/factory.rbs +5 -0
  750. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/file_finder.rbs +28 -0
  751. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/inline_parser/comment_association.rbs +71 -0
  752. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/inline_parser.rbs +126 -0
  753. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/location.rbs +135 -0
  754. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/locator.rbs +56 -0
  755. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/manifest.yaml +5 -0
  756. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/members.rbs +258 -0
  757. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/method_builder.rbs +89 -0
  758. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/method_types.rbs +58 -0
  759. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/namespace.rbs +161 -0
  760. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/parser.rbs +164 -0
  761. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/helpers.rbs +29 -0
  762. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/node_usage.rbs +20 -0
  763. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/rb.rbs +96 -0
  764. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/rbi.rbs +104 -0
  765. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/prototype/runtime.rbs +182 -0
  766. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/rbs.rbs +21 -0
  767. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/rdoc/rbs.rbs +67 -0
  768. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/repository.rbs +85 -0
  769. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/resolver/constant_resolver.rbs +92 -0
  770. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/resolver/context.rbs +34 -0
  771. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/resolver/type_name_resolver.rbs +61 -0
  772. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/rewriter.rbs +45 -0
  773. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/shims/bundler.rbs +38 -0
  774. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/shims/enumerable.rbs +5 -0
  775. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/shims/rubygems.rbs +19 -0
  776. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/sorter.rbs +41 -0
  777. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/source.rbs +48 -0
  778. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/substitution.rbs +48 -0
  779. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/subtractor.rbs +37 -0
  780. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/test/errors.rbs +52 -0
  781. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/test/guranteed.rbs +9 -0
  782. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/test/type_check.rbs +19 -0
  783. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/test.rbs +82 -0
  784. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/type_alias_dependency.rbs +53 -0
  785. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/type_alias_regularity.rbs +98 -0
  786. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/type_param.rbs +115 -0
  787. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/typename.rbs +89 -0
  788. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/types.rbs +588 -0
  789. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/unit_test/convertibles.rbs +154 -0
  790. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/unit_test/spy.rbs +22 -0
  791. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/unit_test/type_assertions.rbs +211 -0
  792. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/unit_test/with_aliases.rbs +136 -0
  793. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/use_map.rbs +35 -0
  794. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/util.rbs +9 -0
  795. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/validator.rbs +63 -0
  796. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/variance_calculator.rbs +87 -0
  797. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/vendorer.rbs +51 -0
  798. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/version.rbs +3 -0
  799. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/visitor.rbs +47 -0
  800. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/wasm/deserializer.rbs +66 -0
  801. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/wasm/serialization_schema.rbs +13 -0
  802. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/sig/writer.rbs +127 -0
  803. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/ast.c +1644 -0
  804. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/lexer.c +3223 -0
  805. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/lexer.re +187 -0
  806. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/lexstate.c +222 -0
  807. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/location.c +31 -0
  808. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/parser.c +4318 -0
  809. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/serialize.c +965 -0
  810. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/string.c +41 -0
  811. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_allocator.c +171 -0
  812. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_assert.c +19 -0
  813. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_buffer.c +54 -0
  814. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_constant_pool.c +268 -0
  815. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_encoding.c +21454 -0
  816. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/src/util/rbs_unescape.c +167 -0
  817. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/abbrev/0/abbrev.rbs +66 -0
  818. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/abbrev/0/array.rbs +26 -0
  819. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/base64/0/base64.rbs +355 -0
  820. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/benchmark/0/benchmark.rbs +452 -0
  821. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/bigdecimal/0/big_decimal.rbs +1647 -0
  822. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/bigdecimal-math/0/big_math.rbs +280 -0
  823. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
  824. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/cgi/0/core.rbs +911 -0
  825. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/cgi/0/manifest.yaml +4 -0
  826. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/cgi-escape/0/escape.rbs +171 -0
  827. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/coverage/0/coverage.rbs +266 -0
  828. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/csv/0/csv.rbs +3776 -0
  829. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/csv/0/manifest.yaml +3 -0
  830. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/date/0/date.rbs +1598 -0
  831. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/date/0/date_time.rbs +617 -0
  832. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/date/0/time.rbs +26 -0
  833. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/dbm/0/dbm.rbs +421 -0
  834. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/delegate/0/delegator.rbs +188 -0
  835. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/delegate/0/kernel.rbs +47 -0
  836. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/delegate/0/simple_delegator.rbs +96 -0
  837. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/did_you_mean/0/did_you_mean.rbs +344 -0
  838. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/digest/0/digest.rbs +693 -0
  839. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/erb/0/erb.rbs +933 -0
  840. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/etc/0/etc.rbs +884 -0
  841. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/fileutils/0/fileutils.rbs +1753 -0
  842. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/find/0/find.rbs +49 -0
  843. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/forwardable/0/forwardable.rbs +271 -0
  844. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/io-console/0/io-console.rbs +414 -0
  845. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/ipaddr/0/ipaddr.rbs +431 -0
  846. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/json/0/json.rbs +1963 -0
  847. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/kconv/0/kconv.rbs +166 -0
  848. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/formatter.rbs +45 -0
  849. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/log_device.rbs +100 -0
  850. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/logger.rbs +796 -0
  851. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/manifest.yaml +2 -0
  852. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/period.rbs +17 -0
  853. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/logger/0/severity.rbs +34 -0
  854. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/kernel.rbs +42 -0
  855. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/abstract_reporter.rbs +52 -0
  856. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/assertion.rbs +17 -0
  857. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/assertions.rbs +590 -0
  858. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/backtrace_filter.rbs +23 -0
  859. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/bench_spec.rbs +102 -0
  860. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/benchmark.rbs +259 -0
  861. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/composite_reporter.rbs +25 -0
  862. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/compress.rbs +13 -0
  863. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/error_on_warning.rbs +3 -0
  864. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/expectation.rbs +2 -0
  865. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/expectations.rbs +21 -0
  866. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/guard.rbs +64 -0
  867. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/mock.rbs +64 -0
  868. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/parallel/executor.rbs +46 -0
  869. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/parallel/test/class_methods.rbs +5 -0
  870. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/parallel/test.rbs +3 -0
  871. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/parallel.rbs +2 -0
  872. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/pride_io.rbs +62 -0
  873. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/pride_lol.rbs +19 -0
  874. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/progress_reporter.rbs +11 -0
  875. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/reportable.rbs +53 -0
  876. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/reporter.rbs +5 -0
  877. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/result.rbs +28 -0
  878. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/runnable.rbs +163 -0
  879. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/skip.rbs +6 -0
  880. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/spec/dsl/instance_methods.rbs +48 -0
  881. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/spec/dsl.rbs +129 -0
  882. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/spec.rbs +11 -0
  883. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/statistics_reporter.rbs +81 -0
  884. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/summary_reporter.rbs +18 -0
  885. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/test/lifecycle_hooks.rbs +92 -0
  886. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/test.rbs +69 -0
  887. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/unexpected_error.rbs +12 -0
  888. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/unexpected_warning.rbs +6 -0
  889. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/unit/test_case.rbs +3 -0
  890. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest/unit.rbs +4 -0
  891. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/minitest/0/minitest.rbs +115 -0
  892. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/monitor/0/monitor.rbs +363 -0
  893. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/mutex_m/0/mutex_m.rbs +104 -0
  894. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-http/0/manifest.yaml +3 -0
  895. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-http/0/net-http.rbs +5580 -0
  896. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-protocol/0/manifest.yaml +2 -0
  897. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-protocol/0/net-protocol.rbs +56 -0
  898. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-smtp/0/manifest.yaml +2 -0
  899. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/net-smtp/0/net-smtp.rbs +55 -0
  900. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/nkf/0/nkf.rbs +402 -0
  901. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/objspace/0/objspace.rbs +470 -0
  902. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/observable/0/observable.rbs +217 -0
  903. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/open-uri/0/manifest.yaml +4 -0
  904. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/open-uri/0/open-uri.rbs +433 -0
  905. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/open3/0/open3.rbs +606 -0
  906. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/openssl/0/manifest.yaml +3 -0
  907. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/openssl/0/openssl.rbs +12237 -0
  908. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/optparse/0/optparse.rbs +1734 -0
  909. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pathname/0/pathname.rbs +36 -0
  910. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pp/0/manifest.yaml +2 -0
  911. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pp/0/pp.rbs +301 -0
  912. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/prettyprint/0/prettyprint.rbs +383 -0
  913. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pstore/0/pstore.rbs +608 -0
  914. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/core_ext.rbs +12 -0
  915. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/dbm.rbs +237 -0
  916. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/manifest.yaml +3 -0
  917. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/psych.rbs +455 -0
  918. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/psych/0/store.rbs +57 -0
  919. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/pty/0/pty.rbs +240 -0
  920. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/random-formatter/0/random-formatter.rbs +277 -0
  921. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/code_object.rbs +52 -0
  922. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/comment.rbs +61 -0
  923. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/context.rbs +153 -0
  924. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/markup.rbs +117 -0
  925. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/options.rbs +76 -0
  926. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/parser.rbs +56 -0
  927. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/rdoc.rbs +393 -0
  928. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/ri.rbs +17 -0
  929. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/store.rbs +48 -0
  930. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/rdoc/0/top_level.rbs +97 -0
  931. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/resolv/0/manifest.yaml +3 -0
  932. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/resolv/0/resolv.rbs +1787 -0
  933. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/ripper/0/ripper.rbs +1654 -0
  934. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/securerandom/0/manifest.yaml +2 -0
  935. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/securerandom/0/securerandom.rbs +49 -0
  936. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/shellwords/0/shellwords.rbs +229 -0
  937. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/singleton/0/singleton.rbs +137 -0
  938. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/addrinfo.rbs +666 -0
  939. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/basic_socket.rbs +590 -0
  940. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/constants.rbs +2295 -0
  941. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/ip_socket.rbs +94 -0
  942. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/socket.rbs +4170 -0
  943. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/socket_error.rbs +5 -0
  944. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/tcp_server.rbs +192 -0
  945. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/tcp_socket.rbs +87 -0
  946. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/udp_socket.rbs +133 -0
  947. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/unix_server.rbs +169 -0
  948. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/socket/0/unix_socket.rbs +172 -0
  949. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/stringio/0/stringio.rbs +1682 -0
  950. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/strscan/0/string_scanner.rbs +1648 -0
  951. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tempfile/0/manifest.yaml +3 -0
  952. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tempfile/0/tempfile.rbs +483 -0
  953. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/time/0/time.rbs +434 -0
  954. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/timeout/0/timeout.rbs +132 -0
  955. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tmpdir/0/tmpdir.rbs +69 -0
  956. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tsort/0/cyclic.rbs +8 -0
  957. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tsort/0/interfaces.rbs +20 -0
  958. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/tsort/0/tsort.rbs +410 -0
  959. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/common.rbs +621 -0
  960. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/file.rbs +118 -0
  961. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/ftp.rbs +13 -0
  962. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/generic.rbs +1111 -0
  963. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/http.rbs +104 -0
  964. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/https.rbs +14 -0
  965. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/ldap.rbs +230 -0
  966. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/ldaps.rbs +14 -0
  967. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/mailto.rbs +92 -0
  968. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/rfc2396_parser.rbs +189 -0
  969. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/rfc3986_parser.rbs +2 -0
  970. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/ws.rbs +13 -0
  971. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/uri/0/wss.rbs +9 -0
  972. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/yaml/0/manifest.yaml +2 -0
  973. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/yaml/0/yaml.rbs +1 -0
  974. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/buf_error.rbs +10 -0
  975. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/data_error.rbs +10 -0
  976. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/deflate.rbs +211 -0
  977. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/error.rbs +20 -0
  978. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file/crc_error.rbs +12 -0
  979. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file/error.rbs +23 -0
  980. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file/length_error.rbs +12 -0
  981. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file/no_footer.rbs +11 -0
  982. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_file.rbs +156 -0
  983. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_reader.rbs +293 -0
  984. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/gzip_writer.rbs +169 -0
  985. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/inflate.rbs +180 -0
  986. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/mem_error.rbs +10 -0
  987. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/need_dict.rbs +13 -0
  988. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/stream_end.rbs +11 -0
  989. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/stream_error.rbs +11 -0
  990. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/version_error.rbs +11 -0
  991. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/zlib.rbs +449 -0
  992. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/stdlib/zlib/0/zstream.rbs +200 -0
  993. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/wasm/README.md +109 -0
  994. data/vendor/bundle/ruby/3.4.0/gems/rbs-4.2.0/wasm/rbs_wasm.c +479 -0
  995. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/LICENSE +19 -0
  996. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/README.md +135 -0
  997. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/datetime.rb +54 -0
  998. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/dumper.rb +182 -0
  999. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/errors.rb +17 -0
  1000. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/inline_table.rb +18 -0
  1001. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/keyvalue.rb +45 -0
  1002. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/parser.rb +296 -0
  1003. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/string.rb +41 -0
  1004. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/table.rb +34 -0
  1005. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/table_array.rb +43 -0
  1006. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb/version.rb +5 -0
  1007. data/vendor/bundle/ruby/3.4.0/gems/toml-rb-6.0.0/lib/toml-rb.rb +90 -0
  1008. data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/Gemfile +4 -0
  1009. data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/LICENSE.txt +22 -0
  1010. data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/README.md +72 -0
  1011. data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/Rakefile +10 -0
  1012. data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/bin/console +14 -0
  1013. data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/bin/setup +8 -0
  1014. data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/lib/tsort.rb +455 -0
  1015. data/vendor/bundle/ruby/3.4.0/gems/tsort-0.2.0/tsort.gemspec +29 -0
  1016. data/vendor/bundle/ruby/3.4.0/specifications/drb-2.2.3.gemspec +22 -0
  1017. data/vendor/bundle/ruby/3.4.0/specifications/logger-1.7.0.gemspec +22 -0
  1018. data/vendor/bundle/ruby/3.4.0/specifications/minitest-6.0.6.gemspec +35 -0
  1019. data/vendor/bundle/ruby/3.4.0/specifications/prism-1.9.0.gemspec +24 -0
  1020. data/vendor/bundle/ruby/3.4.0/specifications/rake-13.4.2.gemspec +26 -0
  1021. data/vendor/bundle/ruby/3.4.0/specifications/rake-compiler-1.3.2.gemspec +33 -0
  1022. data/vendor/bundle/ruby/3.4.0/specifications/rake-compiler-dock-1.12.0.gemspec +28 -0
  1023. data/vendor/bundle/ruby/3.4.0/specifications/rb_sys-0.9.130.gemspec +29 -0
  1024. data/vendor/bundle/ruby/3.4.0/specifications/rbs-4.2.0.gemspec +33 -0
  1025. data/vendor/bundle/ruby/3.4.0/specifications/toml-rb-6.0.0.gemspec +27 -0
  1026. data/vendor/bundle/ruby/3.4.0/specifications/tsort-0.2.0.gemspec +23 -0
  1027. data/vendor/cache/Cargo.toml +21 -0
  1028. data/vendor/cache/LICENSE +21 -0
  1029. data/vendor/cache/README.md +5 -0
  1030. data/vendor/cache/src/hash.rs +85 -0
  1031. data/vendor/cache/src/lib.rs +751 -0
  1032. data/vendor/cache/src/loom_tests.rs +340 -0
  1033. data/vendor/cache/src/s3fifo.rs +648 -0
  1034. data/vendor/cache/src/sync.rs +25 -0
  1035. data/vendor/cache/src/tests.rs +260 -0
  1036. data/vendor/compaction/Cargo.toml +32 -0
  1037. data/vendor/compaction/LICENSE +21 -0
  1038. data/vendor/compaction/README.md +5 -0
  1039. data/vendor/compaction/src/blob.rs +478 -0
  1040. data/vendor/compaction/src/cursor.rs +700 -0
  1041. data/vendor/compaction/src/gc.rs +802 -0
  1042. data/vendor/compaction/src/job.rs +861 -0
  1043. data/vendor/compaction/src/lib.rs +102 -0
  1044. data/vendor/compaction/src/merge.rs +995 -0
  1045. data/vendor/compaction/src/picker.rs +681 -0
  1046. data/vendor/compaction/src/resolver.rs +1346 -0
  1047. data/vendor/engine/Cargo.toml +56 -0
  1048. data/vendor/engine/LICENSE +21 -0
  1049. data/vendor/engine/README.md +5 -0
  1050. data/vendor/engine/src/admission.rs +421 -0
  1051. data/vendor/engine/src/catalog.rs +1233 -0
  1052. data/vendor/engine/src/check.rs +1386 -0
  1053. data/vendor/engine/src/clock.rs +244 -0
  1054. data/vendor/engine/src/clock_loom.rs +482 -0
  1055. data/vendor/engine/src/close_gate.rs +325 -0
  1056. data/vendor/engine/src/compact.rs +1509 -0
  1057. data/vendor/engine/src/engine/hooks.rs +1654 -0
  1058. data/vendor/engine/src/engine/info.rs +229 -0
  1059. data/vendor/engine/src/engine.rs +6114 -0
  1060. data/vendor/engine/src/error.rs +490 -0
  1061. data/vendor/engine/src/feed.rs +960 -0
  1062. data/vendor/engine/src/feed_reader.rs +1600 -0
  1063. data/vendor/engine/src/flush.rs +839 -0
  1064. data/vendor/engine/src/flushed_roots.rs +158 -0
  1065. data/vendor/engine/src/flushed_through_loom.rs +77 -0
  1066. data/vendor/engine/src/health.rs +201 -0
  1067. data/vendor/engine/src/large.rs +372 -0
  1068. data/vendor/engine/src/large_settle.rs +201 -0
  1069. data/vendor/engine/src/lib.rs +112 -0
  1070. data/vendor/engine/src/load_slot.rs +324 -0
  1071. data/vendor/engine/src/maintenance.rs +935 -0
  1072. data/vendor/engine/src/manifest/flight.rs +563 -0
  1073. data/vendor/engine/src/manifest.rs +1516 -0
  1074. data/vendor/engine/src/nonblocking.rs +603 -0
  1075. data/vendor/engine/src/options.rs +334 -0
  1076. data/vendor/engine/src/position.rs +125 -0
  1077. data/vendor/engine/src/purge_guard.rs +220 -0
  1078. data/vendor/engine/src/read/keys.rs +1049 -0
  1079. data/vendor/engine/src/read/knn.rs +423 -0
  1080. data/vendor/engine/src/read/reduce.rs +2057 -0
  1081. data/vendor/engine/src/read/traverse.rs +1013 -0
  1082. data/vendor/engine/src/read.rs +2429 -0
  1083. data/vendor/engine/src/row_cache.rs +1101 -0
  1084. data/vendor/engine/src/shard/tablets.rs +3582 -0
  1085. data/vendor/engine/src/shard.rs +12215 -0
  1086. data/vendor/engine/src/snapshot.rs +1429 -0
  1087. data/vendor/engine/src/source.rs +1379 -0
  1088. data/vendor/engine/src/timer_state.rs +226 -0
  1089. data/vendor/engine/src/waker.rs +124 -0
  1090. data/vendor/engine/src/watermark_waiters.rs +674 -0
  1091. data/vendor/engine/src/write.rs +1321 -0
  1092. data/vendor/format/Cargo.toml +40 -0
  1093. data/vendor/format/LICENSE +21 -0
  1094. data/vendor/format/README.md +5 -0
  1095. data/vendor/format/src/blob.rs +101 -0
  1096. data/vendor/format/src/block.rs +1120 -0
  1097. data/vendor/format/src/bloom.rs +456 -0
  1098. data/vendor/format/src/buckets.rs +552 -0
  1099. data/vendor/format/src/bytes.rs +101 -0
  1100. data/vendor/format/src/checksum.rs +132 -0
  1101. data/vendor/format/src/compress.rs +196 -0
  1102. data/vendor/format/src/cursor.rs +110 -0
  1103. data/vendor/format/src/distance.rs +598 -0
  1104. data/vendor/format/src/error.rs +93 -0
  1105. data/vendor/format/src/exact.rs +602 -0
  1106. data/vendor/format/src/feed.rs +285 -0
  1107. data/vendor/format/src/filter.rs +157 -0
  1108. data/vendor/format/src/half.rs +182 -0
  1109. data/vendor/format/src/hash.rs +127 -0
  1110. data/vendor/format/src/hll.rs +500 -0
  1111. data/vendor/format/src/ids.rs +95 -0
  1112. data/vendor/format/src/key.rs +620 -0
  1113. data/vendor/format/src/kind_params.rs +101 -0
  1114. data/vendor/format/src/lib.rs +54 -0
  1115. data/vendor/format/src/manifest.rs +1287 -0
  1116. data/vendor/format/src/roaring.rs +865 -0
  1117. data/vendor/format/src/scan.rs +297 -0
  1118. data/vendor/format/src/shm.rs +805 -0
  1119. data/vendor/format/src/sst.rs +233 -0
  1120. data/vendor/format/src/superblock.rs +345 -0
  1121. data/vendor/format/src/value.rs +163 -0
  1122. data/vendor/format/src/varint.rs +87 -0
  1123. data/vendor/format/src/vector.rs +936 -0
  1124. data/vendor/format/src/version.rs +92 -0
  1125. data/vendor/format/src/wal.rs +999 -0
  1126. data/vendor/io/Cargo.toml +29 -0
  1127. data/vendor/io/LICENSE +21 -0
  1128. data/vendor/io/README.md +5 -0
  1129. data/vendor/io/src/async_poll.rs +44 -0
  1130. data/vendor/io/src/buf.rs +694 -0
  1131. data/vendor/io/src/completion.rs +444 -0
  1132. data/vendor/io/src/error.rs +110 -0
  1133. data/vendor/io/src/file.rs +206 -0
  1134. data/vendor/io/src/lib.rs +53 -0
  1135. data/vendor/io/src/nowait.rs +256 -0
  1136. data/vendor/io/src/os/mod.rs +149 -0
  1137. data/vendor/io/src/os/unix.rs +897 -0
  1138. data/vendor/io/src/os/windows.rs +552 -0
  1139. data/vendor/io/src/own.rs +257 -0
  1140. data/vendor/io/src/pread.rs +854 -0
  1141. data/vendor/io/src/ring_wake.rs +113 -0
  1142. data/vendor/io/src/shared.rs +410 -0
  1143. data/vendor/io/src/sim.rs +1545 -0
  1144. data/vendor/io/src/sys.rs +214 -0
  1145. data/vendor/io/src/uring.rs +1839 -0
  1146. data/vendor/io/src/vfs.rs +154 -0
  1147. data/vendor/memory/Cargo.toml +34 -0
  1148. data/vendor/memory/LICENSE +21 -0
  1149. data/vendor/memory/README.md +11 -0
  1150. data/vendor/memory/src/consolidate.rs +640 -0
  1151. data/vendor/memory/src/dedup.rs +231 -0
  1152. data/vendor/memory/src/error.rs +131 -0
  1153. data/vendor/memory/src/feed_loop.rs +572 -0
  1154. data/vendor/memory/src/forget.rs +724 -0
  1155. data/vendor/memory/src/hooks.rs +109 -0
  1156. data/vendor/memory/src/ivf.rs +204 -0
  1157. data/vendor/memory/src/layout.rs +340 -0
  1158. data/vendor/memory/src/lib.rs +61 -0
  1159. data/vendor/memory/src/recall.rs +1182 -0
  1160. data/vendor/memory/src/store.rs +1785 -0
  1161. data/vendor/memory/src/watch.rs +339 -0
  1162. data/vendor/memtable/Cargo.toml +24 -0
  1163. data/vendor/memtable/LICENSE +21 -0
  1164. data/vendor/memtable/README.md +5 -0
  1165. data/vendor/memtable/src/lib.rs +1658 -0
  1166. data/vendor/memtable/src/loom_tests.rs +274 -0
  1167. data/vendor/memtable/src/mem.rs +344 -0
  1168. data/vendor/memtable/src/tests.rs +1061 -0
  1169. data/vendor/pager/Cargo.toml +23 -0
  1170. data/vendor/pager/LICENSE +21 -0
  1171. data/vendor/pager/README.md +5 -0
  1172. data/vendor/pager/src/alloc.rs +1008 -0
  1173. data/vendor/pager/src/lib.rs +1710 -0
  1174. data/vendor/pigeonhole/Cargo.toml +42 -0
  1175. data/vendor/pigeonhole/LICENSE +21 -0
  1176. data/vendor/pigeonhole/README.md +99 -0
  1177. data/vendor/pigeonhole/src/cell.rs +829 -0
  1178. data/vendor/pigeonhole/src/check.rs +368 -0
  1179. data/vendor/pigeonhole/src/db.rs +2324 -0
  1180. data/vendor/pigeonhole/src/doc_support.rs +89 -0
  1181. data/vendor/pigeonhole/src/error.rs +257 -0
  1182. data/vendor/pigeonhole/src/feed.rs +696 -0
  1183. data/vendor/pigeonhole/src/info.rs +425 -0
  1184. data/vendor/pigeonhole/src/lib.rs +202 -0
  1185. data/vendor/pigeonhole/src/merge.rs +135 -0
  1186. data/vendor/pigeonhole/src/metrics.rs +476 -0
  1187. data/vendor/pigeonhole/src/nonblocking.rs +666 -0
  1188. data/vendor/pigeonhole/src/options.rs +2075 -0
  1189. data/vendor/pigeonhole/src/read/budget.rs +584 -0
  1190. data/vendor/pigeonhole/src/read.rs +2463 -0
  1191. data/vendor/pigeonhole/src/recovery.rs +876 -0
  1192. data/vendor/pigeonhole/src/retry.rs +358 -0
  1193. data/vendor/pigeonhole/src/set.rs +103 -0
  1194. data/vendor/pigeonhole/src/table.rs +861 -0
  1195. data/vendor/pigeonhole/src/vector.rs +351 -0
  1196. data/vendor/pigeonhole/src/write.rs +2815 -0
  1197. data/vendor/runtime/Cargo.toml +21 -0
  1198. data/vendor/runtime/LICENSE +21 -0
  1199. data/vendor/runtime/README.md +5 -0
  1200. data/vendor/runtime/src/completion.rs +629 -0
  1201. data/vendor/runtime/src/drivers.rs +1175 -0
  1202. data/vendor/runtime/src/lib.rs +1546 -0
  1203. data/vendor/runtime/src/pool.rs +992 -0
  1204. data/vendor/runtime/src/sched.rs +809 -0
  1205. data/vendor/runtime/src/signal.rs +532 -0
  1206. data/vendor/runtime/src/submit_gate.rs +144 -0
  1207. data/vendor/shm/Cargo.toml +24 -0
  1208. data/vendor/shm/LICENSE +21 -0
  1209. data/vendor/shm/README.md +5 -0
  1210. data/vendor/shm/src/lib.rs +427 -0
  1211. data/vendor/shm/src/lock.rs +153 -0
  1212. data/vendor/shm/src/region.rs +1609 -0
  1213. data/vendor/sst/Cargo.toml +26 -0
  1214. data/vendor/sst/LICENSE +21 -0
  1215. data/vendor/sst/README.md +5 -0
  1216. data/vendor/sst/src/blob.rs +380 -0
  1217. data/vendor/sst/src/iter.rs +803 -0
  1218. data/vendor/sst/src/lib.rs +695 -0
  1219. data/vendor/sst/src/reader.rs +814 -0
  1220. data/vendor/sst/src/writer.rs +596 -0
  1221. data/vendor/text/Cargo.toml +26 -0
  1222. data/vendor/text/LICENSE +21 -0
  1223. data/vendor/text/README.md +9 -0
  1224. data/vendor/text/src/error.rs +108 -0
  1225. data/vendor/text/src/fuzzy.rs +265 -0
  1226. data/vendor/text/src/highlight.rs +236 -0
  1227. data/vendor/text/src/index.rs +1152 -0
  1228. data/vendor/text/src/layout.rs +424 -0
  1229. data/vendor/text/src/lib.rs +75 -0
  1230. data/vendor/text/src/maxscore.rs +658 -0
  1231. data/vendor/text/src/query.rs +450 -0
  1232. data/vendor/text/src/search.rs +569 -0
  1233. data/vendor/text/src/sloppy.rs +460 -0
  1234. data/vendor/text/src/tokenizer.rs +163 -0
  1235. data/vendor/vector/Cargo.toml +28 -0
  1236. data/vendor/vector/LICENSE +21 -0
  1237. data/vendor/vector/README.md +9 -0
  1238. data/vendor/vector/src/error.rs +63 -0
  1239. data/vendor/vector/src/half.rs +167 -0
  1240. data/vendor/vector/src/hooks.rs +135 -0
  1241. data/vendor/vector/src/index.rs +2690 -0
  1242. data/vendor/vector/src/layout.rs +102 -0
  1243. data/vendor/vector/src/lib.rs +52 -0
  1244. data/vendor/vector/src/point.rs +500 -0
  1245. data/vendor/vector/src/rebalancer.rs +200 -0
  1246. data/vendor/vector/src/registry.rs +81 -0
  1247. data/vendor/wal/Cargo.toml +25 -0
  1248. data/vendor/wal/LICENSE +21 -0
  1249. data/vendor/wal/README.md +5 -0
  1250. data/vendor/wal/src/feed.rs +610 -0
  1251. data/vendor/wal/src/foreground.rs +122 -0
  1252. data/vendor/wal/src/lib.rs +458 -0
  1253. data/vendor/wal/src/mem.rs +166 -0
  1254. data/vendor/wal/src/recovery.rs +426 -0
  1255. data/vendor/wal/src/stream.rs +2382 -0
  1256. metadata +1310 -0
@@ -0,0 +1,2690 @@
1
+ //! The index (D306): writes, inline split and merge, search, and verification.
2
+
3
+ use std::collections::{HashMap, HashSet, VecDeque};
4
+ use std::sync::atomic::{AtomicBool, Ordering};
5
+ use std::sync::{Arc, Mutex, PoisonError, RwLock};
6
+ use std::time::Duration;
7
+
8
+ use pigeonhole::{
9
+ Element, ErrorCode, Family, KeySet, KeysRead, Pigeonhole, PigeonholeReader, ReadTable,
10
+ RetryPolicy, Scan, Snapshot, Table, Transaction, Vector, VectorSpec,
11
+ };
12
+
13
+ use crate::layout::{
14
+ CEN, CNT, GLOBAL, LAYOUT, LIST, MAP, MARK, META, NEXT, OPTS, VEC, VERSION, centroid_row,
15
+ count_row, list_of, list_row, map_row, queue_row, scramble,
16
+ };
17
+ use crate::point::{Input, Plan, Point, Stored, distance, two_means, unit};
18
+ use crate::rebalancer::{Rebalancer, Signal};
19
+ use crate::{Error, Result};
20
+
21
+ /// A list row stays at most this large (D306 §1): the target list length is scaled down
22
+ /// for large vectors so `2 × target` vectors fit.
23
+ const MAX_LIST_BYTES: u64 = 4 << 20;
24
+ /// Attempts of one split or merge before it leaves the list for the next trigger (rev 3 S1).
25
+ const ATTEMPTS: usize = 4;
26
+ /// Centroid reloads an insert or delete makes before it gives up with `Conflict`.
27
+ const RELOADS: usize = 32;
28
+ /// Splits and merges one insert or delete runs after its commit, at most; the rest stay
29
+ /// queued for the next call.
30
+ const MAINTENANCE_PER_CALL: usize = 16;
31
+
32
+ /// An index's options, fixed when it is created ([`Index::create`]) and stored with it.
33
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
34
+ pub struct IndexOptions {
35
+ target: u32,
36
+ nprobe: u32,
37
+ reassign: u32,
38
+ rebalance: Rebalance,
39
+ }
40
+
41
+ /// Who splits and merges an index's lists (D306 §3).
42
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
43
+ #[non_exhaustive]
44
+ pub enum Rebalance {
45
+ /// Inside the insert or delete that took the list out of its bounds, before the call
46
+ /// returns: the writer pays for the split.
47
+ #[default]
48
+ Inline,
49
+ /// In a [`Rebalancer`]: a write marks the list and returns, and the rebalancer splits or
50
+ /// merges it soon after. [`Index::open`] runs one on a thread of the crate's own;
51
+ /// [`Index::open_with_rebalancer`] hands it to the application instead. Until it runs,
52
+ /// a list may hold more than [`Index::max_list_len`] vectors, which costs searches that
53
+ /// probe it, never their correctness.
54
+ Background,
55
+ }
56
+
57
+ impl Default for IndexOptions {
58
+ fn default() -> Self {
59
+ Self {
60
+ target: 1000,
61
+ nprobe: 24,
62
+ reassign: 2,
63
+ rebalance: Rebalance::Inline,
64
+ }
65
+ }
66
+ }
67
+
68
+ impl IndexOptions {
69
+ /// The defaults: lists of about 1,000 vectors, 24 lists probed per search (95.8%
70
+ /// recall@10 on SIFT1M, D306 PR 3), and 2
71
+ /// neighbouring lists reassigned after a split.
72
+ pub fn new() -> Self {
73
+ Self::default()
74
+ }
75
+
76
+ /// The length a list is kept near (at least 4): a list splits above twice this, and
77
+ /// merges into its nearest neighbour below a quarter of it. Scaled down for large
78
+ /// vectors, so a list row stays within 4 MiB.
79
+ pub fn target_list_len(mut self, n: u32) -> Self {
80
+ self.target = n;
81
+ self
82
+ }
83
+
84
+ /// Lists a search probes unless it says otherwise ([`Search::nprobe`]; at least 1).
85
+ /// Fixed when the index is created, like every option here. The default, 24, gave
86
+ /// 95.8% recall@10 on SIFT1M; recall depends on the data, so measure your own.
87
+ pub fn nprobe(mut self, n: u32) -> Self {
88
+ self.nprobe = n;
89
+ self
90
+ }
91
+
92
+ /// Neighbouring lists a split re-examines for vectors now nearer one of its two new
93
+ /// centroids (SPFresh's LIRE; 0 turns it off). It improves clustering, not correctness.
94
+ pub fn reassign_neighbours(mut self, r: u32) -> Self {
95
+ self.reassign = r;
96
+ self
97
+ }
98
+
99
+ /// Who splits and merges the lists ([`Rebalance::Inline`] by default).
100
+ pub fn rebalance(mut self, r: Rebalance) -> Self {
101
+ self.rebalance = r;
102
+ self
103
+ }
104
+
105
+ /// Who splits and merges the lists.
106
+ pub fn rebalance_mode(&self) -> Rebalance {
107
+ self.rebalance
108
+ }
109
+
110
+ fn checked(mut self, spec: &VectorSpec) -> Result<Self> {
111
+ if self.target < 4 || self.nprobe == 0 {
112
+ return Err(Error::InvalidArgument(format!(
113
+ "index options: the target list length must be at least 4 and nprobe at least \
114
+ 1, not {} and {}",
115
+ self.target, self.nprobe
116
+ )));
117
+ }
118
+ let bytes = match spec.element() {
119
+ Element::F32 => 4 * u64::from(spec.dim()),
120
+ Element::Bit => u64::from(spec.dim()) / 8,
121
+ _ => u64::from(spec.dim()),
122
+ };
123
+ let cap = (MAX_LIST_BYTES / (2 * bytes)).max(4);
124
+ self.target = self.target.min(u32::try_from(cap).unwrap_or(u32::MAX));
125
+ Ok(self)
126
+ }
127
+
128
+ /// Version 2: version 1's three `u32`s, then the rebalance mode (0 inline, 1
129
+ /// background). Version 1 (PR 1) decodes as inline.
130
+ fn encode(&self) -> Vec<u8> {
131
+ let mut out = vec![2];
132
+ for v in [self.target, self.nprobe, self.reassign] {
133
+ out.extend_from_slice(&v.to_le_bytes());
134
+ }
135
+ out.push(match self.rebalance {
136
+ Rebalance::Inline => 0,
137
+ Rebalance::Background => 1,
138
+ });
139
+ out
140
+ }
141
+
142
+ fn decode(b: &[u8]) -> Option<Self> {
143
+ let (rest, rebalance) = match b {
144
+ [1, rest @ ..] => (rest, Rebalance::Inline),
145
+ [2, rest @ .., 0] => (rest, Rebalance::Inline),
146
+ [2, rest @ .., 1] => (rest, Rebalance::Background),
147
+ _ => return None,
148
+ };
149
+ let (words, []) = rest.as_chunks::<4>() else {
150
+ return None;
151
+ };
152
+ let [target, nprobe, reassign] = words else {
153
+ return None;
154
+ };
155
+ Some(Self {
156
+ target: u32::from_le_bytes(*target),
157
+ nprobe: u32::from_le_bytes(*nprobe),
158
+ reassign: u32::from_le_bytes(*reassign),
159
+ rebalance,
160
+ })
161
+ }
162
+ }
163
+
164
+ /// One result of a [`Search`]: the id given at insert, and its distance to the query under
165
+ /// the index's metric (smaller is nearer), as [`VectorSpec`]'s `distance_*` give it.
166
+ ///
167
+ /// Hits at an equal distance come back in the order of the lists that hold them, then by
168
+ /// id, as `nearest_*` orders a list's row then its qualifiers. That order is fixed at a
169
+ /// snapshot, but a split can move a tied id to another list, so which of several tied ids
170
+ /// makes the cut at `k` can change from one layout to the next.
171
+ #[derive(Debug, Clone, PartialEq)]
172
+ #[non_exhaustive]
173
+ pub struct Hit {
174
+ /// The vector's id.
175
+ pub id: Vec<u8>,
176
+ /// Its distance to the query.
177
+ pub distance: f64,
178
+ }
179
+
180
+ /// One transaction's writes to an index ([`Index::insert_f32_in`] and its forms,
181
+ /// [`Index::delete_in`]): make one per transaction with [`Placed::new`], pass it to each
182
+ /// write, and to [`Index::after_commit`] once the transaction commits.
183
+ ///
184
+ /// A transaction's reads don't see its own writes, so the index remembers here where it
185
+ /// put each id: a second write of an id in the same transaction (an upsert, a delete after
186
+ /// an insert, an insert after a delete) acts on that, not on the snapshot (cli692's B1 on
187
+ /// #1412). Writes of one transaction through two `Placed` lose that, so use one.
188
+ ///
189
+ /// **Make it inside the transaction's body** (the closure
190
+ /// [`Pigeonhole::transact`](pigeonhole::Pigeonhole::transact) runs), so a retried attempt
191
+ /// starts with a fresh one: one made outside would carry an aborted attempt's record into
192
+ /// the retry. A `Placed` belongs to the index its first write used; using it with another
193
+ /// index is [`Error::InvalidArgument`] (cli692's C1 and C2).
194
+ #[derive(Debug, Clone, Default)]
195
+ #[must_use = "pass it to Index::after_commit once the transaction commits; dropping it only delays a split or merge until the next write to its lists"]
196
+ pub struct Placed {
197
+ lists: Vec<u32>,
198
+ /// Each id this transaction wrote: the list it's in now, or `None` once deleted.
199
+ ids: HashMap<Vec<u8>, Option<u32>>,
200
+ /// This transaction created list 0 (the index was empty at its snapshot).
201
+ bootstrapped: bool,
202
+ /// The index it belongs to, set by its first write. A `Weak` keeps the shared state's
203
+ /// allocation reserved, so another index can't reuse its address while this lives
204
+ /// (cli692 on #1412).
205
+ index: Option<std::sync::Weak<Inner>>,
206
+ }
207
+
208
+ impl PartialEq for Placed {
209
+ fn eq(&self, other: &Self) -> bool {
210
+ self.lists == other.lists
211
+ && self.ids == other.ids
212
+ && self.bootstrapped == other.bootstrapped
213
+ && match (&self.index, &other.index) {
214
+ (None, None) => true,
215
+ (Some(a), Some(b)) => a.ptr_eq(b),
216
+ _ => false,
217
+ }
218
+ }
219
+ }
220
+
221
+ impl Eq for Placed {}
222
+
223
+ // A `Placed` crosses threads with the transaction it records (cli692 on #1412).
224
+ const _: fn() = || {
225
+ fn send<T: Send + Sync>() {}
226
+ send::<Placed>();
227
+ };
228
+
229
+ impl Placed {
230
+ /// No writes yet.
231
+ pub fn new() -> Self {
232
+ Self::default()
233
+ }
234
+
235
+ /// Binds this record to `index` on first use; another index is `InvalidArgument`.
236
+ fn bind(&mut self, index: &Index) -> Result<()> {
237
+ match &self.index {
238
+ None => {
239
+ self.index = Some(Arc::downgrade(&index.inner));
240
+ Ok(())
241
+ }
242
+ Some(i) if std::ptr::eq(i.as_ptr(), Arc::as_ptr(&index.inner)) => Ok(()),
243
+ Some(_) => Err(Error::InvalidArgument(
244
+ "a Placed records one index's writes: make one per index and transaction".into(),
245
+ )),
246
+ }
247
+ }
248
+
249
+ fn wrote(&mut self, id: &[u8], now: Option<u32>, lists: impl IntoIterator<Item = u32>) {
250
+ for l in lists {
251
+ if !self.lists.contains(&l) {
252
+ self.lists.push(l);
253
+ }
254
+ }
255
+ self.ids.insert(id.to_vec(), now);
256
+ }
257
+ }
258
+
259
+ /// What a bulk load did ([`Index::bulk_load_f32`] and its forms).
260
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
261
+ #[non_exhaustive]
262
+ pub struct BulkStats {
263
+ /// Vectors written (a repeated id counts once per occurrence).
264
+ pub vectors: u64,
265
+ /// Lists k-means made before the load (splits and merges may change the count after).
266
+ pub lists: u32,
267
+ }
268
+
269
+ /// Vectors a bulk load clusters to choose its lists: the first this many it reads.
270
+ const BULK_SAMPLE: usize = 50_000;
271
+ /// Vectors per transaction when a bulk load writes a list.
272
+ const BULK_BATCH: usize = 256;
273
+ /// Lloyd iterations of a bulk load's k-means.
274
+ const KMEANS_ITERATIONS: usize = 10;
275
+
276
+ /// Counts from [`Index::verify`].
277
+ #[derive(Debug, Clone, PartialEq, Eq)]
278
+ #[non_exhaustive]
279
+ pub struct IndexStats {
280
+ /// Each list's length, in list order.
281
+ pub list_lens: Vec<u64>,
282
+ /// Vectors in the index.
283
+ pub vectors: u64,
284
+ }
285
+
286
+ /// An IVF index over one table (D306). Cheap to clone; clones share the centroid cache.
287
+ ///
288
+ /// ```
289
+ /// use pigeonhole::{Element, Metric, Options, Pigeonhole, VectorSpec};
290
+ /// use pigeonhole_vector::{Index, IndexOptions};
291
+ ///
292
+ /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
293
+ /// # let dir = pigeonhole::doc_support::temp_dir();
294
+ /// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default())?;
295
+ /// let spec = VectorSpec::new(2, Element::F32, Metric::L2)?;
296
+ /// let index = Index::create(&db, "points", spec, IndexOptions::new().target_list_len(4))?;
297
+ /// for i in 0..40u32 {
298
+ /// let x = i as f32;
299
+ /// index.insert_f32(&i.to_be_bytes(), &[x, -x])?;
300
+ /// }
301
+ /// let hits = index.search_f32(&[10.2, -10.2], 3).nprobe(2).run()?;
302
+ /// assert_eq!(hits[0].id, 10u32.to_be_bytes());
303
+ ///
304
+ /// assert!(index.delete(&10u32.to_be_bytes())?);
305
+ /// let stats = index.verify()?;
306
+ /// assert_eq!(stats.vectors, 39);
307
+ /// # db.close()?;
308
+ /// # Ok(())
309
+ /// # }
310
+ /// ```
311
+ #[derive(Clone)]
312
+ pub struct Index {
313
+ inner: Arc<Inner>,
314
+ /// Counts the application's handles: a rebalancer's own temporary handle has a token of
315
+ /// its own, so it can tell when every application handle is gone (simp724's R1 on
316
+ /// #1271).
317
+ user: Arc<()>,
318
+ }
319
+
320
+ impl std::fmt::Debug for Index {
321
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
322
+ f.debug_struct("Index")
323
+ .field("table", &self.inner.table.name())
324
+ .field("spec", &self.inner.spec)
325
+ .field("options", &self.inner.opts)
326
+ .finish_non_exhaustive()
327
+ }
328
+ }
329
+
330
+ pub(crate) struct Inner {
331
+ db: Pigeonhole,
332
+ table: Table,
333
+ spec: VectorSpec,
334
+ /// The centroid family's spec: `f32` of the index's dimension and metric, or the
335
+ /// index's own for bits (rev 2 S1).
336
+ cen: VectorSpec,
337
+ opts: IndexOptions,
338
+ /// The centroids as last loaded at the current layout (rev 3 S4).
339
+ layout: RwLock<Arc<Layout>>,
340
+ /// Lists with a split or merge running in this process (rev 4).
341
+ in_flight: Mutex<HashSet<u32>>,
342
+ /// Lists to check against their bounds: after writes, and found by `open` (rev 3 M3).
343
+ pending: Mutex<VecDeque<u32>>,
344
+ /// Wakes the background rebalancer, and tells it when the last handle is gone.
345
+ signal: Arc<Signal>,
346
+ /// The crate's rebalancing thread was started for this index ([`Index::open`] in
347
+ /// background mode): one per index, however many opens share it (#1268 item 8).
348
+ thread: AtomicBool,
349
+ }
350
+
351
+ impl Inner {
352
+ pub(crate) fn db(&self) -> &Pigeonhole {
353
+ &self.db
354
+ }
355
+
356
+ /// Whether this is still the index its table name names: its options row reads through
357
+ /// its own table handle. A dropped table (perhaps created again since) or a closed
358
+ /// database refuses the read (the registry's stale-entry check, #1268 item 8).
359
+ pub(crate) fn is_live(&self) -> bool {
360
+ matches!(self.table.get(GLOBAL, META, OPTS), Ok(Some(_)))
361
+ }
362
+ }
363
+
364
+ impl Drop for Inner {
365
+ fn drop(&mut self) {
366
+ self.signal.close();
367
+ }
368
+ }
369
+
370
+ /// The centroids at one snapshot.
371
+ #[derive(Debug)]
372
+ struct Layout {
373
+ seqno: u64,
374
+ /// `G:layout`: centroids change only with it.
375
+ version: u64,
376
+ /// By list id.
377
+ lists: Vec<List>,
378
+ }
379
+
380
+ #[derive(Debug)]
381
+ struct List {
382
+ id: u32,
383
+ version: u64,
384
+ centroid: Vector,
385
+ point: Point,
386
+ }
387
+
388
+ impl Layout {
389
+ fn list(&self, id: u32) -> Option<&List> {
390
+ self.lists
391
+ .binary_search_by_key(&id, |l| l.id)
392
+ .ok()
393
+ .map(|i| &self.lists[i])
394
+ }
395
+
396
+ /// The `n` lists nearest `p`, nearest first, ties by list id, leaving out `skip`.
397
+ fn nearest(&self, cen: &VectorSpec, p: &Point, n: usize, skip: &[u32]) -> Result<Vec<u32>> {
398
+ let mut all = Vec::with_capacity(self.lists.len());
399
+ for l in self.lists.iter().filter(|l| !skip.contains(&l.id)) {
400
+ all.push((distance(cen, p, &l.centroid)?, l.id));
401
+ }
402
+ all.sort_by(|a, b| a.0.total_cmp(&b.0).then(a.1.cmp(&b.1)));
403
+ Ok(all.into_iter().take(n).map(|(_, id)| id).collect())
404
+ }
405
+ }
406
+
407
+ /// How a transaction body ends besides committing.
408
+ enum Tx {
409
+ Db(pigeonhole::Error),
410
+ /// The layout it acted on is gone: reload the centroids and try again, or stop.
411
+ Stale,
412
+ Fail(Error),
413
+ }
414
+
415
+ impl From<pigeonhole::Error> for Tx {
416
+ fn from(e: pigeonhole::Error) -> Self {
417
+ Tx::Db(e)
418
+ }
419
+ }
420
+
421
+ impl From<Error> for Tx {
422
+ fn from(e: Error) -> Self {
423
+ Tx::Fail(e)
424
+ }
425
+ }
426
+
427
+ impl From<Tx> for Error {
428
+ fn from(t: Tx) -> Self {
429
+ match t {
430
+ Tx::Db(e) => Error::Db(e),
431
+ Tx::Stale => Error::Conflict("the index's layout changed".into()),
432
+ Tx::Fail(e) => e,
433
+ }
434
+ }
435
+ }
436
+
437
+ /// A retry's pause: 5 µs doubling, at most 1 ms.
438
+ fn backoff(attempt: usize) -> Duration {
439
+ Duration::from_micros(5u64 << attempt.min(8)).min(Duration::from_millis(1))
440
+ }
441
+
442
+ fn is_conflict(t: &Tx) -> bool {
443
+ matches!(t, Tx::Db(e) if e.code() == ErrorCode::Conflict)
444
+ }
445
+
446
+ /// A transaction's snapshot shows `M{id}` naming a list with no centroid. A merge moves a
447
+ /// list's vectors and mappings and deletes its centroid in one transaction that reads the
448
+ /// list's whole row, so no consistent snapshot shows this: it's what `verify` reports as
449
+ /// corruption (cli692's B2 on #1412).
450
+ fn unmapped() -> Error {
451
+ corrupt("a mapping names a list with no centroid")
452
+ }
453
+
454
+ fn corrupt(what: &str) -> Error {
455
+ Error::Corruption(what.to_owned())
456
+ }
457
+
458
+ /// The centroid family's spec for an index of `spec` (rev 2 S1).
459
+ fn centroid_spec(spec: &VectorSpec) -> Result<VectorSpec> {
460
+ match spec.element() {
461
+ Element::Bit => Ok(*spec),
462
+ // Half indexes keep `f32` centroids too (#1268 item 7): a mean of halves isn't a half.
463
+ Element::F32 | Element::I8 | Element::F16 | Element::BF16 => {
464
+ Ok(VectorSpec::new(spec.dim(), Element::F32, spec.metric())?)
465
+ }
466
+ other => Err(Error::InvalidArgument(format!(
467
+ "an index of {other:?} vectors is not supported"
468
+ ))),
469
+ }
470
+ }
471
+
472
+ fn read_u64(
473
+ tx: &mut Transaction,
474
+ t: &Table,
475
+ row: &[u8],
476
+ family: &str,
477
+ q: &[u8],
478
+ ) -> std::result::Result<Option<u64>, Tx> {
479
+ match tx.get(t, row, family, q)? {
480
+ None => Ok(None),
481
+ Some(c) => c
482
+ .as_u64()
483
+ .map(Some)
484
+ .ok_or_else(|| Tx::Fail(corrupt("an index counter or version is not an integer"))),
485
+ }
486
+ }
487
+
488
+ /// `C{list}:meta:v`, or `None` when the list doesn't exist (merged away, rev 3 M1).
489
+ fn read_version(
490
+ tx: &mut Transaction,
491
+ t: &Table,
492
+ list: u32,
493
+ ) -> std::result::Result<Option<u64>, Tx> {
494
+ read_u64(tx, t, &centroid_row(list), META, VERSION)
495
+ }
496
+
497
+ /// `M{id}`: the list holding `id`.
498
+ fn read_list_of(
499
+ tx: &mut Transaction,
500
+ t: &Table,
501
+ id: &[u8],
502
+ ) -> std::result::Result<Option<u32>, Tx> {
503
+ read_u64(tx, t, &map_row(id), MAP, LIST)?
504
+ .map(|l| u32::try_from(l).map_err(|_| Tx::Fail(corrupt("a mapping names no list"))))
505
+ .transpose()
506
+ }
507
+
508
+ /// The vector `id` holds in the list row `row`, read in the transaction (rev 4 N1).
509
+ fn read_stored(
510
+ tx: &mut Transaction,
511
+ t: &Table,
512
+ row: &[u8],
513
+ id: &[u8],
514
+ ) -> std::result::Result<Option<Stored>, Tx> {
515
+ match tx.get(t, row, VEC, id)? {
516
+ None => Ok(None),
517
+ Some(c) => {
518
+ let v = c
519
+ .as_vector()
520
+ .ok_or_else(|| Tx::Fail(corrupt("a list column is not a vector")))?;
521
+ Ok(Some(Stored::of(v)?))
522
+ }
523
+ }
524
+ }
525
+
526
+ /// Writes `id`'s vector into list `l`, moving it out of `old` (the list `id` is in) when
527
+ /// that's another list. The caller has read `l`'s version in `tx`. With `check_old` (`old`
528
+ /// came from `M{id}` at `tx`'s snapshot) this reads `old`'s version, and a mapping to a
529
+ /// list with no centroid is `Stale`; without it, `old` is the list this transaction itself
530
+ /// wrote `id` to.
531
+ fn write_into(
532
+ tx: &mut Transaction,
533
+ t: &Table,
534
+ l: u32,
535
+ old: Option<u32>,
536
+ check_old: bool,
537
+ id: &[u8],
538
+ v: Input<'_>,
539
+ ) -> std::result::Result<(), Tx> {
540
+ match old {
541
+ // An upsert within its list: the vector only (M2).
542
+ Some(o) if o == l => v.put(tx, t, &list_row(l), id),
543
+ Some(o) => {
544
+ if check_old && read_version(tx, t, o)?.is_none() {
545
+ return Err(Tx::Stale);
546
+ }
547
+ tx.delete_column(t, &list_row(o), VEC, id);
548
+ v.put(tx, t, &list_row(l), id);
549
+ tx.put_u64(t, &map_row(id), MAP, LIST, u64::from(l))
550
+ .incr(t, &count_row(o), CNT, b"", -1)
551
+ .incr(t, &count_row(l), CNT, b"", 1);
552
+ }
553
+ None => {
554
+ v.put(tx, t, &list_row(l), id);
555
+ tx.put_u64(t, &map_row(id), MAP, LIST, u64::from(l)).incr(
556
+ t,
557
+ &count_row(l),
558
+ CNT,
559
+ b"",
560
+ 1,
561
+ );
562
+ }
563
+ }
564
+ Ok(())
565
+ }
566
+
567
+ /// The bootstrap's writes: list 0, centred on `centroid`, holding `id`. The caller has read
568
+ /// `G:meta:next` as 0 in `tx`.
569
+ fn write_bootstrap(tx: &mut Transaction, t: &Table, centroid: &Point, id: &[u8], v: Input<'_>) {
570
+ put_centroid(tx, t, 0, centroid);
571
+ tx.put_u64(t, &centroid_row(0), META, VERSION, 1)
572
+ .put_u64(t, GLOBAL, META, NEXT, 1)
573
+ .put_u64(t, GLOBAL, META, LAYOUT, 1);
574
+ v.put(tx, t, &list_row(0), id);
575
+ tx.put_u64(t, &map_row(id), MAP, LIST, 0)
576
+ .incr(t, &count_row(0), CNT, b"", 1);
577
+ }
578
+
579
+ fn put_centroid(tx: &mut Transaction, t: &Table, list: u32, c: &Point) {
580
+ let row = centroid_row(list);
581
+ match c {
582
+ Point::F32(x) => tx.put_vector_f32(t, &row, CEN, b"", x),
583
+ Point::Bits(b) => tx.put_vector_bits(t, &row, CEN, b"", b),
584
+ };
585
+ }
586
+
587
+ /// The centroids at `s`.
588
+ /// The reads a search and a centroid load make, from the writer's table or a reader
589
+ /// process's (#1268 item 5, [`ReadIndex`]).
590
+ pub(crate) trait Rows: Sync {
591
+ /// `G:layout` at `s`.
592
+ fn layout_version(&self, s: &Snapshot) -> Result<u64>;
593
+ /// [`layout_version`](Self::layout_version), without blocking on the device.
594
+ #[cfg(feature = "async")]
595
+ fn layout_version_async(&self, s: &Snapshot) -> pigeonhole::nonblocking::GetFuture;
596
+ /// Every `C{list}` row's centroid and metadata.
597
+ fn centroids(&self) -> Scan<'_>;
598
+ /// The rows of `keys`.
599
+ fn rows_of<'t>(&'t self, keys: &KeySet) -> KeysRead<'t>;
600
+ }
601
+
602
+ impl Rows for Table {
603
+ fn layout_version(&self, s: &Snapshot) -> Result<u64> {
604
+ Ok(self
605
+ .get_at(s, GLOBAL, META, LAYOUT)?
606
+ .and_then(|c| c.as_u64())
607
+ .unwrap_or(0))
608
+ }
609
+ #[cfg(feature = "async")]
610
+ fn layout_version_async(&self, s: &Snapshot) -> pigeonhole::nonblocking::GetFuture {
611
+ self.get_at_async(s, GLOBAL, META, LAYOUT)
612
+ }
613
+ fn centroids(&self) -> Scan<'_> {
614
+ self.scan_prefix(b"C").families([CEN, META])
615
+ }
616
+ fn rows_of<'t>(&'t self, keys: &KeySet) -> KeysRead<'t> {
617
+ self.keys(keys)
618
+ }
619
+ }
620
+
621
+ impl Rows for ReadTable {
622
+ fn layout_version(&self, s: &Snapshot) -> Result<u64> {
623
+ Ok(self
624
+ .get_at(s, GLOBAL, META, LAYOUT)?
625
+ .and_then(|c| c.as_u64())
626
+ .unwrap_or(0))
627
+ }
628
+ #[cfg(feature = "async")]
629
+ fn layout_version_async(&self, s: &Snapshot) -> pigeonhole::nonblocking::GetFuture {
630
+ self.get_at_async(s, GLOBAL, META, LAYOUT)
631
+ }
632
+ fn centroids(&self) -> Scan<'_> {
633
+ self.scan_prefix(b"C").families([CEN, META])
634
+ }
635
+ fn rows_of<'t>(&'t self, keys: &KeySet) -> KeysRead<'t> {
636
+ self.keys(keys)
637
+ }
638
+ }
639
+
640
+ fn load(t: &impl Rows, cen: &VectorSpec, s: &Snapshot) -> Result<Layout> {
641
+ let version = t.layout_version(s)?;
642
+ let mut lists = Vec::new();
643
+ for row in t.centroids().snapshot(s).iter()? {
644
+ lists.push(list_of_row(&row?, cen)?);
645
+ }
646
+ Ok(Layout {
647
+ seqno: s.seqno(),
648
+ version,
649
+ lists,
650
+ })
651
+ }
652
+
653
+ /// The centroids at `s`, as [`load`] reads them, without blocking on the device.
654
+ #[cfg(feature = "async")]
655
+ async fn load_async(t: &impl Rows, cen: &VectorSpec, s: &Snapshot) -> Result<Layout> {
656
+ use futures_core::Stream;
657
+ let version = t
658
+ .layout_version_async(s)
659
+ .await?
660
+ .and_then(|c| c.as_u64())
661
+ .unwrap_or(0);
662
+ let mut rows = std::pin::pin!(t.centroids().snapshot(s).stream());
663
+ let mut lists = Vec::new();
664
+ while let Some(row) = std::future::poll_fn(|cx| rows.as_mut().poll_next(cx)).await {
665
+ lists.push(list_of_row(&row?, cen)?);
666
+ }
667
+ Ok(Layout {
668
+ seqno: s.seqno(),
669
+ version,
670
+ lists,
671
+ })
672
+ }
673
+
674
+ /// The layout at `s` for a search: the shared cache when `G:layout` still matches it, else
675
+ /// a fresh load, which replaces the cache when the search is at the current snapshot and the
676
+ /// cache is older (rev 3 S4).
677
+ fn layout_at(
678
+ t: &impl Rows,
679
+ cen: &VectorSpec,
680
+ cache: &RwLock<Arc<Layout>>,
681
+ s: &Snapshot,
682
+ current: Option<&dyn Fn() -> Option<u64>>,
683
+ ) -> Result<Arc<Layout>> {
684
+ let shared = cached(cache);
685
+ if t.layout_version(s)? == shared.version {
686
+ return Ok(shared);
687
+ }
688
+ Ok(adopt(cache, load(t, cen, s)?, current))
689
+ }
690
+
691
+ /// [`layout_at`], without blocking on the device.
692
+ #[cfg(feature = "async")]
693
+ async fn layout_at_async(
694
+ t: &impl Rows,
695
+ cen: &VectorSpec,
696
+ cache: &RwLock<Arc<Layout>>,
697
+ s: &Snapshot,
698
+ current: Option<&(dyn Fn() -> Option<u64> + Sync)>,
699
+ ) -> Result<Arc<Layout>> {
700
+ let shared = cached(cache);
701
+ let version = t
702
+ .layout_version_async(s)
703
+ .await?
704
+ .and_then(|c| c.as_u64())
705
+ .unwrap_or(0);
706
+ if version == shared.version {
707
+ return Ok(shared);
708
+ }
709
+ // Converted after the await: the future holds only the `Sync` reference across it.
710
+ let fresh = load_async(t, cen, s).await?;
711
+ Ok(adopt(
712
+ cache,
713
+ fresh,
714
+ current.map(|f| f as &dyn Fn() -> Option<u64>),
715
+ ))
716
+ }
717
+
718
+ fn cached(cache: &RwLock<Arc<Layout>>) -> Arc<Layout> {
719
+ Arc::clone(&cache.read().unwrap_or_else(PoisonError::into_inner))
720
+ }
721
+
722
+ /// A layout a search loaded replaces the shared cache when the search is at the current
723
+ /// snapshot (`latest` given: the latest visible seqno now) and the cache is older (rev 3
724
+ /// S4), so a slower search at an earlier snapshot never overwrites a newer layout. Or when
725
+ /// the cache is from **beyond** the latest visible seqno: commits the writer lost (a
726
+ /// restart after a power loss took a visible tail, perf287 on #1385). The cache then can't
727
+ /// be current, and without this every search would reload the centroids until the writer
728
+ /// passed the lost seqno again.
729
+ fn adopt(
730
+ cache: &RwLock<Arc<Layout>>,
731
+ fresh: Layout,
732
+ latest: Option<&dyn Fn() -> Option<u64>>,
733
+ ) -> Arc<Layout> {
734
+ let fresh = Arc::new(fresh);
735
+ if let Some(latest) = latest {
736
+ let mut w = cache.write().unwrap_or_else(PoisonError::into_inner);
737
+ if fresh.seqno >= w.seqno || latest().is_some_and(|now| w.seqno > now) {
738
+ *w = Arc::clone(&fresh);
739
+ }
740
+ }
741
+ fresh
742
+ }
743
+
744
+ /// One `C{list}` row's list.
745
+ fn list_of_row(row: &pigeonhole::Row, cen: &VectorSpec) -> Result<List> {
746
+ let id = list_of(row.key()).ok_or_else(|| corrupt("a centroid row key"))?;
747
+ let v = row
748
+ .get(CEN, b"")
749
+ .and_then(|c| c.as_vector())
750
+ .ok_or_else(|| corrupt("a list has no centroid"))?;
751
+ let point = Point::of(v);
752
+ let version = row
753
+ .get(META, VERSION)
754
+ .and_then(|c| c.as_u64())
755
+ .ok_or_else(|| corrupt("a list has no version"))?;
756
+ Ok(List {
757
+ id,
758
+ version,
759
+ centroid: point.to_vector(cen.dim())?,
760
+ point,
761
+ })
762
+ }
763
+
764
+ /// `k` centroids of `points` by Lloyd's k-means (D306 §5), seeded deterministically with
765
+ /// evenly spaced points; a cluster that empties keeps its centroid.
766
+ fn kmeans(cen: &VectorSpec, points: &[Point], k: usize) -> Result<Vec<Point>> {
767
+ let metric = cen.metric();
768
+ let dim = cen.dim();
769
+ let mut centroids: Vec<Point> = (0..k)
770
+ .map(|i| crate::point::unit(metric, points[i * points.len() / k].clone()))
771
+ .collect();
772
+ let mut owner = vec![0usize; points.len()];
773
+ for _ in 0..KMEANS_ITERATIONS {
774
+ let vectors = centroids
775
+ .iter()
776
+ .map(|c| c.to_vector(dim))
777
+ .collect::<Result<Vec<_>>>()?;
778
+ let mut changed = false;
779
+ for (p, o) in points.iter().zip(owner.iter_mut()) {
780
+ let mut best = (f64::INFINITY, 0);
781
+ for (j, c) in vectors.iter().enumerate() {
782
+ let d = distance(cen, p, c)?;
783
+ if d < best.0 {
784
+ best = (d, j);
785
+ }
786
+ }
787
+ changed |= *o != best.1;
788
+ *o = best.1;
789
+ }
790
+ for (j, c) in centroids.iter_mut().enumerate() {
791
+ let members = points
792
+ .iter()
793
+ .zip(&owner)
794
+ .filter(|(_, o)| **o == j)
795
+ .map(|(p, _)| p);
796
+ if let Some(m) = crate::point::mean(metric, members) {
797
+ *c = m;
798
+ }
799
+ }
800
+ if !changed {
801
+ break;
802
+ }
803
+ }
804
+ Ok(centroids)
805
+ }
806
+
807
+ /// Removes its list from the in-flight set when the split or merge ends, however it ends.
808
+ struct Claim<'a> {
809
+ set: &'a Mutex<HashSet<u32>>,
810
+ list: u32,
811
+ }
812
+
813
+ impl Drop for Claim<'_> {
814
+ fn drop(&mut self) {
815
+ self.set
816
+ .lock()
817
+ .unwrap_or_else(PoisonError::into_inner)
818
+ .remove(&self.list);
819
+ }
820
+ }
821
+
822
+ impl Index {
823
+ /// Creates the index `name`, a new table, for vectors of `spec`, and opens it as
824
+ /// [`open`](Self::open) does.
825
+ ///
826
+ /// The table holds the index's rows only; don't write to it directly. Fails with
827
+ /// `TableExists` if a table of that name exists.
828
+ pub fn create(
829
+ db: &Pigeonhole,
830
+ name: &str,
831
+ spec: VectorSpec,
832
+ options: IndexOptions,
833
+ ) -> Result<Index> {
834
+ Self::create_table(db, name, spec, options)?;
835
+ Self::open(db, name)
836
+ }
837
+
838
+ /// [`create`](Self::create), opened as
839
+ /// [`open_with_rebalancer`](Self::open_with_rebalancer) is.
840
+ pub fn create_with_rebalancer(
841
+ db: &Pigeonhole,
842
+ name: &str,
843
+ spec: VectorSpec,
844
+ options: IndexOptions,
845
+ ) -> Result<(Index, Rebalancer)> {
846
+ Self::create_table(db, name, spec, options)?;
847
+ Self::open_with_rebalancer(db, name)
848
+ }
849
+
850
+ fn create_table(
851
+ db: &Pigeonhole,
852
+ name: &str,
853
+ spec: VectorSpec,
854
+ options: IndexOptions,
855
+ ) -> Result<()> {
856
+ let opts = options.checked(&spec)?;
857
+ let cen = centroid_spec(&spec)?;
858
+ let table = db
859
+ .table(name)?
860
+ .family(VEC, Family::vector(spec).max_versions(1))
861
+ .family(CEN, Family::vector(cen).max_versions(1))
862
+ .family(META, Family::default().max_versions(1))
863
+ .family(MAP, Family::default().max_versions(1))
864
+ .family(CNT, Family::counter())
865
+ .create()?;
866
+ table
867
+ .mutate(GLOBAL)
868
+ .put(META, OPTS, &opts.encode())
869
+ .put_u64(META, LAYOUT, 0)
870
+ .put_u64(META, NEXT, 0)
871
+ .commit()?;
872
+ Ok(())
873
+ }
874
+
875
+ /// Opens the index `name`. Lists a crash left outside their bounds (a write committed,
876
+ /// and its split or merge never ran) are queued, and the next insert or delete
877
+ /// rebalances them, or with [`Rebalance::Background`] the crate's rebalancing thread
878
+ /// does: it starts here, and stops when the last handle to this index drops. An
879
+ /// application that runs its own threads opens with
880
+ /// [`open_with_rebalancer`](Self::open_with_rebalancer) instead: in an
881
+ /// application-owned database (D284) the crate shouldn't start threads of its own.
882
+ ///
883
+ /// An index already open in this process (an application handle to it still alive) is
884
+ /// not opened again: `open` returns a clone of that handle, sharing its centroid cache,
885
+ /// its queue of lists to rebalance and its one rebalancing thread (#1268 item 8). "The
886
+ /// same index" is the same table name in the same open database
887
+ /// ([`Pigeonhole::same_database`]), and a table that was dropped since (and perhaps
888
+ /// created again) is opened afresh.
889
+ ///
890
+ /// The rebalancing thread holds the index, and with it a database handle, until it sees
891
+ /// the last [`Index`] handle drop, at most one split later. To reopen the database in
892
+ /// the same process, [`close`](Pigeonhole::close) it first: a closed database refuses
893
+ /// the thread's next write, and the thread ends.
894
+ pub fn open(db: &Pigeonhole, name: &str) -> Result<Index> {
895
+ let index = Self::registered(db, name)?;
896
+ if index.inner.opts.rebalance == Rebalance::Background
897
+ && !index.inner.thread.swap(true, Ordering::AcqRel)
898
+ {
899
+ let started =
900
+ crate::rebalancer::spawn(Rebalancer::new(&index, Arc::clone(&index.inner.signal)));
901
+ if let Err(e) = started {
902
+ // A later open tries again.
903
+ index.inner.thread.store(false, Ordering::Release);
904
+ return Err(Error::InvalidArgument(format!(
905
+ "starting the rebalancer: {e}"
906
+ )));
907
+ }
908
+ }
909
+ Ok(index)
910
+ }
911
+
912
+ /// Opens the index `name` with its [`Rebalancer`] handed to the caller, and no thread of
913
+ /// the crate's own: for an application that runs its threads itself (an
914
+ /// application-owned database, D284). With [`Rebalance::Background`] the application
915
+ /// runs the rebalancer; with [`Rebalance::Inline`] the writes rebalance, and the
916
+ /// rebalancer only finds what `open` queued.
917
+ ///
918
+ /// As with [`open`](Self::open), an index already open in this process shares its state:
919
+ /// the handle is a clone of the open one, and the rebalancer takes from the same queue as
920
+ /// any other (each list is split or merged by one of them at a time). They share one
921
+ /// [`set_wakeup`](Rebalancer::set_wakeup): the last one set is called. A later
922
+ /// [`open`](Self::open) of the index in background mode starts the crate's thread too,
923
+ /// which takes from the same queue: in an application-owned database, open with this
924
+ /// function only.
925
+ pub fn open_with_rebalancer(db: &Pigeonhole, name: &str) -> Result<(Index, Rebalancer)> {
926
+ let index = Self::registered(db, name)?;
927
+ let rebalancer = Rebalancer::new(&index, Arc::clone(&index.inner.signal));
928
+ Ok((index, rebalancer))
929
+ }
930
+
931
+ /// Opens the index `name` from a reader process ([`PigeonholeReader`], #1268 item 5): a
932
+ /// [`ReadIndex`] that searches, at the reader's snapshots, and never writes. The
933
+ /// centroids load with reads only; the writer process inserts, deletes and rebalances.
934
+ /// The same checks as [`open`](Self::open) refuse a table that isn't a vector index.
935
+ pub fn open_reader(reader: &PigeonholeReader, name: &str) -> Result<ReadIndex> {
936
+ let table = reader.table(name)?;
937
+ let not = |why: &str| {
938
+ Error::InvalidArgument(format!("table {name:?} is not a vector index: {why}"))
939
+ };
940
+ let spec = table
941
+ .family_info(VEC)
942
+ .and_then(|f| f.vector)
943
+ .ok_or_else(|| not("it has no vector family `vec`"))?;
944
+ let cen = centroid_spec(&spec)?;
945
+ if table.family_info(CEN).and_then(|f| f.vector) != Some(cen) {
946
+ return Err(not("its centroid family doesn't match"));
947
+ }
948
+ let opts = table
949
+ .get(GLOBAL, META, OPTS)?
950
+ .and_then(|c| IndexOptions::decode(c.value()))
951
+ .ok_or_else(|| not("it has no options"))?;
952
+ let s = reader.snapshot()?;
953
+ let layout = load(&table, &cen, &s)?;
954
+ Ok(ReadIndex {
955
+ inner: Arc::new(ReadInner {
956
+ db: reader.clone(),
957
+ table,
958
+ spec,
959
+ cen,
960
+ opts,
961
+ layout: RwLock::new(Arc::new(layout)),
962
+ }),
963
+ })
964
+ }
965
+
966
+ /// A rebalancer's temporary handle: not one of the application's.
967
+ pub(crate) fn from_inner(inner: Arc<Inner>) -> Self {
968
+ Index {
969
+ inner,
970
+ user: Arc::new(()),
971
+ }
972
+ }
973
+
974
+ pub(crate) fn inner(&self) -> &Arc<Inner> {
975
+ &self.inner
976
+ }
977
+
978
+ pub(crate) fn user(&self) -> &Arc<()> {
979
+ &self.user
980
+ }
981
+
982
+ /// The index from this process's registry, or opened and registered (#1268 item 8).
983
+ fn registered(db: &Pigeonhole, name: &str) -> Result<Index> {
984
+ let (inner, user) = crate::registry::open(db, name, || {
985
+ let index = Self::open_inner(db, name)?;
986
+ Ok((index.inner, index.user))
987
+ })?;
988
+ Ok(Index { inner, user })
989
+ }
990
+
991
+ fn open_inner(db: &Pigeonhole, name: &str) -> Result<Index> {
992
+ let table = db.table(name)?.open()?;
993
+ let not = |why: &str| {
994
+ Error::InvalidArgument(format!("table {name:?} is not a vector index: {why}"))
995
+ };
996
+ let spec = table
997
+ .family_info(VEC)
998
+ .and_then(|f| f.vector)
999
+ .ok_or_else(|| not("it has no vector family `vec`"))?;
1000
+ let cen = centroid_spec(&spec)?;
1001
+ if table.family_info(CEN).and_then(|f| f.vector) != Some(cen) {
1002
+ return Err(not("its centroid family doesn't match"));
1003
+ }
1004
+ let opts = table
1005
+ .get(GLOBAL, META, OPTS)?
1006
+ .and_then(|c| IndexOptions::decode(c.value()))
1007
+ .ok_or_else(|| not("it has no options"))?;
1008
+ let s = db.snapshot()?;
1009
+ let layout = load(&table, &cen, &s)?;
1010
+ let index = Index {
1011
+ user: Arc::new(()),
1012
+ inner: Arc::new(Inner {
1013
+ db: db.clone(),
1014
+ table,
1015
+ spec,
1016
+ cen,
1017
+ opts,
1018
+ layout: RwLock::new(Arc::new(layout)),
1019
+ in_flight: Mutex::new(HashSet::new()),
1020
+ pending: Mutex::new(VecDeque::new()),
1021
+ signal: Arc::new(Signal::default()),
1022
+ thread: AtomicBool::new(false),
1023
+ }),
1024
+ };
1025
+ index.queue_out_of_bounds(&s)?;
1026
+ Ok(index)
1027
+ }
1028
+
1029
+ /// The vectors' spec.
1030
+ pub fn spec(&self) -> VectorSpec {
1031
+ self.inner.spec
1032
+ }
1033
+
1034
+ /// The options it was created with (the target list length as scaled).
1035
+ pub fn options(&self) -> IndexOptions {
1036
+ self.inner.opts
1037
+ }
1038
+
1039
+ /// A list splits when it holds more than this many vectors.
1040
+ pub fn max_list_len(&self) -> u64 {
1041
+ 2 * u64::from(self.inner.opts.target)
1042
+ }
1043
+
1044
+ /// A list merges into its nearest neighbour when it holds fewer than this many
1045
+ /// vectors, unless it is the only list.
1046
+ pub fn min_list_len(&self) -> u64 {
1047
+ u64::from(self.inner.opts.target) / 4
1048
+ }
1049
+
1050
+ /// Inserts the `f32` vector `vector` as `id`, or replaces `id`'s vector (an upsert).
1051
+ /// One transaction, retried on conflicts; a list that grows past its bound is split
1052
+ /// before the call returns. An error after the commit (from that split) leaves the
1053
+ /// insert committed, and retrying it is safe.
1054
+ pub fn insert_f32(&self, id: &[u8], vector: &[f32]) -> Result<()> {
1055
+ self.insert(id, Input::F32(vector))
1056
+ }
1057
+
1058
+ /// [`insert_f32`](Self::insert_f32) for an `i8` index.
1059
+ pub fn insert_i8(&self, id: &[u8], vector: &[i8]) -> Result<()> {
1060
+ self.insert(id, Input::I8(vector))
1061
+ }
1062
+
1063
+ /// [`insert_f32`](Self::insert_f32) for a bit index (bits packed eight to a byte, least
1064
+ /// significant first).
1065
+ pub fn insert_bits(&self, id: &[u8], vector: &[u8]) -> Result<()> {
1066
+ self.insert(id, Input::Bits(vector))
1067
+ }
1068
+
1069
+ /// [`insert_f32`](Self::insert_f32) for an `f16` index: `vector` is IEEE binary16 bit
1070
+ /// patterns, stored bit for bit (#1268 item 7). An `f16` or `bf16` index also takes
1071
+ /// [`insert_f32`](Self::insert_f32), rounding each component to the element.
1072
+ pub fn insert_f16(&self, id: &[u8], vector: &[u16]) -> Result<()> {
1073
+ self.insert(id, Input::F16(vector))
1074
+ }
1075
+
1076
+ /// [`insert_f16`](Self::insert_f16) for a `bf16` index (bfloat16 bit patterns).
1077
+ pub fn insert_bf16(&self, id: &[u8], vector: &[u16]) -> Result<()> {
1078
+ self.insert(id, Input::BF16(vector))
1079
+ }
1080
+
1081
+ /// Deletes `id`'s vector; `false` if there was none. A list that shrinks below its
1082
+ /// bound is merged into its nearest neighbour before the call returns.
1083
+ pub fn delete(&self, id: &[u8]) -> Result<bool> {
1084
+ let inn = &*self.inner;
1085
+ let t = &inn.table;
1086
+ for attempt in 0..RELOADS {
1087
+ let r = inn.db.transact(&RetryPolicy::default(), |tx| {
1088
+ let Some(l) = read_list_of(tx, t, id)? else {
1089
+ return Ok(None);
1090
+ };
1091
+ // A mapping to a list with no centroid can only be seen mid-merge: retry.
1092
+ if read_version(tx, t, l)?.is_none() {
1093
+ return Err(Tx::Stale);
1094
+ }
1095
+ #[cfg(feature = "__unstable-hooks")]
1096
+ crate::hooks::hold(crate::hooks::Hold::DeleteBeforeCommit);
1097
+ tx.delete_column(t, &list_row(l), VEC, id)
1098
+ .delete_column(t, &map_row(id), MAP, LIST)
1099
+ .incr(t, &count_row(l), CNT, b"", -1);
1100
+ Ok(Some(l))
1101
+ });
1102
+ match r {
1103
+ Ok((None, _)) => return Ok(false),
1104
+ Ok((Some(l), _)) => {
1105
+ self.after_write([l])?;
1106
+ return Ok(true);
1107
+ }
1108
+ // Only a merge in flight shows a mapping to a list with no centroid: back off
1109
+ // (capped, as `RetryPolicy`'s pauses) rather than spin against it (#1268).
1110
+ Err(Tx::Stale) => std::thread::sleep(backoff(attempt)),
1111
+ Err(e) => return Err(e.into()),
1112
+ }
1113
+ }
1114
+ Err(Error::Conflict(
1115
+ "a delete kept finding its list mid-merge".into(),
1116
+ ))
1117
+ }
1118
+
1119
+ /// [`insert_f32`](Self::insert_f32) inside the caller's transaction `tx`, so the vector
1120
+ /// commits or rolls back with the caller's other writes (D311 T8). `placed` records the
1121
+ /// transaction's writes to this index: one [`Placed`] per transaction, passed to every
1122
+ /// `*_in` write of it, so writing an id twice in one transaction acts on the first write
1123
+ /// (a transaction's reads don't see its own writes). It neither retries nor splits:
1124
+ /// pass `placed` to [`after_commit`](Self::after_commit) once `tx` commits, so a list
1125
+ /// that grew past its bound is split (or, with [`Rebalance::Background`], marked for
1126
+ /// the rebalancer).
1127
+ ///
1128
+ /// ```
1129
+ /// use pigeonhole::{Element, Family, Metric, Options, Pigeonhole, RetryPolicy, VectorSpec};
1130
+ /// use pigeonhole_vector::{Index, IndexOptions, Placed};
1131
+ ///
1132
+ /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
1133
+ /// # let dir = pigeonhole::doc_support::temp_dir();
1134
+ /// let db = Pigeonhole::open(dir.join("app.phdb"), Options::default())?;
1135
+ /// let spec = VectorSpec::new(2, Element::F32, Metric::L2)?;
1136
+ /// let index = Index::create(&db, "points", spec, IndexOptions::new())?;
1137
+ /// let docs = db.table("docs")?.family("f", Family::default()).create_if_missing()?;
1138
+ /// let (placed, _) = db.transact(&RetryPolicy::default(), |tx| {
1139
+ /// let mut placed = Placed::new();
1140
+ /// tx.put(&docs, b"d1", "f", b"", b"text");
1141
+ /// index.insert_f32_in(tx, &mut placed, b"d1", &[1.0, 2.0])?;
1142
+ /// index.insert_f32_in(tx, &mut placed, b"d1", &[3.0, 4.0])?; // an upsert of it
1143
+ /// Ok::<_, pigeonhole_vector::Error>(placed)
1144
+ /// })?;
1145
+ /// index.after_commit(placed)?;
1146
+ /// assert_eq!(index.verify()?.vectors, 1);
1147
+ /// # db.close()?;
1148
+ /// # Ok(())
1149
+ /// # }
1150
+ /// ```
1151
+ ///
1152
+ /// It places against the centroids the index has cached, reloaded once if the list's
1153
+ /// version read in `tx` differs. If it still differs, `tx`'s snapshot predates a split
1154
+ /// or a merge: the vector is written anyway, and the commit fails with `Conflict`
1155
+ /// (retried by [`Pigeonhole::transact`](pigeonhole::Pigeonhole::transact)), because the
1156
+ /// version `tx` read has been rewritten since. A snapshot showing `id` mapped to a list
1157
+ /// with no centroid is [`Error::Corruption`], as [`verify`](Self::verify) reports it: a
1158
+ /// merge is one transaction, so no consistent snapshot shows that.
1159
+ pub fn insert_f32_in(
1160
+ &self,
1161
+ tx: &mut Transaction,
1162
+ placed: &mut Placed,
1163
+ id: &[u8],
1164
+ vector: &[f32],
1165
+ ) -> Result<()> {
1166
+ self.insert_in(tx, placed, id, Input::F32(vector))
1167
+ }
1168
+
1169
+ /// [`insert_f32_in`](Self::insert_f32_in) for an `i8` index.
1170
+ pub fn insert_i8_in(
1171
+ &self,
1172
+ tx: &mut Transaction,
1173
+ placed: &mut Placed,
1174
+ id: &[u8],
1175
+ vector: &[i8],
1176
+ ) -> Result<()> {
1177
+ self.insert_in(tx, placed, id, Input::I8(vector))
1178
+ }
1179
+
1180
+ /// [`insert_f32_in`](Self::insert_f32_in) for a bit index.
1181
+ pub fn insert_bits_in(
1182
+ &self,
1183
+ tx: &mut Transaction,
1184
+ placed: &mut Placed,
1185
+ id: &[u8],
1186
+ vector: &[u8],
1187
+ ) -> Result<()> {
1188
+ self.insert_in(tx, placed, id, Input::Bits(vector))
1189
+ }
1190
+
1191
+ /// [`insert_f32_in`](Self::insert_f32_in) for an `f16` index (bit patterns).
1192
+ pub fn insert_f16_in(
1193
+ &self,
1194
+ tx: &mut Transaction,
1195
+ placed: &mut Placed,
1196
+ id: &[u8],
1197
+ vector: &[u16],
1198
+ ) -> Result<()> {
1199
+ self.insert_in(tx, placed, id, Input::F16(vector))
1200
+ }
1201
+
1202
+ /// [`insert_f32_in`](Self::insert_f32_in) for a `bf16` index (bit patterns).
1203
+ pub fn insert_bf16_in(
1204
+ &self,
1205
+ tx: &mut Transaction,
1206
+ placed: &mut Placed,
1207
+ id: &[u8],
1208
+ vector: &[u16],
1209
+ ) -> Result<()> {
1210
+ self.insert_in(tx, placed, id, Input::BF16(vector))
1211
+ }
1212
+
1213
+ /// [`delete`](Self::delete) inside the caller's transaction `tx`, recorded in `placed`
1214
+ /// as [`insert_f32_in`](Self::insert_f32_in) records: `false` (and nothing written)
1215
+ /// when there's no vector for `id`, as of this transaction's own earlier writes, else
1216
+ /// as of its snapshot. Pass `placed` to [`after_commit`](Self::after_commit) once `tx`
1217
+ /// commits, so a list that shrank below its bound is merged.
1218
+ pub fn delete_in(&self, tx: &mut Transaction, placed: &mut Placed, id: &[u8]) -> Result<bool> {
1219
+ placed.bind(self)?;
1220
+ let t = &self.inner.table;
1221
+ let l = match placed.ids.get(id).copied() {
1222
+ Some(Some(l)) => l,
1223
+ Some(None) => return Ok(false),
1224
+ None => {
1225
+ let Some(l) = read_list_of(tx, t, id)? else {
1226
+ return Ok(false);
1227
+ };
1228
+ if read_version(tx, t, l)?.is_none() {
1229
+ return Err(unmapped());
1230
+ }
1231
+ l
1232
+ }
1233
+ };
1234
+ tx.delete_column(t, &list_row(l), VEC, id)
1235
+ .delete_column(t, &map_row(id), MAP, LIST)
1236
+ .incr(t, &count_row(l), CNT, b"", -1);
1237
+ placed.wrote(id, None, [l]);
1238
+ Ok(true)
1239
+ }
1240
+
1241
+ /// After the transaction `placed` recorded has committed: splits or merges the lists
1242
+ /// its writes left out of bounds, as [`insert_f32`](Self::insert_f32) and
1243
+ /// [`delete`](Self::delete) do after theirs. It reads the lists' current lengths, so
1244
+ /// calling it after a rollback, twice, or late is harmless, and never calling it only
1245
+ /// delays a rebalance until the next write to those lists. A `Placed` of another index is
1246
+ /// [`Error::InvalidArgument`].
1247
+ pub fn after_commit(&self, mut placed: Placed) -> Result<()> {
1248
+ placed.bind(self)?;
1249
+ self.after_write(placed.lists)
1250
+ }
1251
+
1252
+ /// The `k` vectors nearest the `f32` vector `query`, as a [`Search`] to run.
1253
+ pub fn search_f32<'a>(&'a self, query: &'a [f32], k: usize) -> Search<'a> {
1254
+ Search::new(Of::W(self), Input::F32(query), k)
1255
+ }
1256
+
1257
+ /// [`search_f32`](Self::search_f32) for an `i8` index.
1258
+ pub fn search_i8<'a>(&'a self, query: &'a [i8], k: usize) -> Search<'a> {
1259
+ Search::new(Of::W(self), Input::I8(query), k)
1260
+ }
1261
+
1262
+ /// [`search_f32`](Self::search_f32) for a bit index.
1263
+ pub fn search_bits<'a>(&'a self, query: &'a [u8], k: usize) -> Search<'a> {
1264
+ Search::new(Of::W(self), Input::Bits(query), k)
1265
+ }
1266
+
1267
+ /// [`search_f32`](Self::search_f32) with an `f16` query (bit patterns), for an `f16`
1268
+ /// index. The query widens to `f32` exactly, and the search compares in `f32`, as
1269
+ /// `nearest_f32` does over a half family; [`search_f32`](Self::search_f32) works too.
1270
+ pub fn search_f16<'a>(&'a self, query: &'a [u16], k: usize) -> Search<'a> {
1271
+ Search::new(Of::W(self), Input::F16(query), k)
1272
+ }
1273
+
1274
+ /// [`search_f16`](Self::search_f16) for a `bf16` index (a bfloat16 query).
1275
+ pub fn search_bf16<'a>(&'a self, query: &'a [u16], k: usize) -> Search<'a> {
1276
+ Search::new(Of::W(self), Input::BF16(query), k)
1277
+ }
1278
+
1279
+ /// Loads many vectors into an **empty** index faster than inserting them one by one: it
1280
+ /// clusters the first 50,000 vectors (or more if `expected` needs more lists) with
1281
+ /// k-means into about `expected / target` lists, writes those centroids, then streams
1282
+ /// every vector to its nearest list, a list's vectors written a batch per transaction.
1283
+ /// Lists left out of bounds are then split or merged as the index rebalances
1284
+ /// ([`Rebalance`]).
1285
+ ///
1286
+ /// `expected` is about how many vectors you're about to load. It only chooses how many
1287
+ /// lists k-means starts with (`expected / target`, at least one); a wrong estimate costs
1288
+ /// time, not correctness, since the lists then split or merge to their bounds after the
1289
+ /// load. The sample is the input's first vectors, so shuffle an input that is sorted by
1290
+ /// cluster. A repeated id keeps its last vector, and [`BulkStats::vectors`] counts every
1291
+ /// occurrence.
1292
+ ///
1293
+ /// Fails with `InvalidArgument` if the index already holds a list, or on the first
1294
+ /// vector of another shape; the vectors before that are loaded.
1295
+ pub fn bulk_load_f32<K, V>(
1296
+ &self,
1297
+ expected: u64,
1298
+ vectors: impl IntoIterator<Item = (K, V)>,
1299
+ ) -> Result<BulkStats>
1300
+ where
1301
+ K: AsRef<[u8]>,
1302
+ V: AsRef<[f32]>,
1303
+ {
1304
+ self.bulk(expected, vectors, |v: &V| Input::F32(v.as_ref()))
1305
+ }
1306
+
1307
+ /// [`bulk_load_f32`](Self::bulk_load_f32) for an `i8` index.
1308
+ pub fn bulk_load_i8<K, V>(
1309
+ &self,
1310
+ expected: u64,
1311
+ vectors: impl IntoIterator<Item = (K, V)>,
1312
+ ) -> Result<BulkStats>
1313
+ where
1314
+ K: AsRef<[u8]>,
1315
+ V: AsRef<[i8]>,
1316
+ {
1317
+ self.bulk(expected, vectors, |v: &V| Input::I8(v.as_ref()))
1318
+ }
1319
+
1320
+ /// [`bulk_load_f32`](Self::bulk_load_f32) for a bit index.
1321
+ pub fn bulk_load_bits<K, V>(
1322
+ &self,
1323
+ expected: u64,
1324
+ vectors: impl IntoIterator<Item = (K, V)>,
1325
+ ) -> Result<BulkStats>
1326
+ where
1327
+ K: AsRef<[u8]>,
1328
+ V: AsRef<[u8]>,
1329
+ {
1330
+ self.bulk(expected, vectors, |v: &V| Input::Bits(v.as_ref()))
1331
+ }
1332
+
1333
+ /// [`bulk_load_f32`](Self::bulk_load_f32) for an `f16` index: each vector is IEEE
1334
+ /// binary16 bit patterns, stored bit for bit, as [`insert_f16`](Self::insert_f16)
1335
+ /// stores them. ([`bulk_load_f32`](Self::bulk_load_f32) also loads a half index,
1336
+ /// rounding each component to the element.)
1337
+ pub fn bulk_load_f16<K, V>(
1338
+ &self,
1339
+ expected: u64,
1340
+ vectors: impl IntoIterator<Item = (K, V)>,
1341
+ ) -> Result<BulkStats>
1342
+ where
1343
+ K: AsRef<[u8]>,
1344
+ V: AsRef<[u16]>,
1345
+ {
1346
+ self.bulk(expected, vectors, |v: &V| Input::F16(v.as_ref()))
1347
+ }
1348
+
1349
+ /// [`bulk_load_f16`](Self::bulk_load_f16) for a `bf16` index (bfloat16 bit patterns).
1350
+ pub fn bulk_load_bf16<K, V>(
1351
+ &self,
1352
+ expected: u64,
1353
+ vectors: impl IntoIterator<Item = (K, V)>,
1354
+ ) -> Result<BulkStats>
1355
+ where
1356
+ K: AsRef<[u8]>,
1357
+ V: AsRef<[u16]>,
1358
+ {
1359
+ self.bulk(expected, vectors, |v: &V| Input::BF16(v.as_ref()))
1360
+ }
1361
+
1362
+ fn bulk<K: AsRef<[u8]>, V>(
1363
+ &self,
1364
+ expected: u64,
1365
+ vectors: impl IntoIterator<Item = (K, V)>,
1366
+ input: for<'v> fn(&'v V) -> Input<'v>,
1367
+ ) -> Result<BulkStats> {
1368
+ let inn = &*self.inner;
1369
+ let t = &inn.table;
1370
+ let empty = || Error::InvalidArgument("bulk_load needs an empty index".into());
1371
+ if t.get(GLOBAL, META, NEXT)?.and_then(|c| c.as_u64()) != Some(0) {
1372
+ return Err(empty());
1373
+ }
1374
+ let target = u64::from(inn.opts.target);
1375
+ let want = usize::try_from(expected.div_ceil(target).max(1)).unwrap_or(usize::MAX);
1376
+ let mut it = vectors.into_iter();
1377
+ let sample: Vec<(K, V)> = it.by_ref().take(BULK_SAMPLE.max(want)).collect();
1378
+ if sample.is_empty() {
1379
+ return Ok(BulkStats {
1380
+ vectors: 0,
1381
+ lists: 0,
1382
+ });
1383
+ }
1384
+ let mut points = Vec::with_capacity(sample.len());
1385
+ for (_, v) in &sample {
1386
+ let v = input(v);
1387
+ v.check(&inn.spec)?;
1388
+ points.push(v.placed(&inn.spec));
1389
+ }
1390
+ let centroids = kmeans(&inn.cen, &points, want.min(sample.len()))?;
1391
+ drop(points);
1392
+ let lists = u32::try_from(centroids.len()).map_err(|_| corrupt("too many lists"))?;
1393
+ inn.db.transact(&RetryPolicy::default(), |tx| {
1394
+ if read_u64(tx, t, GLOBAL, META, NEXT)? != Some(0) {
1395
+ return Err(Tx::Fail(empty()));
1396
+ }
1397
+ for (i, c) in (0u32..).zip(&centroids) {
1398
+ put_centroid(tx, t, i, c);
1399
+ tx.put_u64(t, &centroid_row(i), META, VERSION, 1);
1400
+ }
1401
+ tx.put_u64(t, GLOBAL, META, NEXT, u64::from(lists))
1402
+ .put_u64(t, GLOBAL, META, LAYOUT, 1);
1403
+ Ok(())
1404
+ })?;
1405
+ let layout = self.reload()?;
1406
+ // Each list's unwritten batch, and which batch holds an id (a repeat replaces it).
1407
+ let mut batches: HashMap<u32, Vec<(K, V)>> = HashMap::new();
1408
+ let mut waiting: HashMap<Vec<u8>, u32> = HashMap::new();
1409
+ let mut loaded = 0u64;
1410
+ // One point, refilled per vector: a half or `i8` vector widens into its buffer.
1411
+ let mut point = Point::F32(Vec::new());
1412
+ for (id, v) in sample.into_iter().chain(it) {
1413
+ let vi = input(&v);
1414
+ vi.check(&inn.spec)?;
1415
+ vi.placed_into(&inn.spec, &mut point);
1416
+ let l = layout.nearest(&inn.cen, &point, 1, &[])?[0];
1417
+ if let Some(prev) = waiting.insert(id.as_ref().to_vec(), l) {
1418
+ let b = batches.get_mut(&prev).expect("a waiting id's batch");
1419
+ b.retain(|(k, _)| k.as_ref() != id.as_ref());
1420
+ }
1421
+ let batch = batches.entry(l).or_default();
1422
+ batch.push((id, v));
1423
+ loaded += 1;
1424
+ if batch.len() >= BULK_BATCH {
1425
+ let full = std::mem::take(batch);
1426
+ for (k, _) in &full {
1427
+ waiting.remove(k.as_ref());
1428
+ }
1429
+ self.write_batch(l, &full, input)?;
1430
+ }
1431
+ }
1432
+ for (l, batch) in batches {
1433
+ if !batch.is_empty() {
1434
+ self.write_batch(l, &batch, input)?;
1435
+ }
1436
+ }
1437
+ let all: Vec<u32> = layout.lists.iter().map(|l| l.id).collect();
1438
+ match inn.opts.rebalance {
1439
+ Rebalance::Inline => {
1440
+ self.queue(all);
1441
+ while self.maintain_one()?.is_some() {}
1442
+ }
1443
+ _ => self.after_write(all)?,
1444
+ }
1445
+ Ok(BulkStats {
1446
+ vectors: loaded,
1447
+ lists,
1448
+ })
1449
+ }
1450
+
1451
+ /// One transaction writing `batch` into list `l`, each vector as an upsert would.
1452
+ fn write_batch<K: AsRef<[u8]>, V>(
1453
+ &self,
1454
+ l: u32,
1455
+ batch: &[(K, V)],
1456
+ input: for<'v> fn(&'v V) -> Input<'v>,
1457
+ ) -> Result<()> {
1458
+ let inn = &*self.inner;
1459
+ let t = &inn.table;
1460
+ let row = list_row(l);
1461
+ inn.db.transact(&RetryPolicy::default(), |tx| {
1462
+ if read_version(tx, t, l)?.is_none() {
1463
+ return Err(Tx::Fail(Error::Conflict(
1464
+ "a list merged away during a bulk load".into(),
1465
+ )));
1466
+ }
1467
+ let mut added = 0i64;
1468
+ for (id, v) in batch {
1469
+ let id = id.as_ref();
1470
+ let old = read_list_of(tx, t, id)?;
1471
+ match old {
1472
+ Some(o) if o == l => input(v).put(tx, t, &row, id),
1473
+ Some(o) => {
1474
+ tx.delete_column(t, &list_row(o), VEC, id)
1475
+ .incr(t, &count_row(o), CNT, b"", -1)
1476
+ .put_u64(t, &map_row(id), MAP, LIST, u64::from(l));
1477
+ input(v).put(tx, t, &row, id);
1478
+ added += 1;
1479
+ }
1480
+ None => {
1481
+ tx.put_u64(t, &map_row(id), MAP, LIST, u64::from(l));
1482
+ input(v).put(tx, t, &row, id);
1483
+ added += 1;
1484
+ }
1485
+ }
1486
+ }
1487
+ tx.incr(t, &count_row(l), CNT, b"", added);
1488
+ Ok(())
1489
+ })?;
1490
+ Ok(())
1491
+ }
1492
+
1493
+ /// Checks the index's rows against each other at one snapshot: every id in exactly one
1494
+ /// list, its mapping naming that list, every list with a centroid, and every list's
1495
+ /// length counter equal to its vectors. Reads the whole index; for tests and repair
1496
+ /// tooling. A contradiction is `Corruption`.
1497
+ pub fn verify(&self) -> Result<IndexStats> {
1498
+ let inn = &*self.inner;
1499
+ let t = &inn.table;
1500
+ let s = inn.db.snapshot()?;
1501
+ let layout = load(t, &inn.cen, &s)?;
1502
+ let by_row: HashMap<u32, u32> = layout
1503
+ .lists
1504
+ .iter()
1505
+ .map(|l| (scramble(l.id), l.id))
1506
+ .collect();
1507
+ let mut lens: HashMap<u32, u64> = layout.lists.iter().map(|l| (l.id, 0)).collect();
1508
+ let mut home: HashMap<Vec<u8>, u32> = HashMap::new();
1509
+ let mut cells = t.scan_prefix(b"L").family(VEC).snapshot(&s).cells()?;
1510
+ while let Some((row, e)) = cells.next()? {
1511
+ let list = list_of(row)
1512
+ .and_then(|r| by_row.get(&r))
1513
+ .copied()
1514
+ .ok_or_else(|| corrupt("vectors in a list with no centroid"))?;
1515
+ if home.insert(e.qualifier.to_vec(), list).is_some() {
1516
+ return Err(Error::Corruption(format!(
1517
+ "id {:?} is in two lists",
1518
+ e.qualifier
1519
+ )));
1520
+ }
1521
+ *lens.get_mut(&list).expect("listed") += 1;
1522
+ }
1523
+ let mut mapped = 0usize;
1524
+ for row in t.scan_prefix(b"M").family(MAP).snapshot(&s).iter()? {
1525
+ let row = row?;
1526
+ let id = &row.key()[1..];
1527
+ let list = row.get(MAP, LIST).and_then(|c| c.as_u64());
1528
+ if list != home.get(id).map(|l| u64::from(*l)) {
1529
+ return Err(Error::Corruption(format!(
1530
+ "id {id:?} maps to {list:?} but is in {:?}",
1531
+ home.get(id)
1532
+ )));
1533
+ }
1534
+ mapped += 1;
1535
+ }
1536
+ if mapped != home.len() {
1537
+ return Err(corrupt("a vector has no mapping"));
1538
+ }
1539
+ for row in t.scan_prefix(b"N").family(CNT).snapshot(&s).iter()? {
1540
+ let row = row?;
1541
+ let list = list_of(row.key()).ok_or_else(|| corrupt("a count row key"))?;
1542
+ let n = row.get(CNT, b"").and_then(|c| c.as_i64()).unwrap_or(0);
1543
+ let want = lens.get(&list).copied();
1544
+ if want != Some(n.max(0) as u64) || n < 0 {
1545
+ return Err(Error::Corruption(format!(
1546
+ "list {list} counts {n} but holds {want:?}"
1547
+ )));
1548
+ }
1549
+ }
1550
+ for l in &layout.lists {
1551
+ if lens[&l.id] > 0 && t.get_at(&s, &count_row(l.id), CNT, b"")?.is_none() {
1552
+ return Err(Error::Corruption(format!("list {} has no count", l.id)));
1553
+ }
1554
+ }
1555
+ Ok(IndexStats {
1556
+ list_lens: layout.lists.iter().map(|l| lens[&l.id]).collect(),
1557
+ vectors: home.len() as u64,
1558
+ })
1559
+ }
1560
+
1561
+ fn insert(&self, id: &[u8], v: Input<'_>) -> Result<()> {
1562
+ v.check(&self.inner.spec)?;
1563
+ let point = v.placed(&self.inner.spec);
1564
+ let mut layout = self.layout();
1565
+ for _ in 0..RELOADS {
1566
+ let r = if layout.lists.is_empty() {
1567
+ self.bootstrap(id, v, &point)
1568
+ } else {
1569
+ self.place(&layout, id, v, &point)
1570
+ };
1571
+ match r {
1572
+ Ok(touched) => return self.after_write(touched),
1573
+ Err(Tx::Stale) => layout = self.reload()?,
1574
+ Err(e) => return Err(e.into()),
1575
+ }
1576
+ }
1577
+ Err(Error::Conflict(
1578
+ "the index's layout changed under every attempt of an insert".into(),
1579
+ ))
1580
+ }
1581
+
1582
+ /// `insert_*_in`'s body: see [`insert_f32_in`](Self::insert_f32_in).
1583
+ fn insert_in(
1584
+ &self,
1585
+ tx: &mut Transaction,
1586
+ placed: &mut Placed,
1587
+ id: &[u8],
1588
+ v: Input<'_>,
1589
+ ) -> Result<()> {
1590
+ let inn = &*self.inner;
1591
+ v.check(&inn.spec)?;
1592
+ placed.bind(self)?;
1593
+ let point = v.placed(&inn.spec);
1594
+ let t = &inn.table;
1595
+ // Where `id` is: as this transaction left it, else as its snapshot shows it.
1596
+ let tracked = placed.ids.get(id).copied();
1597
+ let l = if placed.bootstrapped {
1598
+ // This transaction created list 0, the only one its snapshot can have.
1599
+ 0
1600
+ } else {
1601
+ let mut layout = self.layout();
1602
+ let mut reloaded = false;
1603
+ loop {
1604
+ if layout.lists.is_empty() {
1605
+ if read_u64(tx, t, GLOBAL, META, NEXT)? == Some(0) {
1606
+ write_bootstrap(tx, t, &unit(inn.cen.metric(), point.clone()), id, v);
1607
+ placed.bootstrapped = true;
1608
+ placed.wrote(id, Some(0), [0]);
1609
+ return Ok(());
1610
+ }
1611
+ if reloaded {
1612
+ // `G:meta:next` isn't 0 in `tx` though the fresh layout has no
1613
+ // lists: the layout and `tx` disagree (a lost tail, say). A `tx`
1614
+ // older than a racing first insert reads 0 and bootstraps, and its
1615
+ // commit conflicts.
1616
+ return Err(Error::Conflict(
1617
+ "the index's layout is newer in the transaction than in the database"
1618
+ .into(),
1619
+ ));
1620
+ }
1621
+ layout = self.reload()?;
1622
+ reloaded = true;
1623
+ continue;
1624
+ }
1625
+ let l = layout.nearest(&inn.cen, &point, 1, &[])?[0];
1626
+ let want = layout.list(l).expect("a listed list").version;
1627
+ if read_version(tx, t, l)? != Some(want) && !reloaded {
1628
+ layout = self.reload()?;
1629
+ reloaded = true;
1630
+ continue;
1631
+ }
1632
+ // The version `tx` read is `want`, or was rewritten after `tx`'s snapshot (the
1633
+ // reload's snapshot is newer than it): then the commit fails with `Conflict`.
1634
+ break l;
1635
+ }
1636
+ };
1637
+ let old = match tracked {
1638
+ Some(now) => now,
1639
+ None => read_list_of(tx, t, id)?,
1640
+ };
1641
+ match write_into(tx, t, l, old, tracked.is_none(), id, v) {
1642
+ Ok(()) => {
1643
+ placed.wrote(id, Some(l), std::iter::once(l).chain(old));
1644
+ Ok(())
1645
+ }
1646
+ Err(Tx::Stale) => Err(unmapped()),
1647
+ Err(e) => Err(e.into()),
1648
+ }
1649
+ }
1650
+
1651
+ /// The first insert into an empty index: list 0, centred on the vector.
1652
+ fn bootstrap(
1653
+ &self,
1654
+ id: &[u8],
1655
+ v: Input<'_>,
1656
+ point: &Point,
1657
+ ) -> std::result::Result<Vec<u32>, Tx> {
1658
+ let inn = &*self.inner;
1659
+ let t = &inn.table;
1660
+ let centroid = unit(inn.cen.metric(), point.clone());
1661
+ inn.db.transact(&RetryPolicy::default(), |tx| {
1662
+ // Any list ever made means this cache is stale.
1663
+ if read_u64(tx, t, GLOBAL, META, NEXT)? != Some(0) {
1664
+ return Err(Tx::Stale);
1665
+ }
1666
+ write_bootstrap(tx, t, &centroid, id, v);
1667
+ Ok(())
1668
+ })?;
1669
+ Ok(vec![0])
1670
+ }
1671
+
1672
+ /// An insert or upsert into the list nearest `point` (D306 §2, rev 3's read sets): it
1673
+ /// reads `M{id}` and the versions of the lists it writes, never `N` or `G`.
1674
+ fn place(
1675
+ &self,
1676
+ layout: &Layout,
1677
+ id: &[u8],
1678
+ v: Input<'_>,
1679
+ point: &Point,
1680
+ ) -> std::result::Result<Vec<u32>, Tx> {
1681
+ let inn = &*self.inner;
1682
+ let t = &inn.table;
1683
+ let l = layout.nearest(&inn.cen, point, 1, &[])?[0];
1684
+ let want = layout.list(l).expect("a listed list").version;
1685
+ let (old, _) = inn.db.transact(&RetryPolicy::default(), |tx| {
1686
+ let old = read_list_of(tx, t, id)?;
1687
+ // Absent: merged away (M1). Another version: the cache predates a split or a
1688
+ // reassignment, so place against the current centroids (rev 2 nit 3).
1689
+ if read_version(tx, t, l)? != Some(want) {
1690
+ return Err(Tx::Stale);
1691
+ }
1692
+ write_into(tx, t, l, old, true, id, v)?;
1693
+ #[cfg(feature = "__unstable-hooks")]
1694
+ crate::hooks::hold(crate::hooks::Hold::PlaceBeforeCommit);
1695
+ Ok(old)
1696
+ })?;
1697
+ Ok(match old {
1698
+ Some(o) if o != l => vec![l, o],
1699
+ _ => vec![l],
1700
+ })
1701
+ }
1702
+
1703
+ fn layout(&self) -> Arc<Layout> {
1704
+ Arc::clone(
1705
+ &self
1706
+ .inner
1707
+ .layout
1708
+ .read()
1709
+ .unwrap_or_else(PoisonError::into_inner),
1710
+ )
1711
+ }
1712
+
1713
+ /// Loads the centroids at a fresh snapshot into the shared cache.
1714
+ fn reload(&self) -> Result<Arc<Layout>> {
1715
+ let inn = &*self.inner;
1716
+ let s = inn.db.snapshot()?;
1717
+ let fresh = Arc::new(load(&inn.table, &inn.cen, &s)?);
1718
+ let mut shared = inn.layout.write().unwrap_or_else(PoisonError::into_inner);
1719
+ if fresh.seqno >= shared.seqno {
1720
+ *shared = Arc::clone(&fresh);
1721
+ }
1722
+ Ok(fresh)
1723
+ }
1724
+
1725
+ /// The centroids at `s`: the shared cache when it holds `s`'s layout, else loaded. Only
1726
+ /// a search at the current snapshot replaces the shared cache (rev 3 S4).
1727
+ fn layout_at(&self, s: &Snapshot, current: bool) -> Result<Arc<Layout>> {
1728
+ let inn = &*self.inner;
1729
+ let latest = || inn.db.snapshot().ok().map(|s| s.seqno());
1730
+ let latest: &dyn Fn() -> Option<u64> = &latest;
1731
+ layout_at(
1732
+ &inn.table,
1733
+ &inn.cen,
1734
+ &inn.layout,
1735
+ s,
1736
+ current.then_some(latest),
1737
+ )
1738
+ }
1739
+
1740
+ fn count(&self, list: u32) -> Result<u64> {
1741
+ let n = self
1742
+ .inner
1743
+ .table
1744
+ .get(&count_row(list), CNT, b"")?
1745
+ .and_then(|c| c.as_i64())
1746
+ .unwrap_or(0);
1747
+ Ok(n.max(0) as u64)
1748
+ }
1749
+
1750
+ fn queue(&self, lists: impl IntoIterator<Item = u32>) {
1751
+ let mut q = self
1752
+ .inner
1753
+ .pending
1754
+ .lock()
1755
+ .unwrap_or_else(PoisonError::into_inner);
1756
+ for l in lists {
1757
+ if !q.contains(&l) {
1758
+ q.push_back(l);
1759
+ }
1760
+ }
1761
+ }
1762
+
1763
+ /// Queues every list outside its bounds at `s` (`open`'s scan, rev 3 M3).
1764
+ fn queue_out_of_bounds(&self, s: &Snapshot) -> Result<()> {
1765
+ let t = &self.inner.table;
1766
+ let lists = self.layout().lists.len();
1767
+ let mut out = Vec::new();
1768
+ for row in t.scan_prefix(b"N").family(CNT).snapshot(s).iter()? {
1769
+ let row = row?;
1770
+ let list = list_of(row.key()).ok_or_else(|| corrupt("a count row key"))?;
1771
+ let n = row
1772
+ .get(CNT, b"")
1773
+ .and_then(|c| c.as_i64())
1774
+ .unwrap_or(0)
1775
+ .max(0) as u64;
1776
+ if n > self.max_list_len() || (n < self.min_list_len() && lists > 1) {
1777
+ out.push(list);
1778
+ }
1779
+ }
1780
+ // Background markers: a hint, re-checked before any work (rev 3 M3).
1781
+ for row in t.scan_prefix(b"Q").family(META).snapshot(s).iter()? {
1782
+ let row = row?;
1783
+ out.push(list_of(row.key()).ok_or_else(|| corrupt("a marker row key"))?);
1784
+ }
1785
+ self.queue(out);
1786
+ Ok(())
1787
+ }
1788
+
1789
+ /// Splits or merges queued lists that are outside their bounds, a bounded number per
1790
+ /// call (a bound check, never an edge: rev 3 M3).
1791
+ fn maintain(&self) -> Result<()> {
1792
+ for _ in 0..MAINTENANCE_PER_CALL {
1793
+ if self.maintain_one()?.is_none() {
1794
+ break;
1795
+ }
1796
+ }
1797
+ Ok(())
1798
+ }
1799
+
1800
+ /// Whether lists are queued for a bound check.
1801
+ pub(crate) fn has_pending(&self) -> bool {
1802
+ !self
1803
+ .inner
1804
+ .pending
1805
+ .lock()
1806
+ .unwrap_or_else(PoisonError::into_inner)
1807
+ .is_empty()
1808
+ }
1809
+
1810
+ /// Checks the next queued list against its bounds, and splits or merges it: `None` when
1811
+ /// nothing is queued, else whether it was out of bounds. In background mode a list found
1812
+ /// within its bounds has its stale marker removed. An error puts the list back.
1813
+ pub(crate) fn maintain_one(&self) -> Result<Option<bool>> {
1814
+ let next = self
1815
+ .inner
1816
+ .pending
1817
+ .lock()
1818
+ .unwrap_or_else(PoisonError::into_inner)
1819
+ .pop_front();
1820
+ let Some(l) = next else {
1821
+ return Ok(None);
1822
+ };
1823
+ let r = (|| {
1824
+ let n = self.count(l)?;
1825
+ if n > self.max_list_len() {
1826
+ self.split(l)?;
1827
+ Ok(true)
1828
+ } else if n < self.min_list_len() && self.layout().lists.len() > 1 {
1829
+ self.merge(l)?;
1830
+ Ok(true)
1831
+ } else {
1832
+ if self.inner.opts.rebalance == Rebalance::Background {
1833
+ self.inner
1834
+ .table
1835
+ .mutate(&queue_row(l))
1836
+ .delete_row()
1837
+ .commit()?;
1838
+ }
1839
+ Ok(false)
1840
+ }
1841
+ })();
1842
+ if r.is_err() {
1843
+ self.queue([l]);
1844
+ }
1845
+ r.map(Some)
1846
+ }
1847
+
1848
+ /// After a write committed into `lists`: rebalance them now ([`Rebalance::Inline`]), or
1849
+ /// mark those out of bounds for the rebalancer ([`Rebalance::Background`]): a `Q` row in
1850
+ /// its own transaction (rev 4 N2) and the in-process queue. A list already queued here
1851
+ /// isn't marked again.
1852
+ fn after_write(&self, lists: impl IntoIterator<Item = u32>) -> Result<()> {
1853
+ #[cfg(feature = "__unstable-hooks")]
1854
+ if crate::hooks::skipping_rebalance() {
1855
+ return Ok(());
1856
+ }
1857
+ if self.inner.opts.rebalance == Rebalance::Inline {
1858
+ self.queue(lists);
1859
+ return self.maintain();
1860
+ }
1861
+ let mut marked = false;
1862
+ for l in lists {
1863
+ let queued = self
1864
+ .inner
1865
+ .pending
1866
+ .lock()
1867
+ .unwrap_or_else(PoisonError::into_inner)
1868
+ .contains(&l);
1869
+ if queued {
1870
+ continue;
1871
+ }
1872
+ let n = self.count(l)?;
1873
+ let several = self.layout().lists.len() > 1;
1874
+ if n > self.max_list_len() || (n < self.min_list_len() && several) {
1875
+ self.inner
1876
+ .table
1877
+ .mutate(&queue_row(l))
1878
+ .put_u64(META, MARK, 1)
1879
+ .commit()?;
1880
+ self.queue([l]);
1881
+ marked = true;
1882
+ }
1883
+ }
1884
+ if marked {
1885
+ self.inner.signal.notify();
1886
+ }
1887
+ Ok(())
1888
+ }
1889
+
1890
+ /// Marks `list` in flight in this process, or `None` if it already is (rev 4).
1891
+ fn claim(&self, list: u32) -> Option<Claim<'_>> {
1892
+ let set = &self.inner.in_flight;
1893
+ // The lock is released before a `Claim` exists: its drop takes the lock again.
1894
+ let fresh = set
1895
+ .lock()
1896
+ .unwrap_or_else(PoisonError::into_inner)
1897
+ .insert(list);
1898
+ fresh.then(|| Claim { set, list })
1899
+ }
1900
+
1901
+ /// The ids and points of `list` at `s`, in id order.
1902
+ fn members(&self, s: &Snapshot, list: u32) -> Result<(Vec<Vec<u8>>, Vec<Point>)> {
1903
+ let mut cells = self
1904
+ .inner
1905
+ .table
1906
+ .row(&list_row(list))
1907
+ .family(VEC)
1908
+ .snapshot(s)
1909
+ .cells()?;
1910
+ let (mut ids, mut points) = (Vec::new(), Vec::new());
1911
+ while let Some(e) = cells.next()? {
1912
+ let v = e
1913
+ .cell
1914
+ .as_vector()
1915
+ .ok_or_else(|| corrupt("a list column is not a vector"))?;
1916
+ ids.push(e.qualifier.to_vec());
1917
+ points.push(Point::of(v));
1918
+ }
1919
+ Ok((ids, points))
1920
+ }
1921
+
1922
+ /// Splits `list` (D306 §3): 2-means on a snapshot read, then one transaction moving
1923
+ /// what it reads itself (rev 3 S1, rev 4 N1); then phase 2 over its neighbours.
1924
+ fn split(&self, list: u32) -> Result<()> {
1925
+ let Some(_claim) = self.claim(list) else {
1926
+ return Ok(());
1927
+ };
1928
+ for _ in 0..ATTEMPTS {
1929
+ // The loser of a duplicate split re-checks the length before splitting the
1930
+ // fresh half (rev 3 S2).
1931
+ if self.count(list)? <= self.max_list_len() {
1932
+ return Ok(());
1933
+ }
1934
+ let s0 = self.inner.db.snapshot()?;
1935
+ let mut layout = self.layout();
1936
+ if layout.list(list).is_none() {
1937
+ layout = self.reload()?;
1938
+ }
1939
+ let Some(current) = layout.list(list) else {
1940
+ return Ok(());
1941
+ };
1942
+ let (ids, points) = self.members(&s0, list)?;
1943
+ if ids.len() as u64 <= self.max_list_len() {
1944
+ return Ok(());
1945
+ }
1946
+ #[cfg(feature = "__unstable-hooks")]
1947
+ crate::hooks::hold(crate::hooks::Hold::SplitBeforeCommit);
1948
+ let min = usize::try_from(self.min_list_len()).unwrap_or(usize::MAX);
1949
+ let plan = two_means(&self.inner.cen, &points, &current.point, min)?;
1950
+ let moving: Vec<&[u8]> = plan.moving.iter().map(|i| ids[*i].as_slice()).collect();
1951
+ match self.split_commit(list, &plan, &moving) {
1952
+ Ok(new) => {
1953
+ let layout = self.reload()?;
1954
+ self.queue([list, new]);
1955
+ #[cfg(feature = "__unstable-hooks")]
1956
+ if crate::hooks::failing_after_split() {
1957
+ // A crash between the split's commit and its phase 2.
1958
+ return Ok(());
1959
+ }
1960
+ return self.reassign(&layout, list, new, &plan);
1961
+ }
1962
+ Err(Tx::Stale) => return Ok(()),
1963
+ Err(e) if is_conflict(&e) => {}
1964
+ Err(e) => return Err(e.into()),
1965
+ }
1966
+ }
1967
+ // Lost every attempt: the next write into the list triggers it again.
1968
+ Ok(())
1969
+ }
1970
+
1971
+ fn split_commit(
1972
+ &self,
1973
+ list: u32,
1974
+ plan: &Plan,
1975
+ moving: &[&[u8]],
1976
+ ) -> std::result::Result<u32, Tx> {
1977
+ let inn = &*self.inner;
1978
+ let t = &inn.table;
1979
+ let (new, _) = inn
1980
+ .db
1981
+ .transact(&RetryPolicy::default().max_attempts(1), |tx| {
1982
+ let Some(version) = read_version(tx, t, list)? else {
1983
+ return Err(Tx::Stale);
1984
+ };
1985
+ let next = read_u64(tx, t, GLOBAL, META, NEXT)?
1986
+ .ok_or_else(|| corrupt("no next list id"))?;
1987
+ let layout = read_u64(tx, t, GLOBAL, META, LAYOUT)?.unwrap_or(0);
1988
+ let new = u32::try_from(next).map_err(|_| corrupt("list ids exhausted"))?;
1989
+ let (from, to) = (list_row(list), list_row(new));
1990
+ let mut moved = 0i64;
1991
+ for id in moving {
1992
+ // Deleted or moved away since the 2-means snapshot: skip it (rev 4 N1).
1993
+ let Some(stored) = read_stored(tx, t, &from, id)? else {
1994
+ continue;
1995
+ };
1996
+ stored.input().put(tx, t, &to, id);
1997
+ tx.delete_column(t, &from, VEC, id).put_u64(
1998
+ t,
1999
+ &map_row(id),
2000
+ MAP,
2001
+ LIST,
2002
+ u64::from(new),
2003
+ );
2004
+ moved += 1;
2005
+ }
2006
+ if moved == 0 {
2007
+ return Err(Tx::Stale);
2008
+ }
2009
+ put_centroid(tx, t, list, &plan.stay);
2010
+ put_centroid(tx, t, new, &plan.go);
2011
+ tx.put_u64(t, &centroid_row(list), META, VERSION, version + 1)
2012
+ .put_u64(t, &centroid_row(new), META, VERSION, 1)
2013
+ .incr(t, &count_row(list), CNT, b"", -moved)
2014
+ .incr(t, &count_row(new), CNT, b"", moved)
2015
+ .put_u64(t, GLOBAL, META, NEXT, next + 1)
2016
+ .put_u64(t, GLOBAL, META, LAYOUT, layout + 1);
2017
+ if inn.opts.rebalance == Rebalance::Background {
2018
+ tx.delete_row(t, &queue_row(list));
2019
+ }
2020
+ Ok(new)
2021
+ })?;
2022
+ Ok(new)
2023
+ }
2024
+
2025
+ /// Phase 2 (SPFresh's LIRE): each of the split's nearest neighbour lists gives up the
2026
+ /// vectors now nearer one of the two new centroids, one transaction per neighbour that
2027
+ /// bumps the neighbour's version (rev 3 S3). A conflict skips that neighbour: this is
2028
+ /// clustering, not correctness.
2029
+ fn reassign(&self, layout: &Layout, list: u32, new: u32, plan: &Plan) -> Result<()> {
2030
+ let inn = &*self.inner;
2031
+ let t = &inn.table;
2032
+ let r = inn.opts.reassign as usize;
2033
+ if r == 0 {
2034
+ return Ok(());
2035
+ }
2036
+ let dim = inn.cen.dim();
2037
+ let (stay, go) = (plan.stay.to_vector(dim)?, plan.go.to_vector(dim)?);
2038
+ for nbr in layout.nearest(&inn.cen, &plan.stay, r, &[list, new])? {
2039
+ let Some(n) = layout.list(nbr) else {
2040
+ continue;
2041
+ };
2042
+ let s = inn.db.snapshot()?;
2043
+ let (ids, points) = self.members(&s, nbr)?;
2044
+ let mut moves: Vec<(&[u8], u32)> = Vec::new();
2045
+ for (id, p) in ids.iter().zip(&points) {
2046
+ let here = distance(&inn.cen, p, &n.centroid)?;
2047
+ let (ds, dg) = (distance(&inn.cen, p, &stay)?, distance(&inn.cen, p, &go)?);
2048
+ let (d, dest) = if dg < ds { (dg, new) } else { (ds, list) };
2049
+ if d < here {
2050
+ moves.push((id, dest));
2051
+ }
2052
+ }
2053
+ if moves.is_empty() {
2054
+ continue;
2055
+ }
2056
+ let done = inn
2057
+ .db
2058
+ .transact(&RetryPolicy::default().max_attempts(1), |tx| {
2059
+ let Some(version) = read_version(tx, t, nbr)? else {
2060
+ return Err(Tx::Stale);
2061
+ };
2062
+ if read_version(tx, t, list)?.is_none() || read_version(tx, t, new)?.is_none() {
2063
+ return Err(Tx::Stale);
2064
+ }
2065
+ let from = list_row(nbr);
2066
+ let mut gained: HashMap<u32, i64> = HashMap::new();
2067
+ for (id, dest) in &moves {
2068
+ let Some(stored) = read_stored(tx, t, &from, id)? else {
2069
+ continue;
2070
+ };
2071
+ stored.input().put(tx, t, &list_row(*dest), id);
2072
+ tx.delete_column(t, &from, VEC, id).put_u64(
2073
+ t,
2074
+ &map_row(id),
2075
+ MAP,
2076
+ LIST,
2077
+ u64::from(*dest),
2078
+ );
2079
+ *gained.entry(*dest).or_default() += 1;
2080
+ }
2081
+ let lost: i64 = gained.values().sum();
2082
+ if lost == 0 {
2083
+ return Err(Tx::Stale);
2084
+ }
2085
+ tx.incr(t, &count_row(nbr), CNT, b"", -lost).put_u64(
2086
+ t,
2087
+ &centroid_row(nbr),
2088
+ META,
2089
+ VERSION,
2090
+ version + 1,
2091
+ );
2092
+ for (dest, n) in &gained {
2093
+ tx.incr(t, &count_row(*dest), CNT, b"", *n);
2094
+ }
2095
+ #[cfg(feature = "__unstable-hooks")]
2096
+ crate::hooks::hold(crate::hooks::Hold::ReassignBeforeCommit);
2097
+ Ok(())
2098
+ });
2099
+ match done {
2100
+ Ok(_) => self.queue([nbr, list, new]),
2101
+ Err(Tx::Stale) => {}
2102
+ Err(e) if is_conflict(&e) => {}
2103
+ Err(e) => return Err(e.into()),
2104
+ }
2105
+ }
2106
+ Ok(())
2107
+ }
2108
+
2109
+ /// Merges `list` into its nearest neighbour (D306 §3): one transaction that reads the
2110
+ /// list row whole and moves every vector (rev 3's table).
2111
+ fn merge(&self, list: u32) -> Result<()> {
2112
+ let Some(_claim) = self.claim(list) else {
2113
+ return Ok(());
2114
+ };
2115
+ let inn = &*self.inner;
2116
+ let t = &inn.table;
2117
+ for _ in 0..ATTEMPTS {
2118
+ let mut layout = self.layout();
2119
+ if layout.list(list).is_none() {
2120
+ layout = self.reload()?;
2121
+ }
2122
+ let Some(src) = layout.list(list) else {
2123
+ return Ok(());
2124
+ };
2125
+ if layout.lists.len() <= 1 || self.count(list)? >= self.min_list_len() {
2126
+ return Ok(());
2127
+ }
2128
+ let Some(&dst) = layout.nearest(&inn.cen, &src.point, 1, &[list])?.first() else {
2129
+ return Ok(());
2130
+ };
2131
+ let r = inn
2132
+ .db
2133
+ .transact(&RetryPolicy::default().max_attempts(1), |tx| {
2134
+ if read_version(tx, t, list)?.is_none() {
2135
+ return Ok(false);
2136
+ }
2137
+ // A destination merged away meanwhile: reload and choose again (M1).
2138
+ let Some(version) = read_version(tx, t, dst)? else {
2139
+ return Err(Tx::Stale);
2140
+ };
2141
+ let from = list_row(list);
2142
+ let moving: Vec<(Vec<u8>, Stored)> = match tx.get_row(t, &from, &[VEC])? {
2143
+ None => Vec::new(),
2144
+ Some(row) => row
2145
+ .iter()
2146
+ .map(|e| {
2147
+ let v = e
2148
+ .cell
2149
+ .as_vector()
2150
+ .ok_or_else(|| corrupt("a list column is not a vector"))?;
2151
+ Ok((e.qualifier.to_vec(), Stored::of(v)?))
2152
+ })
2153
+ .collect::<Result<_>>()?,
2154
+ };
2155
+ let to = list_row(dst);
2156
+ for (id, stored) in &moving {
2157
+ stored.input().put(tx, t, &to, id);
2158
+ tx.put_u64(t, &map_row(id), MAP, LIST, u64::from(dst));
2159
+ }
2160
+ let layout = read_u64(tx, t, GLOBAL, META, LAYOUT)?.unwrap_or(0);
2161
+ tx.delete_family(t, &from, VEC)
2162
+ .delete_row(t, &centroid_row(list))
2163
+ .delete_row(t, &count_row(list))
2164
+ .incr(t, &count_row(dst), CNT, b"", moving.len() as i64)
2165
+ .put_u64(t, &centroid_row(dst), META, VERSION, version + 1)
2166
+ .put_u64(t, GLOBAL, META, LAYOUT, layout + 1);
2167
+ if inn.opts.rebalance == Rebalance::Background {
2168
+ tx.delete_row(t, &queue_row(list));
2169
+ }
2170
+ Ok(true)
2171
+ });
2172
+ match r {
2173
+ Ok((merged, _)) => {
2174
+ if merged {
2175
+ #[cfg(feature = "__unstable-hooks")]
2176
+ crate::hooks::hold(crate::hooks::Hold::MergeBeforeReload);
2177
+ self.reload()?;
2178
+ self.queue([dst]);
2179
+ }
2180
+ return Ok(());
2181
+ }
2182
+ Err(Tx::Stale) => {
2183
+ self.reload()?;
2184
+ }
2185
+ Err(e) if is_conflict(&e) => {}
2186
+ Err(e) => return Err(e.into()),
2187
+ }
2188
+ }
2189
+ Ok(())
2190
+ }
2191
+ }
2192
+
2193
+ /// The rows of `lists`, for one multi-get.
2194
+ fn rows(lists: &[u32]) -> KeySet {
2195
+ KeySet::from_unsorted(lists.iter().map(|l| list_row(*l)))
2196
+ }
2197
+
2198
+ fn hits(near: Vec<pigeonhole::Neighbour>) -> Vec<Hit> {
2199
+ near.into_iter()
2200
+ .map(|n| Hit {
2201
+ id: n.qualifier,
2202
+ distance: n.distance,
2203
+ })
2204
+ .collect()
2205
+ }
2206
+
2207
+ /// An index opened from a reader process ([`Index::open_reader`], #1268 item 5): searches
2208
+ /// only, at the reader's snapshots, with the same results as the writer's
2209
+ /// [`Index`] at the same snapshot. It holds its own centroid cache, reloaded when a search
2210
+ /// sees the layout changed. If the writer restarts, a search fails with `NoWriter` or
2211
+ /// `SnapshotExpired` (`Error::Db`) until the reader attaches to the new writer; searching
2212
+ /// again is enough. A reader process has its own block cache: size it as the writer's.
2213
+ #[derive(Clone)]
2214
+ pub struct ReadIndex {
2215
+ inner: Arc<ReadInner>,
2216
+ }
2217
+
2218
+ struct ReadInner {
2219
+ db: PigeonholeReader,
2220
+ table: ReadTable,
2221
+ spec: VectorSpec,
2222
+ cen: VectorSpec,
2223
+ opts: IndexOptions,
2224
+ layout: RwLock<Arc<Layout>>,
2225
+ }
2226
+
2227
+ impl std::fmt::Debug for ReadIndex {
2228
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2229
+ f.debug_struct("ReadIndex")
2230
+ .field("table", &self.inner.table.name())
2231
+ .field("spec", &self.inner.spec)
2232
+ .field("options", &self.inner.opts)
2233
+ .finish_non_exhaustive()
2234
+ }
2235
+ }
2236
+
2237
+ impl ReadIndex {
2238
+ /// The vectors' spec.
2239
+ pub fn spec(&self) -> VectorSpec {
2240
+ self.inner.spec
2241
+ }
2242
+
2243
+ /// The options it was created with (the target list length as scaled).
2244
+ pub fn options(&self) -> IndexOptions {
2245
+ self.inner.opts
2246
+ }
2247
+
2248
+ /// The `k` vectors nearest the `f32` vector `query`, as a [`Search`] to run.
2249
+ pub fn search_f32<'a>(&'a self, query: &'a [f32], k: usize) -> Search<'a> {
2250
+ Search::new(Of::R(self), Input::F32(query), k)
2251
+ }
2252
+
2253
+ /// [`search_f32`](Self::search_f32) for an `i8` index.
2254
+ pub fn search_i8<'a>(&'a self, query: &'a [i8], k: usize) -> Search<'a> {
2255
+ Search::new(Of::R(self), Input::I8(query), k)
2256
+ }
2257
+
2258
+ /// [`search_f32`](Self::search_f32) for a bit index.
2259
+ pub fn search_bits<'a>(&'a self, query: &'a [u8], k: usize) -> Search<'a> {
2260
+ Search::new(Of::R(self), Input::Bits(query), k)
2261
+ }
2262
+
2263
+ /// [`Index::search_f16`] from a reader process.
2264
+ pub fn search_f16<'a>(&'a self, query: &'a [u16], k: usize) -> Search<'a> {
2265
+ Search::new(Of::R(self), Input::F16(query), k)
2266
+ }
2267
+
2268
+ /// [`Index::search_bf16`] from a reader process.
2269
+ pub fn search_bf16<'a>(&'a self, query: &'a [u16], k: usize) -> Search<'a> {
2270
+ Search::new(Of::R(self), Input::BF16(query), k)
2271
+ }
2272
+ }
2273
+
2274
+ /// A nearest-neighbour search under construction ([`Index::search_f32`],
2275
+ /// [`ReadIndex::search_f32`] and their `i8` and bit forms). Finish with
2276
+ /// [`run`](Search::run).
2277
+ #[derive(Debug)]
2278
+ #[must_use = "a search does nothing until .run()"]
2279
+ pub struct Search<'a> {
2280
+ index: Of<'a>,
2281
+ query: Input<'a>,
2282
+ k: usize,
2283
+ nprobe: Option<u32>,
2284
+ snapshot: Option<&'a Snapshot>,
2285
+ parallel: usize,
2286
+ id_prefix: Option<&'a [u8]>,
2287
+ max_probe: Option<u32>,
2288
+ }
2289
+
2290
+ /// What a [`Search`] read ([`Search::run_with_stats`]).
2291
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2292
+ #[non_exhaustive]
2293
+ pub struct SearchStats {
2294
+ /// Lists probed: `nprobe` (at most every list), or more for a search with an
2295
+ /// [`id_prefix`](Search::id_prefix) that widened to find `k` hits.
2296
+ pub lists_probed: u32,
2297
+ /// Lists in the index at the search's snapshot.
2298
+ pub lists: u32,
2299
+ }
2300
+
2301
+ /// The index a [`Search`] reads: the writer's, or a reader process's.
2302
+ #[derive(Debug, Clone, Copy)]
2303
+ enum Of<'a> {
2304
+ W(&'a Index),
2305
+ R(&'a ReadIndex),
2306
+ }
2307
+
2308
+ impl<'a> Of<'a> {
2309
+ fn spec(&self) -> &'a VectorSpec {
2310
+ match *self {
2311
+ Of::W(i) => &i.inner.spec,
2312
+ Of::R(i) => &i.inner.spec,
2313
+ }
2314
+ }
2315
+
2316
+ fn cen(&self) -> &'a VectorSpec {
2317
+ match *self {
2318
+ Of::W(i) => &i.inner.cen,
2319
+ Of::R(i) => &i.inner.cen,
2320
+ }
2321
+ }
2322
+
2323
+ fn nprobe(&self) -> u32 {
2324
+ match *self {
2325
+ Of::W(i) => i.inner.opts.nprobe,
2326
+ Of::R(i) => i.inner.opts.nprobe,
2327
+ }
2328
+ }
2329
+
2330
+ fn snapshot(&self) -> pigeonhole::Result<Snapshot> {
2331
+ match *self {
2332
+ Of::W(i) => i.inner.db.snapshot(),
2333
+ Of::R(i) => i.inner.db.snapshot(),
2334
+ }
2335
+ }
2336
+
2337
+ fn layout_at(&self, s: &Snapshot, current: bool) -> Result<Arc<Layout>> {
2338
+ match *self {
2339
+ Of::W(i) => i.layout_at(s, current),
2340
+ Of::R(i) => {
2341
+ let inn = &*i.inner;
2342
+ let latest = || inn.db.snapshot().ok().map(|s| s.seqno());
2343
+ let latest: &dyn Fn() -> Option<u64> = &latest;
2344
+ layout_at(
2345
+ &inn.table,
2346
+ &inn.cen,
2347
+ &inn.layout,
2348
+ s,
2349
+ current.then_some(latest),
2350
+ )
2351
+ }
2352
+ }
2353
+ }
2354
+
2355
+ #[cfg(feature = "async")]
2356
+ async fn layout_at_async(&self, s: &Snapshot, current: bool) -> Result<Arc<Layout>> {
2357
+ match *self {
2358
+ Of::W(i) => {
2359
+ let inn = &*i.inner;
2360
+ let latest = || inn.db.snapshot().ok().map(|s| s.seqno());
2361
+ let latest: &(dyn Fn() -> Option<u64> + Sync) = &latest;
2362
+ layout_at_async(
2363
+ &inn.table,
2364
+ &inn.cen,
2365
+ &inn.layout,
2366
+ s,
2367
+ current.then_some(latest),
2368
+ )
2369
+ .await
2370
+ }
2371
+ Of::R(i) => {
2372
+ let inn = &*i.inner;
2373
+ let latest = || inn.db.snapshot().ok().map(|s| s.seqno());
2374
+ let latest: &(dyn Fn() -> Option<u64> + Sync) = &latest;
2375
+ layout_at_async(
2376
+ &inn.table,
2377
+ &inn.cen,
2378
+ &inn.layout,
2379
+ s,
2380
+ current.then_some(latest),
2381
+ )
2382
+ .await
2383
+ }
2384
+ }
2385
+ }
2386
+
2387
+ fn rows_of(&self, keys: &KeySet) -> KeysRead<'a> {
2388
+ match *self {
2389
+ Of::W(i) => i.inner.table.rows_of(keys),
2390
+ Of::R(i) => i.inner.table.rows_of(keys),
2391
+ }
2392
+ }
2393
+ }
2394
+
2395
+ impl<'a> Search<'a> {
2396
+ fn new(index: Of<'a>, query: Input<'a>, k: usize) -> Self {
2397
+ Self {
2398
+ index,
2399
+ query,
2400
+ k,
2401
+ nprobe: None,
2402
+ snapshot: None,
2403
+ parallel: 1,
2404
+ id_prefix: None,
2405
+ max_probe: None,
2406
+ }
2407
+ }
2408
+
2409
+ /// Only ids starting with `prefix`. The probed lists hold every id near the query, so a
2410
+ /// prefix that's rare among them can leave fewer than `k` hits at `nprobe`: the search
2411
+ /// then doubles the lists it probes (nearest first) until `k` hits pass, every list is
2412
+ /// probed, or [`max_probe`](Self::max_probe) lists are. Each round reads only its new
2413
+ /// lists, each list once: a round widens only when the earlier ones found fewer than
2414
+ /// `k`, so it already holds every prefixed vector of the lists they read. A prefixed
2415
+ /// search that probes every list is exact for the prefix.
2416
+ ///
2417
+ /// Ties among the hits come back by probe round, then by list, then by id.
2418
+ ///
2419
+ /// **Cost:** a seek into each probed list, then the prefix's own cells there: the list's
2420
+ /// other cells aren't read (the prefix becomes the read's qualifier seek). On one 100,000
2421
+ /// cell row, 100 cells under a prefix took 0.01 ms against 5.14 ms for the whole row
2422
+ /// (#1342, R1).
2423
+ pub fn id_prefix(mut self, prefix: &'a [u8]) -> Self {
2424
+ self.id_prefix = Some(prefix);
2425
+ self
2426
+ }
2427
+
2428
+ /// With an [`id_prefix`](Self::id_prefix), widen to at most `n` lists (default: every
2429
+ /// list). Never fewer than `nprobe`. Without a prefix it has no effect.
2430
+ pub fn max_probe(mut self, n: u32) -> Self {
2431
+ self.max_probe = Some(n);
2432
+ self
2433
+ }
2434
+
2435
+ /// Probe the `n` lists whose centroids are nearest the query (at least 1; the index's
2436
+ /// [`IndexOptions::nprobe`] by default). More lists, better recall, more work; with
2437
+ /// every list probed the search is exact.
2438
+ pub fn nprobe(mut self, n: u32) -> Self {
2439
+ self.nprobe = Some(n);
2440
+ self
2441
+ }
2442
+
2443
+ /// Search at `snapshot`: the centroids, the lists and their vectors as of it.
2444
+ pub fn snapshot(mut self, snapshot: &'a Snapshot) -> Self {
2445
+ self.snapshot = Some(snapshot);
2446
+ self
2447
+ }
2448
+
2449
+ /// Read the probed lists on up to `n` threads owned by the call (default 1). The
2450
+ /// result is the same at any `n`.
2451
+ pub fn parallel(mut self, n: usize) -> Self {
2452
+ self.parallel = n;
2453
+ self
2454
+ }
2455
+
2456
+ /// Runs the search: at most `k` hits, nearest first. One snapshot covers the centroids
2457
+ /// and the lists, so a concurrent split never shows a vector twice or hides it.
2458
+ ///
2459
+ /// Hits at an equal distance come back by the list that holds them, then by id (for a
2460
+ /// widened [`id_prefix`](Self::id_prefix) search, by probe round first). A split
2461
+ /// can move a tied id to another list, so which of several ids tied at the `k`-th
2462
+ /// distance makes the cut can differ between layouts; at one snapshot it's fixed.
2463
+ pub fn run(self) -> Result<Vec<Hit>> {
2464
+ Ok(self.run_with_stats()?.0)
2465
+ }
2466
+
2467
+ /// [`run`](Self::run), with what it read. A prefixed search that stopped at
2468
+ /// [`max_probe`](Self::max_probe) shows fewer hits than `k` with `lists_probed` below
2469
+ /// `lists`. [`run_async_with_stats`](Self::run_async_with_stats) is its async form.
2470
+ pub fn run_with_stats(self) -> Result<(Vec<Hit>, SearchStats)> {
2471
+ let index = self.index;
2472
+ self.query.check(index.spec())?;
2473
+ let taken;
2474
+ let s = match self.snapshot {
2475
+ Some(s) => s,
2476
+ None => {
2477
+ taken = index.snapshot()?;
2478
+ &taken
2479
+ }
2480
+ };
2481
+ let layout = index.layout_at(s, self.snapshot.is_none())?;
2482
+ let Some(order) = self.order(&layout)? else {
2483
+ return Ok((Vec::new(), self.stats(&layout, 0)));
2484
+ };
2485
+ let (mut done, mut probe) = (0, self.first_probe(&layout));
2486
+ let mut found = Vec::new();
2487
+ loop {
2488
+ let keys = rows(&order[done..probe]);
2489
+ let near = self.nearest(&keys, s).parallel(self.parallel).run()?;
2490
+ self.union(&mut found, near);
2491
+ match self.widen(&layout, probe, found.len()) {
2492
+ Some(next) => (done, probe) = (probe, next),
2493
+ None => return Ok((hits(found), self.stats(&layout, probe))),
2494
+ }
2495
+ }
2496
+ }
2497
+
2498
+ /// The lists this search may probe, nearest the query first: `nprobe` of them, or, with
2499
+ /// an [`id_prefix`](Self::id_prefix), as many as it may widen to. `None` when there's
2500
+ /// nothing to read.
2501
+ fn order(&self, layout: &Layout) -> Result<Option<Vec<u32>>> {
2502
+ if layout.lists.is_empty() || self.k == 0 {
2503
+ return Ok(None);
2504
+ }
2505
+ let first = self.first_probe(layout);
2506
+ let n = if self.id_prefix.is_some() {
2507
+ self.cap(layout, first)
2508
+ } else {
2509
+ first
2510
+ };
2511
+ Ok(Some(layout.nearest(
2512
+ self.index.cen(),
2513
+ &self.query.point(),
2514
+ n,
2515
+ &[],
2516
+ )?))
2517
+ }
2518
+
2519
+ /// Adds a round's hits to the earlier rounds'. A round widens only when the earlier
2520
+ /// ones found fewer than `k`, so `found` then holds every prefixed vector of the lists
2521
+ /// they read, and the nearest `k` of the union are the nearest of every list probed.
2522
+ /// The sort is stable: ties keep the earlier round's hits first, then each round's own
2523
+ /// order (list, then id).
2524
+ fn union(&self, found: &mut Vec<pigeonhole::Neighbour>, near: Vec<pigeonhole::Neighbour>) {
2525
+ if found.is_empty() {
2526
+ *found = near;
2527
+ return;
2528
+ }
2529
+ found.extend(near);
2530
+ found.sort_by(|a, b| a.distance.total_cmp(&b.distance));
2531
+ found.truncate(self.k);
2532
+ }
2533
+
2534
+ /// Lists to probe first: `nprobe`, at least 1, at most every list.
2535
+ fn first_probe(&self, layout: &Layout) -> usize {
2536
+ let probe = self.nprobe.unwrap_or(self.index.nprobe()).max(1) as usize;
2537
+ probe.min(layout.lists.len().max(1))
2538
+ }
2539
+
2540
+ /// After probing `probe` lists for `found` hits: how many to probe next, or `None` to
2541
+ /// stop. Only a prefixed search short of `k` widens, doubling up to `max_probe`.
2542
+ fn widen(&self, layout: &Layout, probe: usize, found: usize) -> Option<usize> {
2543
+ self.id_prefix?;
2544
+ let cap = self.cap(layout, probe);
2545
+ (found < self.k && probe < cap).then(|| probe.saturating_mul(2).min(cap))
2546
+ }
2547
+
2548
+ /// The most lists a prefixed search widens to: `max_probe` (default every list), at
2549
+ /// least `first`.
2550
+ fn cap(&self, layout: &Layout, first: usize) -> usize {
2551
+ let all = layout.lists.len();
2552
+ self.max_probe
2553
+ .map_or(all, |m| (m as usize).min(all))
2554
+ .max(first)
2555
+ }
2556
+
2557
+ fn stats(&self, layout: &Layout, probed: usize) -> SearchStats {
2558
+ let n = |x: usize| u32::try_from(x).unwrap_or(u32::MAX);
2559
+ SearchStats {
2560
+ lists_probed: n(probed),
2561
+ lists: n(layout.lists.len()),
2562
+ }
2563
+ }
2564
+
2565
+ /// [`run`](Self::run) as a future that never blocks on the device (D296 PR 5): the
2566
+ /// layout version is read with `get_at_async`, a layout that changed is reloaded through
2567
+ /// an async scan, and the probed lists are read with `Nearest::run_async`, which yields
2568
+ /// within a wide list. Its result equals `run`'s. It never fans out:
2569
+ /// [`parallel`](Self::parallel) is ignored. The future is `Send`.
2570
+ #[cfg(feature = "async")]
2571
+ pub async fn run_async(self) -> Result<Vec<Hit>> {
2572
+ Ok(self.run_async_with_stats().await?.0)
2573
+ }
2574
+
2575
+ /// [`run_async`](Self::run_async), with what it read, as
2576
+ /// [`run_with_stats`](Self::run_with_stats) reports it. The future is `Send`.
2577
+ #[cfg(feature = "async")]
2578
+ pub async fn run_async_with_stats(self) -> Result<(Vec<Hit>, SearchStats)> {
2579
+ let index = self.index;
2580
+ self.query.check(index.spec())?;
2581
+ let taken;
2582
+ let s = match self.snapshot {
2583
+ Some(s) => s,
2584
+ None => {
2585
+ taken = index.snapshot()?;
2586
+ &taken
2587
+ }
2588
+ };
2589
+ let layout = index.layout_at_async(s, self.snapshot.is_none()).await?;
2590
+ let Some(order) = self.order(&layout)? else {
2591
+ return Ok((Vec::new(), self.stats(&layout, 0)));
2592
+ };
2593
+ let (mut done, mut probe) = (0, self.first_probe(&layout));
2594
+ let mut found = Vec::new();
2595
+ loop {
2596
+ let keys = rows(&order[done..probe]);
2597
+ let near = self.nearest(&keys, s).run_async().await?;
2598
+ self.union(&mut found, near);
2599
+ match self.widen(&layout, probe, found.len()) {
2600
+ Some(next) => (done, probe) = (probe, next),
2601
+ None => return Ok((hits(found), self.stats(&layout, probe))),
2602
+ }
2603
+ }
2604
+ }
2605
+
2606
+ fn nearest(&self, keys: &KeySet, s: &Snapshot) -> pigeonhole::Nearest<'a> {
2607
+ let mut read = self.index.rows_of(keys).family(VEC).snapshot(s);
2608
+ if let Some(p) = self.id_prefix {
2609
+ read = read.qualifier_prefix(p);
2610
+ }
2611
+ match self.query {
2612
+ Input::F32(q) => read.nearest_f32(q, self.k),
2613
+ Input::I8(q) => read.nearest_i8(q, self.k),
2614
+ Input::Bits(q) => read.nearest_bits(q, self.k),
2615
+ // A half query widens exactly and searches as `f32` (`nearest_f32` takes a half
2616
+ // family; there's no `nearest_f16`). The search keeps its own copy.
2617
+ q @ (Input::F16(_) | Input::BF16(_)) => {
2618
+ let mut widened = Vec::new();
2619
+ q.widen_into(&mut widened);
2620
+ read.nearest_f32(&widened, self.k)
2621
+ }
2622
+ }
2623
+ }
2624
+ }
2625
+
2626
+ #[cfg(test)]
2627
+ mod tests {
2628
+ use super::*;
2629
+
2630
+ fn layout(seqno: u64, version: u64) -> Layout {
2631
+ Layout {
2632
+ seqno,
2633
+ version,
2634
+ lists: Vec::new(),
2635
+ }
2636
+ }
2637
+
2638
+ /// The shared layout cache (rev 3 S4, perf287 on #1385): a search at the current snapshot
2639
+ /// adopts a newer layout, never an older one a slower search loaded, and does adopt one
2640
+ /// when the cache is from beyond the latest visible seqno (commits a restarted writer
2641
+ /// lost). A search at an older snapshot never adopts.
2642
+ #[test]
2643
+ fn the_layout_cache_adopts_newer_layouts_and_drops_a_lost_tails() {
2644
+ let cache = RwLock::new(Arc::new(layout(100, 5)));
2645
+ let at = |c: &RwLock<Arc<Layout>>| (c.read().unwrap().seqno, c.read().unwrap().version);
2646
+ let now_120 = || Some(120);
2647
+ let now: &dyn Fn() -> Option<u64> = &now_120;
2648
+ // A slower search's older layout, the cache still visible: kept.
2649
+ adopt(&cache, layout(90, 4), Some(now));
2650
+ assert_eq!(at(&cache), (100, 5));
2651
+ // A newer one: adopted.
2652
+ adopt(&cache, layout(110, 6), Some(now));
2653
+ assert_eq!(at(&cache), (110, 6));
2654
+ // Not at the current snapshot: never adopted.
2655
+ adopt(&cache, layout(115, 7), None);
2656
+ assert_eq!(at(&cache), (110, 6));
2657
+ // The writer lost its tail: the latest visible seqno is 60, below the cache's 110.
2658
+ // The fresh layout (seqno 55) replaces it, and later loads adopt as usual.
2659
+ let now_60 = || Some(60);
2660
+ let lost: &dyn Fn() -> Option<u64> = &now_60;
2661
+ adopt(&cache, layout(55, 3), Some(lost));
2662
+ assert_eq!(at(&cache), (55, 3));
2663
+ adopt(&cache, layout(58, 4), Some(lost));
2664
+ assert_eq!(at(&cache), (58, 4));
2665
+ // The latest seqno unknown (the snapshot failed): an older layout is kept.
2666
+ let unknown = || None;
2667
+ let unknown: &dyn Fn() -> Option<u64> = &unknown;
2668
+ adopt(&cache, layout(50, 2), Some(unknown));
2669
+ assert_eq!(at(&cache), (58, 4));
2670
+ }
2671
+
2672
+ #[test]
2673
+ fn options_round_trip_and_scale_for_large_vectors() {
2674
+ let o = IndexOptions::new()
2675
+ .target_list_len(7)
2676
+ .nprobe(3)
2677
+ .reassign_neighbours(0);
2678
+ assert_eq!(IndexOptions::decode(&o.encode()), Some(o));
2679
+ assert_eq!(IndexOptions::decode(&[2]), None);
2680
+ let wide = VectorSpec::new(4096, Element::F32, pigeonhole::Metric::L2).unwrap();
2681
+ // 2 × target × 16 KiB ≤ 4 MiB.
2682
+ assert_eq!(IndexOptions::new().checked(&wide).unwrap().target, 128);
2683
+ assert!(
2684
+ IndexOptions::new()
2685
+ .target_list_len(3)
2686
+ .checked(&wide)
2687
+ .is_err()
2688
+ );
2689
+ }
2690
+ }