dynvec/lib.rs
1//! Vector storage + HNSW ANN index engine.
2//!
3//! `dynvec` provides three things:
4//!
5//! 1. A node-local vector row store with two encodings (per-vector
6//! int8 quantisation and IEEE 754 half-precision floats) and
7//! three distance metrics (euclidean, cosine, dot product).
8//! 2. An HNSW approximate-nearest-neighbour index for k-NN queries.
9//! 3. A per-table [`Engine`] handle, which is the unit the
10//! `dynomite::vector` registry hands out when serving Redis
11//! Stack RediSearch FT.* commands.
12//!
13//! # Module layout
14//!
15//! * [`encoding`] -- vector compression codecs.
16//! * [`distance`] -- L2 / cosine / dot product scoring.
17//! * [`index`] -- the HNSW graph.
18//! * [`storage`] -- row store + per-table HNSW index, with a
19//! pluggable [`storage::Backend`] trait so the same surface
20//! works against an in-memory backend (default) or a Noxu DB
21//! (off-by-default `noxu` feature).
22//! * [`engine`] -- per-table handle exposed to embedders.
23//! * [`api`] -- the HTTP API (gated on the `http` feature; kept
24//! as a debug surface only).
25//!
26//! The distributed k-NN coordinator that used to live here has
27//! moved to `dynomite::vector::query_fsm`, where it can sit
28//! against the cluster machinery directly.
29//!
30//! # Quick start
31//!
32//! ```
33//! use std::collections::HashMap;
34//! use dynvec::distance::Distance;
35//! use dynvec::encoding::Codec;
36//! use dynvec::index::HnswParams;
37//! use dynvec::storage::{IndexAlgorithm, TableSchema, VectorStore};
38//!
39//! let store = VectorStore::in_memory();
40//! store.create_table(TableSchema {
41//! name: "demo".to_string(),
42//! dim: 3,
43//! codec: Codec::Int8Quantized,
44//! distance: Distance::Cosine,
45//! hnsw: HnswParams::default(),
46//! algorithm: IndexAlgorithm::Hnsw,
47//! }).unwrap();
48//! store
49//! .upsert("demo", b"a".to_vec(), &[1.0, 0.0, 0.0], HashMap::new())
50//! .unwrap();
51//! store
52//! .upsert("demo", b"b".to_vec(), &[0.0, 1.0, 0.0], HashMap::new())
53//! .unwrap();
54//! let hits = store.search("demo", &[0.95, 0.05, 0.0], 1, None).unwrap();
55//! assert_eq!(hits[0].0.key, b"a");
56//! ```
57
58#![doc(html_root_url = "https://docs.rs/dynvec/0.0.1")]
59
60pub mod distance;
61pub mod encoding;
62pub mod engine;
63pub mod index;
64pub mod storage;
65pub mod turbo_hnsw;
66pub mod turbo_index;
67
68#[cfg(feature = "http")]
69pub mod api;
70
71pub use crate::distance::Distance;
72pub use crate::encoding::{
73 decode_turbovec, distance_turbovec, encode_turbovec, Codec, EncodedVector, Encoder, Fp16,
74 Int8Quantized, Turbovec,
75};
76pub use crate::engine::Engine;
77pub use crate::index::{HnswIndex, HnswParams, NodeId, SearchResult};
78pub use crate::storage::{
79 Backend, IndexAlgorithm, MemoryBackend, RowKey, StoreError, TableSchema, TableStats, VectorRow,
80 VectorStore,
81};
82pub use crate::turbo_hnsw::{CodecDistance, TurboHnswIndex};
83pub use crate::turbo_index::TurboTable;