usearch 2.21.3 → 2.25.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.
- package/README.md +24 -24
- package/binding.gyp +15 -37
- package/c/CMakeLists.txt +4 -5
- package/c/README.md +7 -7
- package/c/lib.cpp +32 -14
- package/c/test.c +83 -1
- package/c/usearch.h +24 -3
- package/cpp/CMakeLists.txt +4 -0
- package/cpp/README.md +5 -5
- package/cpp/bench.cpp +97 -116
- package/cpp/test.cpp +117 -20
- package/include/usearch/index.hpp +235 -52
- package/include/usearch/index_dense.hpp +105 -40
- package/include/usearch/index_plugins.hpp +1387 -204
- package/javascript/dist/cjs/usearch.d.ts +8 -3
- package/javascript/dist/cjs/usearch.js +12 -4
- package/javascript/dist/esm/usearch.d.ts +8 -3
- package/javascript/dist/esm/usearch.js +12 -4
- package/javascript/lib.cpp +17 -0
- package/javascript/usearch.ts +14 -6
- package/numkong/.clang-tidy +30 -0
- package/{simsimd → numkong}/.cmake-format.py +18 -0
- package/numkong/.editorconfig +12 -0
- package/numkong/.git-blame-ignore-revs +123 -0
- package/numkong/.mailmap +15 -0
- package/numkong/.spi.yml +11 -0
- package/numkong/.swift-format +14 -0
- package/numkong/CITATION.cff +81 -0
- package/numkong/CONTRIBUTING.md +500 -0
- package/numkong/Cargo.toml +54 -0
- package/numkong/MANIFEST.in +8 -0
- package/numkong/Package.swift +84 -0
- package/numkong/README.md +569 -0
- package/numkong/bench/README.md +217 -0
- package/numkong/bench/bench-browser.html +323 -0
- package/numkong/bench/bench.cpp +344 -0
- package/numkong/bench/bench.hpp +816 -0
- package/numkong/bench/bench.js +148 -0
- package/numkong/bench/bench.mjs +616 -0
- package/numkong/bench/bench_attention.cpp +113 -0
- package/numkong/bench/bench_cast.cpp +264 -0
- package/numkong/bench/bench_cross_amx.cpp +62 -0
- package/numkong/bench/bench_cross_arm.cpp +245 -0
- package/numkong/bench/bench_cross_blas.cpp +309 -0
- package/numkong/bench/bench_cross_loongarch.cpp +106 -0
- package/numkong/bench/bench_cross_power.cpp +84 -0
- package/numkong/bench/bench_cross_rvv.cpp +121 -0
- package/numkong/bench/bench_cross_serial.cpp +151 -0
- package/numkong/bench/bench_cross_sme.cpp +163 -0
- package/numkong/bench/bench_cross_wasm.cpp +142 -0
- package/numkong/bench/bench_cross_x86.cpp +455 -0
- package/numkong/bench/bench_curved.cpp +210 -0
- package/numkong/bench/bench_dot.cpp +315 -0
- package/numkong/bench/bench_each.cpp +503 -0
- package/numkong/bench/bench_geospatial.cpp +112 -0
- package/numkong/bench/bench_maxsim.cpp +154 -0
- package/numkong/bench/bench_mesh.cpp +148 -0
- package/numkong/bench/bench_probability.cpp +60 -0
- package/numkong/bench/bench_reduce.cpp +371 -0
- package/numkong/bench/bench_set.cpp +73 -0
- package/numkong/bench/bench_sparse.cpp +198 -0
- package/numkong/bench/bench_spatial.cpp +347 -0
- package/numkong/bench/bench_trigonometry.cpp +137 -0
- package/numkong/bench/swift/Bench.swift +506 -0
- package/numkong/binding.gyp +169 -0
- package/numkong/build.rs +484 -0
- package/numkong/c/dispatch.h +512 -0
- package/numkong/c/dispatch_bf16.c +447 -0
- package/numkong/c/dispatch_bf16c.c +52 -0
- package/numkong/c/dispatch_e2m3.c +296 -0
- package/numkong/c/dispatch_e3m2.c +284 -0
- package/numkong/c/dispatch_e4m3.c +318 -0
- package/numkong/c/dispatch_e5m2.c +316 -0
- package/numkong/c/dispatch_f16.c +452 -0
- package/numkong/c/dispatch_f16c.c +58 -0
- package/numkong/c/dispatch_f32.c +434 -0
- package/numkong/c/dispatch_f32c.c +99 -0
- package/numkong/c/dispatch_f64.c +348 -0
- package/numkong/c/dispatch_f64c.c +98 -0
- package/numkong/c/dispatch_i16.c +96 -0
- package/numkong/c/dispatch_i32.c +89 -0
- package/numkong/c/dispatch_i4.c +153 -0
- package/numkong/c/dispatch_i64.c +86 -0
- package/numkong/c/dispatch_i8.c +348 -0
- package/numkong/c/dispatch_other.c +348 -0
- package/numkong/c/dispatch_u1.c +193 -0
- package/numkong/c/dispatch_u16.c +124 -0
- package/numkong/c/dispatch_u32.c +118 -0
- package/numkong/c/dispatch_u4.c +153 -0
- package/numkong/c/dispatch_u64.c +102 -0
- package/numkong/c/dispatch_u8.c +364 -0
- package/numkong/c/numkong.c +940 -0
- package/numkong/cmake/nk_arm_isa_probes.cmake +61 -0
- package/numkong/cmake/nk_isa_probe.cmake +90 -0
- package/numkong/cmake/nk_loongarch_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_math_lib.cmake +46 -0
- package/numkong/cmake/nk_power_isa_probes.cmake +15 -0
- package/numkong/cmake/nk_riscv_isa_probes.cmake +19 -0
- package/numkong/cmake/nk_x86_isa_probes.cmake +35 -0
- package/numkong/cmake/toolchain-aarch64-gnu.cmake +86 -0
- package/numkong/cmake/toolchain-android-arm64.cmake +25 -0
- package/numkong/cmake/toolchain-android-armv7.cmake +25 -0
- package/numkong/cmake/toolchain-loongarch64-gnu.cmake +68 -0
- package/numkong/cmake/toolchain-ppc64le-gnu.cmake +74 -0
- package/numkong/cmake/toolchain-riscv64-gnu.cmake +107 -0
- package/numkong/cmake/toolchain-riscv64-llvm.cmake +114 -0
- package/numkong/cmake/toolchain-wasi.cmake +77 -0
- package/numkong/cmake/toolchain-wasm.cmake +70 -0
- package/numkong/cmake/toolchain-wasm64.cmake +62 -0
- package/numkong/cmake/toolchain-x86_64-llvm.cmake +47 -0
- package/numkong/include/README.md +643 -0
- package/numkong/include/module.modulemap +129 -0
- package/numkong/include/numkong/attention/sapphireamx.h +1363 -0
- package/numkong/include/numkong/attention/sme.h +2075 -0
- package/numkong/include/numkong/attention.h +49 -0
- package/numkong/include/numkong/capabilities.h +930 -0
- package/numkong/include/numkong/cast/README.md +262 -0
- package/numkong/include/numkong/cast/diamond.h +64 -0
- package/numkong/include/numkong/cast/haswell.h +823 -0
- package/numkong/include/numkong/cast/icelake.h +475 -0
- package/numkong/include/numkong/cast/loongsonasx.h +252 -0
- package/numkong/include/numkong/cast/neon.h +1174 -0
- package/numkong/include/numkong/cast/powervsx.h +449 -0
- package/numkong/include/numkong/cast/rvv.h +970 -0
- package/numkong/include/numkong/cast/sapphire.h +262 -0
- package/numkong/include/numkong/cast/serial.h +2336 -0
- package/numkong/include/numkong/cast/skylake.h +915 -0
- package/numkong/include/numkong/cast/v128relaxed.h +537 -0
- package/numkong/include/numkong/cast.h +254 -0
- package/numkong/include/numkong/cast.hpp +44 -0
- package/numkong/include/numkong/curved/README.md +223 -0
- package/numkong/include/numkong/curved/genoa.h +182 -0
- package/numkong/include/numkong/curved/haswell.h +276 -0
- package/numkong/include/numkong/curved/neon.h +329 -0
- package/numkong/include/numkong/curved/neonbfdot.h +211 -0
- package/numkong/include/numkong/curved/rvv.h +305 -0
- package/numkong/include/numkong/curved/serial.h +207 -0
- package/numkong/include/numkong/curved/skylake.h +457 -0
- package/numkong/include/numkong/curved/smef64.h +530 -0
- package/numkong/include/numkong/curved.h +513 -0
- package/numkong/include/numkong/curved.hpp +144 -0
- package/numkong/include/numkong/dot/README.md +442 -0
- package/numkong/include/numkong/dot/alder.h +563 -0
- package/numkong/include/numkong/dot/diamond.h +158 -0
- package/numkong/include/numkong/dot/genoa.h +289 -0
- package/numkong/include/numkong/dot/haswell.h +1723 -0
- package/numkong/include/numkong/dot/icelake.h +997 -0
- package/numkong/include/numkong/dot/loongsonasx.h +671 -0
- package/numkong/include/numkong/dot/neon.h +869 -0
- package/numkong/include/numkong/dot/neonbfdot.h +243 -0
- package/numkong/include/numkong/dot/neonfhm.h +358 -0
- package/numkong/include/numkong/dot/neonfp8.h +323 -0
- package/numkong/include/numkong/dot/neonsdot.h +622 -0
- package/numkong/include/numkong/dot/powervsx.h +752 -0
- package/numkong/include/numkong/dot/rvv.h +722 -0
- package/numkong/include/numkong/dot/rvvbb.h +72 -0
- package/numkong/include/numkong/dot/rvvbf16.h +123 -0
- package/numkong/include/numkong/dot/rvvhalf.h +129 -0
- package/numkong/include/numkong/dot/sapphire.h +141 -0
- package/numkong/include/numkong/dot/serial.h +874 -0
- package/numkong/include/numkong/dot/sierra.h +405 -0
- package/numkong/include/numkong/dot/skylake.h +1116 -0
- package/numkong/include/numkong/dot/sve.h +420 -0
- package/numkong/include/numkong/dot/svebfdot.h +75 -0
- package/numkong/include/numkong/dot/svehalf.h +168 -0
- package/numkong/include/numkong/dot/svesdot.h +90 -0
- package/numkong/include/numkong/dot/v128relaxed.h +1293 -0
- package/numkong/include/numkong/dot.h +1136 -0
- package/numkong/include/numkong/dot.hpp +94 -0
- package/numkong/include/numkong/dots/README.md +496 -0
- package/numkong/include/numkong/dots/alder.h +117 -0
- package/numkong/include/numkong/dots/diamond.h +86 -0
- package/numkong/include/numkong/dots/genoa.h +100 -0
- package/numkong/include/numkong/dots/graniteamx.h +733 -0
- package/numkong/include/numkong/dots/haswell.h +310 -0
- package/numkong/include/numkong/dots/icelake.h +180 -0
- package/numkong/include/numkong/dots/loongsonasx.h +176 -0
- package/numkong/include/numkong/dots/neon.h +123 -0
- package/numkong/include/numkong/dots/neonbfdot.h +59 -0
- package/numkong/include/numkong/dots/neonfhm.h +96 -0
- package/numkong/include/numkong/dots/neonfp8.h +99 -0
- package/numkong/include/numkong/dots/neonsdot.h +144 -0
- package/numkong/include/numkong/dots/powervsx.h +194 -0
- package/numkong/include/numkong/dots/rvv.h +2593 -0
- package/numkong/include/numkong/dots/sapphireamx.h +4017 -0
- package/numkong/include/numkong/dots/serial.h +2867 -0
- package/numkong/include/numkong/dots/sierra.h +100 -0
- package/numkong/include/numkong/dots/skylake.h +207 -0
- package/numkong/include/numkong/dots/sme.h +5041 -0
- package/numkong/include/numkong/dots/smebi32.h +477 -0
- package/numkong/include/numkong/dots/smef64.h +1328 -0
- package/numkong/include/numkong/dots/smehalf.h +47 -0
- package/numkong/include/numkong/dots/v128relaxed.h +317 -0
- package/numkong/include/numkong/dots.h +3110 -0
- package/numkong/include/numkong/dots.hpp +641 -0
- package/numkong/include/numkong/each/README.md +465 -0
- package/numkong/include/numkong/each/haswell.h +1658 -0
- package/numkong/include/numkong/each/icelake.h +272 -0
- package/numkong/include/numkong/each/neon.h +1138 -0
- package/numkong/include/numkong/each/neonbfdot.h +211 -0
- package/numkong/include/numkong/each/neonhalf.h +318 -0
- package/numkong/include/numkong/each/rvv.h +1121 -0
- package/numkong/include/numkong/each/sapphire.h +343 -0
- package/numkong/include/numkong/each/serial.h +282 -0
- package/numkong/include/numkong/each/skylake.h +1562 -0
- package/numkong/include/numkong/each/v128relaxed.h +562 -0
- package/numkong/include/numkong/each.h +2232 -0
- package/numkong/include/numkong/each.hpp +434 -0
- package/numkong/include/numkong/geospatial/README.md +147 -0
- package/numkong/include/numkong/geospatial/haswell.h +633 -0
- package/numkong/include/numkong/geospatial/neon.h +615 -0
- package/numkong/include/numkong/geospatial/rvv.h +701 -0
- package/numkong/include/numkong/geospatial/serial.h +309 -0
- package/numkong/include/numkong/geospatial/skylake.h +613 -0
- package/numkong/include/numkong/geospatial/v128relaxed.h +652 -0
- package/numkong/include/numkong/geospatial.h +453 -0
- package/numkong/include/numkong/geospatial.hpp +235 -0
- package/numkong/include/numkong/matrix.hpp +336 -0
- package/numkong/include/numkong/maxsim/README.md +187 -0
- package/numkong/include/numkong/maxsim/alder.h +511 -0
- package/numkong/include/numkong/maxsim/genoa.h +115 -0
- package/numkong/include/numkong/maxsim/haswell.h +553 -0
- package/numkong/include/numkong/maxsim/icelake.h +480 -0
- package/numkong/include/numkong/maxsim/neonsdot.h +394 -0
- package/numkong/include/numkong/maxsim/sapphireamx.h +877 -0
- package/numkong/include/numkong/maxsim/serial.h +490 -0
- package/numkong/include/numkong/maxsim/sme.h +993 -0
- package/numkong/include/numkong/maxsim/v128relaxed.h +280 -0
- package/numkong/include/numkong/maxsim.h +571 -0
- package/numkong/include/numkong/maxsim.hpp +133 -0
- package/numkong/include/numkong/mesh/README.md +219 -0
- package/numkong/include/numkong/mesh/haswell.h +2013 -0
- package/numkong/include/numkong/mesh/neon.h +1821 -0
- package/numkong/include/numkong/mesh/neonbfdot.h +771 -0
- package/numkong/include/numkong/mesh/rvv.h +936 -0
- package/numkong/include/numkong/mesh/serial.h +721 -0
- package/numkong/include/numkong/mesh/skylake.h +2344 -0
- package/numkong/include/numkong/mesh/v128relaxed.h +1081 -0
- package/numkong/include/numkong/mesh.h +666 -0
- package/numkong/include/numkong/mesh.hpp +701 -0
- package/numkong/include/numkong/numkong.h +78 -0
- package/numkong/include/numkong/numkong.hpp +58 -0
- package/numkong/include/numkong/probability/README.md +177 -0
- package/numkong/include/numkong/probability/haswell.h +267 -0
- package/numkong/include/numkong/probability/neon.h +255 -0
- package/numkong/include/numkong/probability/rvv.h +414 -0
- package/numkong/include/numkong/probability/serial.h +181 -0
- package/numkong/include/numkong/probability/skylake.h +324 -0
- package/numkong/include/numkong/probability.h +380 -0
- package/numkong/include/numkong/probability.hpp +120 -0
- package/numkong/include/numkong/random.h +50 -0
- package/numkong/include/numkong/random.hpp +285 -0
- package/numkong/include/numkong/reduce/README.md +552 -0
- package/numkong/include/numkong/reduce/alder.h +636 -0
- package/numkong/include/numkong/reduce/genoa.h +201 -0
- package/numkong/include/numkong/reduce/haswell.h +3785 -0
- package/numkong/include/numkong/reduce/icelake.h +549 -0
- package/numkong/include/numkong/reduce/neon.h +3980 -0
- package/numkong/include/numkong/reduce/neonbfdot.h +142 -0
- package/numkong/include/numkong/reduce/neonfhm.h +293 -0
- package/numkong/include/numkong/reduce/neonsdot.h +357 -0
- package/numkong/include/numkong/reduce/rvv.h +3533 -0
- package/numkong/include/numkong/reduce/serial.h +753 -0
- package/numkong/include/numkong/reduce/sierra.h +338 -0
- package/numkong/include/numkong/reduce/skylake.h +3794 -0
- package/numkong/include/numkong/reduce/sve.h +52 -0
- package/numkong/include/numkong/reduce/v128relaxed.h +2302 -0
- package/numkong/include/numkong/reduce.h +1582 -0
- package/numkong/include/numkong/reduce.hpp +778 -0
- package/numkong/include/numkong/scalar/README.md +89 -0
- package/numkong/include/numkong/scalar/haswell.h +122 -0
- package/numkong/include/numkong/scalar/loongsonasx.h +74 -0
- package/numkong/include/numkong/scalar/neon.h +122 -0
- package/numkong/include/numkong/scalar/neonhalf.h +70 -0
- package/numkong/include/numkong/scalar/powervsx.h +96 -0
- package/numkong/include/numkong/scalar/rvv.h +211 -0
- package/numkong/include/numkong/scalar/sapphire.h +74 -0
- package/numkong/include/numkong/scalar/serial.h +332 -0
- package/numkong/include/numkong/scalar/v128relaxed.h +56 -0
- package/numkong/include/numkong/scalar.h +696 -0
- package/numkong/include/numkong/set/README.md +179 -0
- package/numkong/include/numkong/set/haswell.h +334 -0
- package/numkong/include/numkong/set/icelake.h +485 -0
- package/numkong/include/numkong/set/loongsonasx.h +181 -0
- package/numkong/include/numkong/set/neon.h +363 -0
- package/numkong/include/numkong/set/powervsx.h +326 -0
- package/numkong/include/numkong/set/rvv.h +226 -0
- package/numkong/include/numkong/set/rvvbb.h +117 -0
- package/numkong/include/numkong/set/serial.h +174 -0
- package/numkong/include/numkong/set/sve.h +187 -0
- package/numkong/include/numkong/set/v128relaxed.h +240 -0
- package/numkong/include/numkong/set.h +471 -0
- package/numkong/include/numkong/set.hpp +114 -0
- package/numkong/include/numkong/sets/README.md +149 -0
- package/numkong/include/numkong/sets/haswell.h +63 -0
- package/numkong/include/numkong/sets/icelake.h +66 -0
- package/numkong/include/numkong/sets/loongsonasx.h +52 -0
- package/numkong/include/numkong/sets/neon.h +61 -0
- package/numkong/include/numkong/sets/powervsx.h +65 -0
- package/numkong/include/numkong/sets/serial.h +43 -0
- package/numkong/include/numkong/sets/smebi32.h +1135 -0
- package/numkong/include/numkong/sets/v128relaxed.h +58 -0
- package/numkong/include/numkong/sets.h +382 -0
- package/numkong/include/numkong/sparse/README.md +156 -0
- package/numkong/include/numkong/sparse/icelake.h +463 -0
- package/numkong/include/numkong/sparse/neon.h +288 -0
- package/numkong/include/numkong/sparse/serial.h +117 -0
- package/numkong/include/numkong/sparse/sve2.h +504 -0
- package/numkong/include/numkong/sparse/turin.h +322 -0
- package/numkong/include/numkong/sparse.h +363 -0
- package/numkong/include/numkong/sparse.hpp +113 -0
- package/numkong/include/numkong/spatial/README.md +439 -0
- package/numkong/include/numkong/spatial/alder.h +604 -0
- package/numkong/include/numkong/spatial/diamond.h +240 -0
- package/numkong/include/numkong/spatial/genoa.h +222 -0
- package/numkong/include/numkong/spatial/haswell.h +979 -0
- package/numkong/include/numkong/spatial/icelake.h +1067 -0
- package/numkong/include/numkong/spatial/loongsonasx.h +483 -0
- package/numkong/include/numkong/spatial/neon.h +846 -0
- package/numkong/include/numkong/spatial/neonbfdot.h +164 -0
- package/numkong/include/numkong/spatial/neonfp8.h +258 -0
- package/numkong/include/numkong/spatial/neonsdot.h +429 -0
- package/numkong/include/numkong/spatial/powervsx.h +738 -0
- package/numkong/include/numkong/spatial/rvv.h +991 -0
- package/numkong/include/numkong/spatial/rvvbf16.h +128 -0
- package/numkong/include/numkong/spatial/rvvhalf.h +120 -0
- package/numkong/include/numkong/spatial/serial.h +347 -0
- package/numkong/include/numkong/spatial/sierra.h +516 -0
- package/numkong/include/numkong/spatial/skylake.h +605 -0
- package/numkong/include/numkong/spatial/sve.h +246 -0
- package/numkong/include/numkong/spatial/svebfdot.h +125 -0
- package/numkong/include/numkong/spatial/svehalf.h +136 -0
- package/numkong/include/numkong/spatial/svesdot.h +143 -0
- package/numkong/include/numkong/spatial/v128relaxed.h +969 -0
- package/numkong/include/numkong/spatial.h +1681 -0
- package/numkong/include/numkong/spatial.hpp +183 -0
- package/numkong/include/numkong/spatials/README.md +580 -0
- package/numkong/include/numkong/spatials/alder.h +94 -0
- package/numkong/include/numkong/spatials/diamond.h +82 -0
- package/numkong/include/numkong/spatials/genoa.h +94 -0
- package/numkong/include/numkong/spatials/graniteamx.h +173 -0
- package/numkong/include/numkong/spatials/haswell.h +219 -0
- package/numkong/include/numkong/spatials/icelake.h +113 -0
- package/numkong/include/numkong/spatials/loongsonasx.h +153 -0
- package/numkong/include/numkong/spatials/neon.h +109 -0
- package/numkong/include/numkong/spatials/neonbfdot.h +60 -0
- package/numkong/include/numkong/spatials/neonfhm.h +92 -0
- package/numkong/include/numkong/spatials/neonfp8.h +111 -0
- package/numkong/include/numkong/spatials/neonsdot.h +143 -0
- package/numkong/include/numkong/spatials/powervsx.h +153 -0
- package/numkong/include/numkong/spatials/rvv.h +1976 -0
- package/numkong/include/numkong/spatials/sapphireamx.h +1149 -0
- package/numkong/include/numkong/spatials/serial.h +248 -0
- package/numkong/include/numkong/spatials/sierra.h +96 -0
- package/numkong/include/numkong/spatials/skylake.h +184 -0
- package/numkong/include/numkong/spatials/sme.h +1927 -0
- package/numkong/include/numkong/spatials/smef64.h +483 -0
- package/numkong/include/numkong/spatials/v128relaxed.h +240 -0
- package/numkong/include/numkong/spatials.h +3374 -0
- package/numkong/include/numkong/spatials.hpp +509 -0
- package/numkong/include/numkong/tensor.hpp +1981 -0
- package/numkong/include/numkong/trigonometry/README.md +184 -0
- package/numkong/include/numkong/trigonometry/haswell.h +653 -0
- package/numkong/include/numkong/trigonometry/neon.h +638 -0
- package/numkong/include/numkong/trigonometry/rvv.h +700 -0
- package/numkong/include/numkong/trigonometry/serial.h +703 -0
- package/numkong/include/numkong/trigonometry/skylake.h +725 -0
- package/numkong/include/numkong/trigonometry/v128relaxed.h +667 -0
- package/numkong/include/numkong/trigonometry.h +467 -0
- package/numkong/include/numkong/trigonometry.hpp +166 -0
- package/numkong/include/numkong/types.h +1695 -0
- package/numkong/include/numkong/types.hpp +6027 -0
- package/numkong/include/numkong/vector.hpp +766 -0
- package/numkong/javascript/@numkong-darwin-arm64/package.json +26 -0
- package/numkong/javascript/@numkong-darwin-x64/package.json +26 -0
- package/numkong/javascript/@numkong-linux-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-linux-x64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-arm64/package.json +25 -0
- package/numkong/javascript/@numkong-win32-x64/package.json +25 -0
- package/numkong/javascript/README.md +254 -0
- package/numkong/javascript/node-gyp-build.d.ts +4 -0
- package/numkong/javascript/numkong-browser.ts +40 -0
- package/numkong/javascript/numkong-wasm.ts +750 -0
- package/numkong/javascript/numkong.c +712 -0
- package/numkong/javascript/numkong.ts +613 -0
- package/{simsimd → numkong}/javascript/tsconfig-base.json +6 -3
- package/numkong/javascript/tsconfig-cjs.json +13 -0
- package/{simsimd → numkong}/javascript/tsconfig-esm.json +1 -1
- package/numkong/javascript/types.ts +784 -0
- package/numkong/numkong.gypi +104 -0
- package/numkong/package.json +108 -0
- package/numkong/probes/arm_neon.c +8 -0
- package/numkong/probes/arm_neon_bfdot.c +9 -0
- package/numkong/probes/arm_neon_fhm.c +9 -0
- package/numkong/probes/arm_neon_half.c +8 -0
- package/numkong/probes/arm_neon_sdot.c +9 -0
- package/numkong/probes/arm_neonfp8.c +9 -0
- package/numkong/probes/arm_sme.c +16 -0
- package/numkong/probes/arm_sme2.c +16 -0
- package/numkong/probes/arm_sme2p1.c +16 -0
- package/numkong/probes/arm_sme_bf16.c +16 -0
- package/numkong/probes/arm_sme_bi32.c +16 -0
- package/numkong/probes/arm_sme_f64.c +16 -0
- package/numkong/probes/arm_sme_fa64.c +14 -0
- package/numkong/probes/arm_sme_half.c +16 -0
- package/numkong/probes/arm_sme_lut2.c +15 -0
- package/numkong/probes/arm_sve.c +18 -0
- package/numkong/probes/arm_sve2.c +20 -0
- package/numkong/probes/arm_sve2p1.c +18 -0
- package/numkong/probes/arm_sve_bfdot.c +20 -0
- package/numkong/probes/arm_sve_half.c +18 -0
- package/numkong/probes/arm_sve_sdot.c +21 -0
- package/numkong/probes/loongarch_lasx.c +12 -0
- package/numkong/probes/power_vsx.c +12 -0
- package/numkong/probes/probe.js +127 -0
- package/numkong/probes/riscv_rvv.c +14 -0
- package/numkong/probes/riscv_rvv_bb.c +15 -0
- package/numkong/probes/riscv_rvv_bf16.c +17 -0
- package/numkong/probes/riscv_rvv_half.c +14 -0
- package/numkong/probes/wasm_v128relaxed.c +11 -0
- package/numkong/probes/x86_alder.c +17 -0
- package/numkong/probes/x86_diamond.c +17 -0
- package/numkong/probes/x86_genoa.c +17 -0
- package/numkong/probes/x86_graniteamx.c +19 -0
- package/numkong/probes/x86_haswell.c +11 -0
- package/numkong/probes/x86_icelake.c +17 -0
- package/numkong/probes/x86_sapphire.c +16 -0
- package/numkong/probes/x86_sapphireamx.c +18 -0
- package/numkong/probes/x86_sierra.c +17 -0
- package/numkong/probes/x86_skylake.c +15 -0
- package/numkong/probes/x86_turin.c +17 -0
- package/numkong/rust/README.md +698 -0
- package/numkong/rust/capabilities.rs +96 -0
- package/numkong/rust/cast.rs +314 -0
- package/numkong/rust/curved.rs +391 -0
- package/numkong/rust/each.rs +2721 -0
- package/numkong/rust/geospatial.rs +343 -0
- package/numkong/rust/matrix.rs +5424 -0
- package/numkong/rust/maxsim.rs +540 -0
- package/numkong/rust/mesh.rs +837 -0
- package/numkong/rust/numkong.rs +409 -0
- package/numkong/rust/probability.rs +272 -0
- package/numkong/rust/reduce.rs +1249 -0
- package/numkong/rust/set.rs +194 -0
- package/numkong/rust/sparse.rs +513 -0
- package/numkong/rust/spatial.rs +1815 -0
- package/numkong/rust/tensor.rs +7565 -0
- package/numkong/rust/types.rs +3666 -0
- package/numkong/rust/vector.rs +1899 -0
- package/numkong/rustfmt.toml +2 -0
- package/numkong/swift/Matrix.swift +1388 -0
- package/numkong/swift/MaxSim.swift +151 -0
- package/numkong/swift/NumKong.swift +283 -0
- package/numkong/swift/Numerics.swift +329 -0
- package/numkong/swift/README.md +433 -0
- package/numkong/swift/Scalar.swift +741 -0
- package/numkong/swift/Tensor.swift +209 -0
- package/numkong/test/README.md +315 -0
- package/numkong/test/playwright.config.ts +16 -0
- package/numkong/test/swift/Test.swift +534 -0
- package/numkong/test/test-browser-bundle-runner.mjs +36 -0
- package/numkong/test/test-browser-bundle.html +188 -0
- package/numkong/test/test-browser-runner.mjs +43 -0
- package/numkong/test/test-browser.html +305 -0
- package/numkong/test/test-dtypes.mjs +453 -0
- package/numkong/test/test-wasm.mjs +267 -0
- package/numkong/test/test.cpp +442 -0
- package/numkong/test/test.hpp +580 -0
- package/numkong/test/test.mjs +363 -0
- package/numkong/test/test_base.py +1041 -0
- package/numkong/test/test_cast.cpp +242 -0
- package/numkong/test/test_cross.hpp +551 -0
- package/numkong/test/test_cross.py +467 -0
- package/numkong/test/test_cross_amx.cpp +50 -0
- package/numkong/test/test_cross_arm.cpp +225 -0
- package/numkong/test/test_cross_blas.cpp +354 -0
- package/numkong/test/test_cross_loongarch.cpp +90 -0
- package/numkong/test/test_cross_power.cpp +73 -0
- package/numkong/test/test_cross_rvv.cpp +109 -0
- package/numkong/test/test_cross_serial.cpp +181 -0
- package/numkong/test/test_cross_sme.cpp +148 -0
- package/numkong/test/test_cross_wasm.cpp +141 -0
- package/numkong/test/test_cross_x86.cpp +442 -0
- package/numkong/test/test_curved.cpp +182 -0
- package/numkong/test/test_curved.py +207 -0
- package/numkong/test/test_dot.cpp +353 -0
- package/numkong/test/test_dot.py +296 -0
- package/numkong/test/test_each.cpp +437 -0
- package/numkong/test/test_each.py +756 -0
- package/numkong/test/test_geospatial.cpp +155 -0
- package/numkong/test/test_geospatial.py +241 -0
- package/numkong/test/test_maxsim.cpp +138 -0
- package/numkong/test/test_maxsim.py +209 -0
- package/numkong/test/test_mesh.cpp +203 -0
- package/numkong/test/test_mesh.py +394 -0
- package/numkong/test/test_probability.cpp +136 -0
- package/numkong/test/test_probability.py +166 -0
- package/numkong/test/test_reduce.cpp +563 -0
- package/numkong/test/test_reduce.py +781 -0
- package/numkong/test/test_set.cpp +151 -0
- package/numkong/test/test_set.py +120 -0
- package/numkong/test/test_similarities.py +579 -0
- package/numkong/test/test_sparse.cpp +121 -0
- package/numkong/test/test_sparse.py +118 -0
- package/numkong/test/test_spatial.cpp +518 -0
- package/numkong/test/test_spatial.py +269 -0
- package/numkong/test/test_tensor.cpp +884 -0
- package/numkong/test/test_tensor.py +1417 -0
- package/numkong/test/test_trigonometry.cpp +156 -0
- package/numkong/test/test_trigonometry.py +180 -0
- package/package.json +7 -8
- package/prebuilds/darwin-arm64+x64/usearch.node +0 -0
- package/prebuilds/linux-arm64/usearch.node +0 -0
- package/prebuilds/linux-x64/usearch.node +0 -0
- package/fp16/CMakeLists.txt +0 -176
- package/fp16/LICENSE +0 -11
- package/fp16/README.md +0 -20
- package/fp16/bench/alt-element.cc +0 -89
- package/fp16/bench/from-alt-array.cc +0 -175
- package/fp16/bench/from-ieee-array.cc +0 -399
- package/fp16/bench/ieee-element.cc +0 -272
- package/fp16/bench/to-alt-array.cc +0 -91
- package/fp16/bench/to-ieee-array.cc +0 -303
- package/fp16/cmake/DownloadGoogleBenchmark.cmake +0 -15
- package/fp16/cmake/DownloadGoogleTest.cmake +0 -15
- package/fp16/cmake/DownloadPSimd.cmake +0 -15
- package/fp16/configure.py +0 -65
- package/fp16/confu.yaml +0 -8
- package/fp16/include/fp16/__init__.py +0 -0
- package/fp16/include/fp16/avx.py +0 -50
- package/fp16/include/fp16/avx2.py +0 -53
- package/fp16/include/fp16/bitcasts.h +0 -92
- package/fp16/include/fp16/fp16.h +0 -451
- package/fp16/include/fp16/psimd.h +0 -131
- package/fp16/include/fp16.h +0 -11
- package/fp16/jni/Android.mk +0 -6
- package/fp16/jni/Application.mk +0 -4
- package/fp16/test/alt-from-fp32-value.cc +0 -498
- package/fp16/test/alt-to-fp32-bits.cc +0 -263
- package/fp16/test/alt-to-fp32-psimd.cc +0 -145
- package/fp16/test/alt-to-fp32-value.cc +0 -348
- package/fp16/test/alt-to-fp32x2-psimd.cc +0 -245
- package/fp16/test/bitcasts.cc +0 -56
- package/fp16/test/ieee-from-fp32-value.cc +0 -523
- package/fp16/test/ieee-to-fp32-bits.cc +0 -333
- package/fp16/test/ieee-to-fp32-psimd.cc +0 -312
- package/fp16/test/ieee-to-fp32-value.cc +0 -420
- package/fp16/test/ieee-to-fp32x2-psimd.cc +0 -541
- package/fp16/test/peachpy/alt-xmm-to-fp32-xmm-avx.cc +0 -96
- package/fp16/test/peachpy/alt-xmm-to-fp32-ymm-avx2.cc +0 -96
- package/fp16/test/peachpy/stubs.py +0 -38
- package/fp16/test/tables.cc +0 -530
- package/fp16/test/tables.h +0 -13
- package/fp16/third-party/THHalf.h +0 -92
- package/fp16/third-party/eigen-half.h +0 -170
- package/fp16/third-party/float16-compressor.h +0 -80
- package/fp16/third-party/half.hpp +0 -2916
- package/fp16/third-party/npy-halffloat.h +0 -328
- package/simsimd/.git-blame-ignore-revs +0 -2
- package/simsimd/CONTRIBUTING.md +0 -321
- package/simsimd/Cargo.toml +0 -49
- package/simsimd/MANIFEST.in +0 -4
- package/simsimd/Package.swift +0 -28
- package/simsimd/README.md +0 -1493
- package/simsimd/binding.gyp +0 -35
- package/simsimd/build.rs +0 -70
- package/simsimd/c/lib.c +0 -374
- package/simsimd/include/module.modulemap +0 -4
- package/simsimd/include/simsimd/binary.h +0 -486
- package/simsimd/include/simsimd/curved.h +0 -1541
- package/simsimd/include/simsimd/dot.h +0 -1853
- package/simsimd/include/simsimd/elementwise.h +0 -2465
- package/simsimd/include/simsimd/geospatial.h +0 -43
- package/simsimd/include/simsimd/mesh.h +0 -69
- package/simsimd/include/simsimd/probability.h +0 -606
- package/simsimd/include/simsimd/simsimd.h +0 -2567
- package/simsimd/include/simsimd/sparse.h +0 -1384
- package/simsimd/include/simsimd/spatial.h +0 -2335
- package/simsimd/include/simsimd/types.h +0 -666
- package/simsimd/javascript/fallback.ts +0 -233
- package/simsimd/javascript/lib.c +0 -125
- package/simsimd/javascript/node-gyp-build.d.ts +0 -1
- package/simsimd/javascript/simsimd.ts +0 -179
- package/simsimd/javascript/tsconfig-cjs.json +0 -8
- package/simsimd/package-lock.json +0 -1761
- package/simsimd/package.json +0 -61
- package/simsimd/rust/lib.rs +0 -1821
- package/simsimd/scripts/bench.cxx +0 -1170
- package/simsimd/scripts/bench.ipynb +0 -187
- package/simsimd/scripts/bench.js +0 -127
- package/simsimd/scripts/bench.rs +0 -876
- package/simsimd/scripts/bench_vectors.py +0 -734
- package/simsimd/scripts/bench_vectors_live.py +0 -213
- package/simsimd/scripts/test.c +0 -187
- package/simsimd/scripts/test.mjs +0 -220
- package/simsimd/scripts/test.py +0 -1505
- package/simsimd/swift/SimSIMD.swift +0 -149
- package/simsimd/swift/Test.swift +0 -128
- /package/{simsimd → numkong}/CODE_OF_CONDUCT.md +0 -0
- /package/{simsimd → numkong}/LICENSE +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-cjs.json +0 -0
- /package/{simsimd → numkong}/javascript/dist-package-esm.json +0 -0
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
#define UNUM_USEARCH_HPP
|
|
9
9
|
|
|
10
10
|
#define USEARCH_VERSION_MAJOR 2
|
|
11
|
-
#define USEARCH_VERSION_MINOR
|
|
12
|
-
#define USEARCH_VERSION_PATCH
|
|
11
|
+
#define USEARCH_VERSION_MINOR 25
|
|
12
|
+
#define USEARCH_VERSION_PATCH 0
|
|
13
13
|
|
|
14
14
|
// Inferring C++ version
|
|
15
15
|
// https://stackoverflow.com/a/61552074
|
|
@@ -72,7 +72,9 @@
|
|
|
72
72
|
// OS-specific includes
|
|
73
73
|
#if defined(USEARCH_DEFINED_WINDOWS)
|
|
74
74
|
#define _USE_MATH_DEFINES
|
|
75
|
+
#ifndef NOMINMAX
|
|
75
76
|
#define NOMINMAX
|
|
77
|
+
#endif
|
|
76
78
|
#include <Windows.h>
|
|
77
79
|
#include <sys/stat.h> // `fstat` for file size
|
|
78
80
|
#undef NOMINMAX
|
|
@@ -500,7 +502,7 @@ template <typename allocator_at = std::allocator<byte_t>> class bitset_gt {
|
|
|
500
502
|
|
|
501
503
|
static constexpr std::size_t bits_per_slot() { return sizeof(compressed_slot_t) * CHAR_BIT; }
|
|
502
504
|
static constexpr compressed_slot_t bits_mask() { return sizeof(compressed_slot_t) * CHAR_BIT - 1; }
|
|
503
|
-
static constexpr std::size_t
|
|
505
|
+
static constexpr std::size_t bits_slots(std::size_t bits) { return divide_round_up<bits_per_slot()>(bits); }
|
|
504
506
|
|
|
505
507
|
compressed_slot_t* slots_{};
|
|
506
508
|
/// @brief Number of slots.
|
|
@@ -524,8 +526,8 @@ template <typename allocator_at = std::allocator<byte_t>> class bitset_gt {
|
|
|
524
526
|
}
|
|
525
527
|
|
|
526
528
|
bitset_gt(std::size_t capacity) noexcept
|
|
527
|
-
: slots_((compressed_slot_t*)allocator_t{}.allocate(
|
|
528
|
-
count_(slots_ ?
|
|
529
|
+
: slots_((compressed_slot_t*)allocator_t{}.allocate(bits_slots(capacity) * sizeof(compressed_slot_t))),
|
|
530
|
+
count_(slots_ ? bits_slots(capacity) : 0u) {
|
|
529
531
|
clear();
|
|
530
532
|
}
|
|
531
533
|
|
|
@@ -595,6 +597,125 @@ template <typename allocator_at = std::allocator<byte_t>> class bitset_gt {
|
|
|
595
597
|
|
|
596
598
|
using bitset_t = bitset_gt<>;
|
|
597
599
|
|
|
600
|
+
/**
|
|
601
|
+
* @brief Cache-line-padded striped spin-lock array for concurrent graph mutations.
|
|
602
|
+
* Maps node slots to lock stripes via Fibonacci hashing, with each stripe
|
|
603
|
+
* occupying its own cache line to eliminate false sharing.
|
|
604
|
+
* The number of stripes is proportional to `threads * connectivity`, not
|
|
605
|
+
* graph size, keeping the lock array comfortably within L2/L3 cache.
|
|
606
|
+
*/
|
|
607
|
+
template <typename allocator_at = std::allocator<byte_t>, std::size_t cache_line_ak = 128> //
|
|
608
|
+
class striped_locks_gt {
|
|
609
|
+
using allocator_t = allocator_at;
|
|
610
|
+
using byte_t = typename allocator_t::value_type;
|
|
611
|
+
static_assert(sizeof(byte_t) == 1, "Allocator must allocate separate addressable bytes");
|
|
612
|
+
|
|
613
|
+
static constexpr std::uint64_t fibonacci_k = 0x9E3779B97F4A7C15ull;
|
|
614
|
+
|
|
615
|
+
using atomic_flag_t = std::atomic<std::uint8_t>;
|
|
616
|
+
struct alignas(cache_line_ak) padded_lock_t {
|
|
617
|
+
atomic_flag_t flag{0};
|
|
618
|
+
char padding_[cache_line_ak - sizeof(atomic_flag_t)];
|
|
619
|
+
};
|
|
620
|
+
static_assert(sizeof(padded_lock_t) == cache_line_ak, "Lock stripe must be exactly one cache line");
|
|
621
|
+
|
|
622
|
+
// `padded_lock_t` is `alignas(cache_line_ak)` (128 B by default) which
|
|
623
|
+
// exceeds what a plain allocator guarantees (typically 16 B on x86-64).
|
|
624
|
+
// Rather than demanding an over-aligned allocator, we over-allocate and
|
|
625
|
+
// keep a pointer to the aligned sub-region — `raw_` is what we hand back
|
|
626
|
+
// to the allocator, `stripes_` is the aligned view used for reads/writes.
|
|
627
|
+
byte_t* raw_{};
|
|
628
|
+
std::size_t raw_bytes_{};
|
|
629
|
+
padded_lock_t* stripes_{};
|
|
630
|
+
std::size_t count_{};
|
|
631
|
+
unsigned shift_{};
|
|
632
|
+
|
|
633
|
+
inline std::size_t stripe_for_(std::size_t slot) const noexcept {
|
|
634
|
+
return static_cast<std::size_t>((static_cast<std::uint64_t>(slot) * fibonacci_k) >> shift_);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
public:
|
|
638
|
+
striped_locks_gt() noexcept {}
|
|
639
|
+
~striped_locks_gt() noexcept { reset(); }
|
|
640
|
+
|
|
641
|
+
explicit operator bool() const noexcept { return stripes_; }
|
|
642
|
+
|
|
643
|
+
void reset() noexcept {
|
|
644
|
+
if (stripes_)
|
|
645
|
+
for (std::size_t i = 0; i < count_; i++)
|
|
646
|
+
stripes_[i].~padded_lock_t();
|
|
647
|
+
if (raw_)
|
|
648
|
+
allocator_t{}.deallocate(raw_, raw_bytes_);
|
|
649
|
+
raw_ = nullptr;
|
|
650
|
+
raw_bytes_ = 0;
|
|
651
|
+
stripes_ = nullptr;
|
|
652
|
+
count_ = 0;
|
|
653
|
+
shift_ = 64;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
striped_locks_gt(std::size_t threads, std::size_t connectivity) noexcept {
|
|
657
|
+
std::size_t desired = threads * connectivity * 4;
|
|
658
|
+
if (desired < 256)
|
|
659
|
+
desired = 256;
|
|
660
|
+
count_ = ceil2(desired);
|
|
661
|
+
shift_ = 64;
|
|
662
|
+
for (std::size_t n = count_; n > 1; n >>= 1)
|
|
663
|
+
shift_--;
|
|
664
|
+
// Request one extra stripe's worth of slack so we can always land on a
|
|
665
|
+
// `cache_line_ak`-aligned address inside the allocation, regardless of
|
|
666
|
+
// what the underlying allocator returns.
|
|
667
|
+
constexpr std::size_t alignment_k = alignof(padded_lock_t);
|
|
668
|
+
raw_bytes_ = count_ * sizeof(padded_lock_t) + alignment_k;
|
|
669
|
+
raw_ = allocator_t{}.allocate(raw_bytes_);
|
|
670
|
+
if (!raw_) {
|
|
671
|
+
raw_bytes_ = 0;
|
|
672
|
+
count_ = 0;
|
|
673
|
+
shift_ = 64;
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
auto raw_address = reinterpret_cast<std::uintptr_t>(raw_);
|
|
677
|
+
auto aligned_address = (raw_address + alignment_k - 1) & ~(static_cast<std::uintptr_t>(alignment_k) - 1);
|
|
678
|
+
stripes_ = reinterpret_cast<padded_lock_t*>(aligned_address);
|
|
679
|
+
for (std::size_t i = 0; i < count_; i++)
|
|
680
|
+
new (&stripes_[i]) padded_lock_t();
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
striped_locks_gt(striped_locks_gt&& other) noexcept {
|
|
684
|
+
raw_ = exchange(other.raw_, (byte_t*)nullptr);
|
|
685
|
+
raw_bytes_ = exchange(other.raw_bytes_, std::size_t{0});
|
|
686
|
+
stripes_ = exchange(other.stripes_, nullptr);
|
|
687
|
+
count_ = exchange(other.count_, std::size_t{0});
|
|
688
|
+
shift_ = exchange(other.shift_, unsigned{64});
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
striped_locks_gt& operator=(striped_locks_gt&& other) noexcept {
|
|
692
|
+
std::swap(raw_, other.raw_);
|
|
693
|
+
std::swap(raw_bytes_, other.raw_bytes_);
|
|
694
|
+
std::swap(stripes_, other.stripes_);
|
|
695
|
+
std::swap(count_, other.count_);
|
|
696
|
+
std::swap(shift_, other.shift_);
|
|
697
|
+
return *this;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
striped_locks_gt(striped_locks_gt const&) = delete;
|
|
701
|
+
striped_locks_gt& operator=(striped_locks_gt const&) = delete;
|
|
702
|
+
|
|
703
|
+
inline bool atomic_set(std::size_t i) noexcept {
|
|
704
|
+
return stripes_[stripe_for_(i)].flag.exchange(1, std::memory_order_acquire);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
inline void atomic_reset(std::size_t i) noexcept {
|
|
708
|
+
stripes_[stripe_for_(i)].flag.store(0, std::memory_order_release);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
inline void lock(std::size_t i) noexcept {
|
|
712
|
+
while (atomic_set(i))
|
|
713
|
+
std::this_thread::yield();
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
inline void unlock(std::size_t i) noexcept { atomic_reset(i); }
|
|
717
|
+
};
|
|
718
|
+
|
|
598
719
|
/**
|
|
599
720
|
* @brief Similar to `std::priority_queue`, but allows raw access to underlying
|
|
600
721
|
* memory, in case you want to shuffle it or sort. Good for collections
|
|
@@ -726,10 +847,12 @@ class max_heap_gt {
|
|
|
726
847
|
*/
|
|
727
848
|
usearch_profiled_m bool reserve(std::size_t new_capacity) noexcept {
|
|
728
849
|
usearch_profile_name_m(max_heap_reserve);
|
|
729
|
-
if (new_capacity
|
|
850
|
+
if (new_capacity <= capacity_)
|
|
730
851
|
return true;
|
|
731
852
|
|
|
732
853
|
new_capacity = ceil2(new_capacity);
|
|
854
|
+
if (new_capacity == 0)
|
|
855
|
+
return false;
|
|
733
856
|
new_capacity = (std::max<std::size_t>)(new_capacity, (std::max<std::size_t>)(capacity_ * 2u, 16u));
|
|
734
857
|
auto allocator = allocator_t{};
|
|
735
858
|
auto new_elements = allocator.allocate(new_capacity);
|
|
@@ -892,10 +1015,12 @@ class sorted_buffer_gt {
|
|
|
892
1015
|
inline void clear() noexcept { size_ = 0; }
|
|
893
1016
|
|
|
894
1017
|
bool reserve(std::size_t new_capacity) noexcept {
|
|
895
|
-
if (new_capacity
|
|
1018
|
+
if (new_capacity <= capacity_)
|
|
896
1019
|
return true;
|
|
897
1020
|
|
|
898
1021
|
new_capacity = ceil2(new_capacity);
|
|
1022
|
+
if (new_capacity == 0)
|
|
1023
|
+
return false;
|
|
899
1024
|
new_capacity = (std::max<std::size_t>)(new_capacity, (std::max<std::size_t>)(capacity_ * 2u, 16u));
|
|
900
1025
|
auto allocator = allocator_t{};
|
|
901
1026
|
auto new_elements = allocator.allocate(new_capacity);
|
|
@@ -1011,8 +1136,10 @@ class usearch_pack_m uint40_t {
|
|
|
1011
1136
|
return result;
|
|
1012
1137
|
}
|
|
1013
1138
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1139
|
+
/* Parenthesized declarator keeps MSVC's preprocessor from expanding
|
|
1140
|
+
* `max` / `min` against `<windows.h>`'s `max(a,b)` / `min(a,b)` macros. */
|
|
1141
|
+
inline static uint40_t(max)() noexcept { return uint40_t{}.broadcast(0xFF); }
|
|
1142
|
+
inline static uint40_t(min)() noexcept { return uint40_t{}.broadcast(0); }
|
|
1016
1143
|
|
|
1017
1144
|
inline bool operator==(uint40_t const& other) const noexcept { return std::memcmp(octets, other.octets, 5) == 0; }
|
|
1018
1145
|
inline bool operator!=(uint40_t const& other) const noexcept { return !(*this == other); }
|
|
@@ -1044,7 +1171,7 @@ template <typename element_at> struct default_free_value_gt {
|
|
|
1044
1171
|
template <typename sfinae_element_at = element_at,
|
|
1045
1172
|
typename std::enable_if<std::is_integral<sfinae_element_at>::value>::type* = nullptr>
|
|
1046
1173
|
static sfinae_element_at value() noexcept {
|
|
1047
|
-
return std::numeric_limits<element_at>::max();
|
|
1174
|
+
return (std::numeric_limits<element_at>::max)();
|
|
1048
1175
|
}
|
|
1049
1176
|
template <typename sfinae_element_at = element_at,
|
|
1050
1177
|
typename std::enable_if<!std::is_integral<sfinae_element_at>::value>::type* = nullptr>
|
|
@@ -1054,7 +1181,7 @@ template <typename element_at> struct default_free_value_gt {
|
|
|
1054
1181
|
};
|
|
1055
1182
|
|
|
1056
1183
|
template <> struct default_free_value_gt<uint40_t> {
|
|
1057
|
-
static uint40_t value() noexcept { return uint40_t::max(); }
|
|
1184
|
+
static uint40_t value() noexcept { return (uint40_t::max)(); }
|
|
1058
1185
|
};
|
|
1059
1186
|
|
|
1060
1187
|
template <typename element_at> element_at default_free_value() { return default_free_value_gt<element_at>::value(); }
|
|
@@ -1778,7 +1905,7 @@ class memory_mapped_file_t {
|
|
|
1778
1905
|
#if defined(USEARCH_DEFINED_WINDOWS)
|
|
1779
1906
|
|
|
1780
1907
|
HANDLE file_handle =
|
|
1781
|
-
|
|
1908
|
+
CreateFileA(path_, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
|
1782
1909
|
if (file_handle == INVALID_HANDLE_VALUE)
|
|
1783
1910
|
return result.failed("Opening file failed!");
|
|
1784
1911
|
|
|
@@ -2029,8 +2156,8 @@ class index_gt {
|
|
|
2029
2156
|
friend inline vector_key_t get_key(member_iterator_gt const& it) noexcept { return it.key(); }
|
|
2030
2157
|
|
|
2031
2158
|
// clang-format off
|
|
2032
|
-
member_iterator_gt operator++(int) noexcept {
|
|
2033
|
-
member_iterator_gt operator--(int) noexcept {
|
|
2159
|
+
member_iterator_gt operator++(int) noexcept { member_iterator_gt old(index_, slot_); ++(*this); return old; }
|
|
2160
|
+
member_iterator_gt operator--(int) noexcept { member_iterator_gt old(index_, slot_); --(*this); return old; }
|
|
2034
2161
|
member_iterator_gt operator+(difference_type d) noexcept { return member_iterator_gt(index_, static_cast<compressed_slot_t>(static_cast<std::size_t>(slot_) + d)); }
|
|
2035
2162
|
member_iterator_gt operator-(difference_type d) noexcept { return member_iterator_gt(index_, static_cast<compressed_slot_t>(static_cast<std::size_t>(slot_) - d)); }
|
|
2036
2163
|
member_iterator_gt& operator++() noexcept { slot_ = static_cast<compressed_slot_t>(static_cast<std::size_t>(slot_) + 1); return *this; }
|
|
@@ -2084,7 +2211,7 @@ class index_gt {
|
|
|
2084
2211
|
*/
|
|
2085
2212
|
static constexpr std::size_t node_head_bytes_() { return sizeof(vector_key_t) + sizeof(level_t); }
|
|
2086
2213
|
|
|
2087
|
-
using nodes_mutexes_t =
|
|
2214
|
+
using nodes_mutexes_t = striped_locks_gt<dynamic_allocator_t>;
|
|
2088
2215
|
|
|
2089
2216
|
using visits_hash_set_t = growing_hash_set_gt<compressed_slot_t, hash_gt<compressed_slot_t>, dynamic_allocator_t>;
|
|
2090
2217
|
|
|
@@ -2189,7 +2316,7 @@ class index_gt {
|
|
|
2189
2316
|
misaligned_store<compressed_slot_t>(tape_ + shift(i - removed_count), slot);
|
|
2190
2317
|
}
|
|
2191
2318
|
}
|
|
2192
|
-
misaligned_store<neighbors_count_t>(tape_, old_count - removed_count);
|
|
2319
|
+
misaligned_store<neighbors_count_t>(tape_, static_cast<neighbors_count_t>(old_count - removed_count));
|
|
2193
2320
|
return removed_count;
|
|
2194
2321
|
}
|
|
2195
2322
|
};
|
|
@@ -2507,7 +2634,8 @@ class index_gt {
|
|
|
2507
2634
|
return true;
|
|
2508
2635
|
}
|
|
2509
2636
|
|
|
2510
|
-
|
|
2637
|
+
std::size_t connectivity_max = (std::max)(config_.connectivity_base, config_.connectivity);
|
|
2638
|
+
nodes_mutexes_t new_mutexes(limits.threads(), connectivity_max);
|
|
2511
2639
|
buffer_gt<node_t, nodes_allocator_t> new_nodes(limits.members);
|
|
2512
2640
|
buffer_gt<context_t, contexts_allocator_t> new_contexts(limits.threads());
|
|
2513
2641
|
if (!new_nodes || !new_contexts || !new_mutexes)
|
|
@@ -2516,10 +2644,6 @@ class index_gt {
|
|
|
2516
2644
|
// Move the nodes info, and deallocate previous buffers.
|
|
2517
2645
|
if (nodes_)
|
|
2518
2646
|
std::memcpy(new_nodes.data(), nodes_.data(), sizeof(node_t) * size());
|
|
2519
|
-
|
|
2520
|
-
// Pre-reserve the capacity for `top_for_refine`, which always contains at most one more
|
|
2521
|
-
// element than the connectivity factors.
|
|
2522
|
-
std::size_t connectivity_max = (std::max)(config_.connectivity_base, config_.connectivity);
|
|
2523
2647
|
for (std::size_t i = 0; i != new_contexts.size(); ++i)
|
|
2524
2648
|
if (!new_contexts[i].top_for_refine.reserve(connectivity_max + 1))
|
|
2525
2649
|
return false;
|
|
@@ -2567,7 +2691,7 @@ class index_gt {
|
|
|
2567
2691
|
member_cref_t member;
|
|
2568
2692
|
distance_t distance;
|
|
2569
2693
|
|
|
2570
|
-
inline match_t() noexcept : member({nullptr, 0}), distance(std::numeric_limits<distance_t>::max()) {}
|
|
2694
|
+
inline match_t() noexcept : member({nullptr, 0}), distance((std::numeric_limits<distance_t>::max)()) {}
|
|
2571
2695
|
|
|
2572
2696
|
inline match_t(member_cref_t member, distance_t distance) noexcept : member(member), distance(distance) {}
|
|
2573
2697
|
|
|
@@ -2624,7 +2748,10 @@ class index_gt {
|
|
|
2624
2748
|
inline bool empty() const noexcept { return !count; }
|
|
2625
2749
|
inline match_t operator[](std::size_t i) const noexcept { return at(i); }
|
|
2626
2750
|
inline match_t front() const noexcept { return at(0); }
|
|
2627
|
-
inline match_t back() const noexcept {
|
|
2751
|
+
inline match_t back() const noexcept {
|
|
2752
|
+
usearch_assert_m(count > 0, "Can't call back() on an empty result set");
|
|
2753
|
+
return at(count - 1);
|
|
2754
|
+
}
|
|
2628
2755
|
inline bool contains(vector_key_t key) const noexcept {
|
|
2629
2756
|
for (std::size_t i = 0; i != count; ++i)
|
|
2630
2757
|
if (at(i).member.key == key)
|
|
@@ -2716,7 +2843,7 @@ class index_gt {
|
|
|
2716
2843
|
keys[i] = vector_key_t{};
|
|
2717
2844
|
distances[i] = std::numeric_limits<distance_t>::has_signaling_NaN
|
|
2718
2845
|
? std::numeric_limits<distance_t>::signaling_NaN()
|
|
2719
|
-
: std::numeric_limits<distance_t>::max();
|
|
2846
|
+
: (std::numeric_limits<distance_t>::max)();
|
|
2720
2847
|
}
|
|
2721
2848
|
return initialized_count;
|
|
2722
2849
|
}
|
|
@@ -2783,6 +2910,10 @@ class index_gt {
|
|
|
2783
2910
|
callback_at&& callback = callback_at{}, //
|
|
2784
2911
|
prefetch_at&& prefetch = prefetch_at{}) usearch_noexcept_m {
|
|
2785
2912
|
|
|
2913
|
+
// Zero expansion is meaningless, fall back to default
|
|
2914
|
+
if (!config.expansion)
|
|
2915
|
+
config.expansion = default_expansion_add();
|
|
2916
|
+
|
|
2786
2917
|
add_result_t result;
|
|
2787
2918
|
if (is_immutable())
|
|
2788
2919
|
return result.failed("Can't add to an immutable index");
|
|
@@ -2987,7 +3118,8 @@ class index_gt {
|
|
|
2987
3118
|
}
|
|
2988
3119
|
form_reverse_links_(metric, updated_slot, closest_view, value, level, context);
|
|
2989
3120
|
}
|
|
2990
|
-
updated_node.key(key)
|
|
3121
|
+
if (static_cast<vector_key_t>(updated_node.key()) != key)
|
|
3122
|
+
updated_node.key(key);
|
|
2991
3123
|
|
|
2992
3124
|
// Normalize stats
|
|
2993
3125
|
result.computed_distances = context.computed_distances - result.computed_distances;
|
|
@@ -3097,6 +3229,9 @@ class index_gt {
|
|
|
3097
3229
|
predicate_at&& predicate = predicate_at{}, //
|
|
3098
3230
|
prefetch_at&& prefetch = prefetch_at{}) const noexcept {
|
|
3099
3231
|
|
|
3232
|
+
if (!config.expansion)
|
|
3233
|
+
config.expansion = default_expansion_search();
|
|
3234
|
+
|
|
3100
3235
|
context_t& context = contexts_[config.thread];
|
|
3101
3236
|
cluster_result_t result;
|
|
3102
3237
|
if (!nodes_count_)
|
|
@@ -3175,7 +3310,7 @@ class index_gt {
|
|
|
3175
3310
|
continue;
|
|
3176
3311
|
|
|
3177
3312
|
++result.nodes;
|
|
3178
|
-
result.edges += neighbors_(node, level).size();
|
|
3313
|
+
result.edges += neighbors_(node, static_cast<level_t>(level)).size();
|
|
3179
3314
|
result.allocated_bytes += node_head_bytes_() + neighbors_bytes;
|
|
3180
3315
|
}
|
|
3181
3316
|
|
|
@@ -3797,12 +3932,11 @@ class index_gt {
|
|
|
3797
3932
|
struct node_lock_t {
|
|
3798
3933
|
nodes_mutexes_t& mutexes;
|
|
3799
3934
|
std::size_t slot;
|
|
3800
|
-
inline ~node_lock_t() noexcept { mutexes.
|
|
3935
|
+
inline ~node_lock_t() noexcept { mutexes.unlock(slot); }
|
|
3801
3936
|
};
|
|
3802
3937
|
|
|
3803
3938
|
inline node_lock_t node_lock_(std::size_t slot) const noexcept {
|
|
3804
|
-
|
|
3805
|
-
;
|
|
3939
|
+
nodes_mutexes_.lock(slot);
|
|
3806
3940
|
return {nodes_mutexes_, slot};
|
|
3807
3941
|
}
|
|
3808
3942
|
|
|
@@ -3810,18 +3944,17 @@ class index_gt {
|
|
|
3810
3944
|
nodes_mutexes_t& mutexes;
|
|
3811
3945
|
std::size_t slot;
|
|
3812
3946
|
inline ~optional_node_lock_t() noexcept {
|
|
3813
|
-
if (slot != std::numeric_limits<std::size_t>::max())
|
|
3814
|
-
mutexes.
|
|
3947
|
+
if (slot != (std::numeric_limits<std::size_t>::max)())
|
|
3948
|
+
mutexes.unlock(slot);
|
|
3815
3949
|
}
|
|
3816
3950
|
};
|
|
3817
3951
|
|
|
3818
3952
|
inline optional_node_lock_t optional_node_lock_(std::size_t slot, bool condition) const noexcept {
|
|
3819
3953
|
if (condition) {
|
|
3820
|
-
|
|
3821
|
-
;
|
|
3954
|
+
nodes_mutexes_.lock(slot);
|
|
3822
3955
|
return {nodes_mutexes_, slot};
|
|
3823
3956
|
} else {
|
|
3824
|
-
return {nodes_mutexes_, std::numeric_limits<std::size_t>::max()};
|
|
3957
|
+
return {nodes_mutexes_, (std::numeric_limits<std::size_t>::max)()};
|
|
3825
3958
|
}
|
|
3826
3959
|
}
|
|
3827
3960
|
|
|
@@ -3829,15 +3962,19 @@ class index_gt {
|
|
|
3829
3962
|
nodes_mutexes_t& mutexes;
|
|
3830
3963
|
std::size_t slot;
|
|
3831
3964
|
inline ~node_conditional_lock_t() noexcept {
|
|
3832
|
-
if (slot != std::numeric_limits<std::size_t>::max())
|
|
3833
|
-
mutexes.
|
|
3965
|
+
if (slot != (std::numeric_limits<std::size_t>::max)())
|
|
3966
|
+
mutexes.unlock(slot);
|
|
3834
3967
|
}
|
|
3835
3968
|
};
|
|
3836
3969
|
|
|
3837
3970
|
inline node_conditional_lock_t node_try_conditional_lock_(std::size_t slot, bool condition,
|
|
3838
3971
|
bool& failed_to_acquire) const noexcept {
|
|
3839
|
-
|
|
3840
|
-
|
|
3972
|
+
if (!condition) {
|
|
3973
|
+
failed_to_acquire = false;
|
|
3974
|
+
return {nodes_mutexes_, (std::numeric_limits<std::size_t>::max)()};
|
|
3975
|
+
}
|
|
3976
|
+
failed_to_acquire = nodes_mutexes_.atomic_set(slot);
|
|
3977
|
+
return {nodes_mutexes_, failed_to_acquire ? (std::numeric_limits<std::size_t>::max)() : slot};
|
|
3841
3978
|
}
|
|
3842
3979
|
|
|
3843
3980
|
template <typename metric_at, bool require_non_empty_ak = false>
|
|
@@ -3888,8 +4025,12 @@ class index_gt {
|
|
|
3888
4025
|
usearch_assert_m(close_slot != new_slot, "Self-loops are impossible");
|
|
3889
4026
|
usearch_assert_m(level <= close_node.level(), "Linking to missing level");
|
|
3890
4027
|
|
|
3891
|
-
//
|
|
3892
|
-
|
|
4028
|
+
// Skip to prevent duplicate entries in the neighbor list.
|
|
4029
|
+
if (std::find_if(close_header.begin(), close_header.end(),
|
|
4030
|
+
[new_slot](compressed_slot_t slot) { return slot == new_slot; }) != close_header.end()) {
|
|
4031
|
+
continue;
|
|
4032
|
+
}
|
|
4033
|
+
|
|
3893
4034
|
if (close_header.size() < connectivity_max) {
|
|
3894
4035
|
close_header.push_back(new_slot);
|
|
3895
4036
|
continue;
|
|
@@ -3904,7 +4045,7 @@ class index_gt {
|
|
|
3904
4045
|
// Export the results:
|
|
3905
4046
|
close_header.clear();
|
|
3906
4047
|
candidates_view_t top_view = refine_(metric, connectivity_max, top_for_refine, context,
|
|
3907
|
-
context.computed_distances_in_reverse_refines);
|
|
4048
|
+
context.computed_distances_in_reverse_refines, new_slot, value);
|
|
3908
4049
|
usearch_assert_m(top_view.size(), "This would lead to isolated nodes");
|
|
3909
4050
|
for (std::size_t idx = 0; idx != top_view.size(); idx++)
|
|
3910
4051
|
close_header.push_back(top_view[idx].slot);
|
|
@@ -3952,7 +4093,9 @@ class index_gt {
|
|
|
3952
4093
|
std::size_t progress) noexcept
|
|
3953
4094
|
: index_(index), neighbors_(neighbors), visits_(visits), current_(progress) {}
|
|
3954
4095
|
candidates_iterator_t operator++(int) noexcept {
|
|
3955
|
-
|
|
4096
|
+
candidates_iterator_t old(index_, neighbors_, visits_, current_);
|
|
4097
|
+
++(*this);
|
|
4098
|
+
return old;
|
|
3956
4099
|
}
|
|
3957
4100
|
candidates_iterator_t& operator++() noexcept {
|
|
3958
4101
|
++current_;
|
|
@@ -3991,12 +4134,13 @@ class index_gt {
|
|
|
3991
4134
|
if (!is_dummy<prefetch_at>())
|
|
3992
4135
|
prefetch(citerator_at(closest_slot), citerator_at(closest_slot) + 1);
|
|
3993
4136
|
|
|
4137
|
+
bool const need_lock = !is_immutable();
|
|
3994
4138
|
distance_t closest_dist = context.measure(query, citerator_at(closest_slot), metric);
|
|
3995
4139
|
for (level_t level = begin_level; level > end_level; --level) {
|
|
3996
4140
|
bool changed;
|
|
3997
4141
|
do {
|
|
3998
4142
|
changed = false;
|
|
3999
|
-
|
|
4143
|
+
optional_node_lock_t closest_lock = optional_node_lock_(closest_slot, need_lock);
|
|
4000
4144
|
neighbors_ref_t closest_neighbors = neighbors_non_base_(node_at_(closest_slot), level);
|
|
4001
4145
|
|
|
4002
4146
|
// Optional prefetching
|
|
@@ -4042,6 +4186,10 @@ class index_gt {
|
|
|
4042
4186
|
// At the very least we are going to explore the starting node and its neighbors
|
|
4043
4187
|
if (!visits.reserve(config_.connectivity_base + 1u))
|
|
4044
4188
|
return false;
|
|
4189
|
+
if (!top.reserve(top_limit))
|
|
4190
|
+
return false;
|
|
4191
|
+
if (!next.reserve(top_limit))
|
|
4192
|
+
return false;
|
|
4045
4193
|
|
|
4046
4194
|
// Optional prefetching
|
|
4047
4195
|
if (!is_dummy<prefetch_at>())
|
|
@@ -4119,6 +4267,10 @@ class index_gt {
|
|
|
4119
4267
|
// At the very least we are going to explore the starting node and its neighbors
|
|
4120
4268
|
if (!visits.reserve(config_.connectivity_base + 1u))
|
|
4121
4269
|
return false;
|
|
4270
|
+
if (!top.reserve(top_limit))
|
|
4271
|
+
return false;
|
|
4272
|
+
if (!next.reserve(top_limit))
|
|
4273
|
+
return false;
|
|
4122
4274
|
|
|
4123
4275
|
// Optional prefetching
|
|
4124
4276
|
if (!is_dummy<prefetch_at>())
|
|
@@ -4152,8 +4304,7 @@ class index_gt {
|
|
|
4152
4304
|
node_try_conditional_lock_(candidate_slot, updated_slot != candidate_slot, failed_to_acquire);
|
|
4153
4305
|
if (failed_to_acquire)
|
|
4154
4306
|
continue;
|
|
4155
|
-
auto optional_node_lock =
|
|
4156
|
-
optional_node_lock_(candidate_slot, updated_slot == candidate_slot);
|
|
4307
|
+
auto optional_node_lock = optional_node_lock_(candidate_slot, updated_slot == candidate_slot);
|
|
4157
4308
|
neighbors_ref_t candidate_neighbors = neighbors_(candidate_ref, level);
|
|
4158
4309
|
|
|
4159
4310
|
// Optional prefetching
|
|
@@ -4288,16 +4439,50 @@ class index_gt {
|
|
|
4288
4439
|
}
|
|
4289
4440
|
}
|
|
4290
4441
|
|
|
4442
|
+
/// @brief Helper for `refine_()`: computes inter-neighbor distance, substituting
|
|
4443
|
+
/// @p override_value when either slot matches @p override_slot.
|
|
4444
|
+
/// The `std::nullptr_t` overload below avoids instantiating the override
|
|
4445
|
+
/// branch when no override is provided, keeping the code C++11 compatible.
|
|
4446
|
+
template <typename metric_at, typename override_value_at>
|
|
4447
|
+
distance_t inter_neighbor_distance_( //
|
|
4448
|
+
candidate_t const& candidate, candidate_t const& submitted, //
|
|
4449
|
+
compressed_slot_t override_slot, override_value_at override_value, //
|
|
4450
|
+
metric_at&& metric, context_t& context) const noexcept {
|
|
4451
|
+
if (candidate.slot == override_slot)
|
|
4452
|
+
return context.measure(override_value, citerator_at(submitted.slot), metric);
|
|
4453
|
+
else if (submitted.slot == override_slot)
|
|
4454
|
+
return context.measure(override_value, citerator_at(candidate.slot), metric);
|
|
4455
|
+
else
|
|
4456
|
+
return context.measure(citerator_at(candidate.slot), citerator_at(submitted.slot), metric);
|
|
4457
|
+
}
|
|
4458
|
+
|
|
4459
|
+
template <typename metric_at>
|
|
4460
|
+
distance_t inter_neighbor_distance_( //
|
|
4461
|
+
candidate_t const& candidate, candidate_t const& submitted, //
|
|
4462
|
+
compressed_slot_t, std::nullptr_t, //
|
|
4463
|
+
metric_at&& metric, context_t& context) const noexcept {
|
|
4464
|
+
return context.measure(citerator_at(candidate.slot), citerator_at(submitted.slot), metric);
|
|
4465
|
+
}
|
|
4466
|
+
|
|
4291
4467
|
/**
|
|
4292
4468
|
* @brief This algorithm from the original paper implements a heuristic,
|
|
4293
4469
|
* that massively reduces the number of connections a point has,
|
|
4294
4470
|
* to keep only the neighbors, that are from each other.
|
|
4471
|
+
*
|
|
4472
|
+
* @param[in] override_slot Optional slot whose stored vector is stale (e.g. during update,
|
|
4473
|
+
* where the callback has not yet committed the new vector).
|
|
4474
|
+
* When set, inter-result distances involving this slot will use
|
|
4475
|
+
* @p override_value instead of reading from `citerator_at()`.
|
|
4476
|
+
* @param[in] override_value The up-to-date vector for @p override_slot. Only used when
|
|
4477
|
+
* @p override_value_at is not `std::nullptr_t`.
|
|
4295
4478
|
*/
|
|
4296
|
-
template <typename metric_at>
|
|
4479
|
+
template <typename metric_at, typename override_value_at = std::nullptr_t>
|
|
4297
4480
|
candidates_view_t refine_( //
|
|
4298
4481
|
metric_at&& metric, //
|
|
4299
4482
|
std::size_t needed, top_candidates_t& top, context_t& context, //
|
|
4300
|
-
std::size_t& refines_counter
|
|
4483
|
+
std::size_t& refines_counter, //
|
|
4484
|
+
compressed_slot_t override_slot = ((std::numeric_limits<compressed_slot_t>::max))(),
|
|
4485
|
+
override_value_at override_value = {}) const noexcept {
|
|
4301
4486
|
|
|
4302
4487
|
// Avoid expensive computation, if the set is already small
|
|
4303
4488
|
candidate_t* top_data = top.data();
|
|
@@ -4316,10 +4501,8 @@ class index_gt {
|
|
|
4316
4501
|
std::size_t idx = 0;
|
|
4317
4502
|
for (; idx < submitted_count; idx++) {
|
|
4318
4503
|
candidate_t submitted = top_data[idx];
|
|
4319
|
-
distance_t inter_result_dist =
|
|
4320
|
-
|
|
4321
|
-
citerator_at(submitted.slot), //
|
|
4322
|
-
metric);
|
|
4504
|
+
distance_t inter_result_dist = inter_neighbor_distance_( //
|
|
4505
|
+
candidate, submitted, override_slot, override_value, metric, context);
|
|
4323
4506
|
if (inter_result_dist < candidate.distance) {
|
|
4324
4507
|
good = false;
|
|
4325
4508
|
break;
|
|
@@ -4410,7 +4593,7 @@ static join_result_t join( //
|
|
|
4410
4593
|
return result.failed("Can't join with itself, consider copying");
|
|
4411
4594
|
|
|
4412
4595
|
if (config.max_proposals == 0)
|
|
4413
|
-
config.max_proposals = std::log(men.size()) + executor.size();
|
|
4596
|
+
config.max_proposals = static_cast<std::size_t>(std::log(men.size())) + executor.size();
|
|
4414
4597
|
|
|
4415
4598
|
using proposals_count_t = std::uint16_t;
|
|
4416
4599
|
config.max_proposals = (std::min)(men.size(), config.max_proposals);
|