Profiling the build showed 90% of all distance evaluations are in back-link pruning (40.8M of 44.9M at 10K): every overflow re-runs the diversity heuristic pairwise over ~max_conn candidates. The bulk build now inserts in batches: plan every node's neighbours against the graph as it stood when the batch began (read-only, so plans are independent), link, then prune each overflowing list once. A node gaining several back-links in a batch is pruned once rather than once per link, so this is faster even single-threaded (10K: 1676 -> 1074 ms). With `parallel`, planning and pruning use rayon (10K: 388 ms; 100K: ~21 s -> 5.9 s on 16 cores). Batches start at one node and are capped at 1/16 of the linked graph and 512 nodes; a node that raises the top layer gets a batch to itself. The result is deterministic and identical with or without the feature (one code path; test compares two builds byte for byte). Parallelising within a single insert was tried first: 1.45x on 16 cores, tasks too small. Incremental insert() stays sequential. Recall on clustered data is unchanged or slightly better; uniform random data dips slightly (10K, ef=64: 0.474 -> 0.444). clawhdf5-agent's `parallel` feature now passes through to the index. Co-Authored-By: Claude Fable 5.1 <[email protected]>
clawhdf5-ann
HNSW approximate nearest neighbor index stored as HDF5.
Features
- Build and query HNSW indexes persisted in HDF5 format
- Pure Rust, no C dependencies
- Efficient similarity search for high-dimensional vectors
Usage
use clawhdf5_ann::HnswIndex;
let index = HnswIndex::from_hdf5("vectors.h5").unwrap();
let neighbors = index.search(&query, 10);
License
MIT