1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2026 James Gober.
// Licensed under Apache-2.0 OR MIT.
//! # iqdb — embedded vector database for Rust
//!
//! `iqdb` is a single-process, in-application similarity-search engine for
//! high-dimensional workloads. It targets the operational shape of
//! [`sqlite`] or [`redb`]: no daemon, no network hop, no separate runtime.
//! Open a handle, write vectors, query nearest neighbours — all from inside
//! your binary.
//!
//! The `0.5.0` release re-platforms `iqdb` onto the **iqdb crate family**:
//! it is now the integration layer that composes the family's shared
//! vocabulary ([`iqdb_types`]), its index seam ([`iqdb_index`]), the exact
//! and approximate index implementations ([`iqdb_flat`], [`iqdb_hnsw`],
//! [`iqdb_ivf`]), durable storage ([`iqdb_persist`]), and an optional result
//! cache ([`iqdb_cache`]). The public vocabulary — [`Vector`], [`VectorId`],
//! [`Metadata`], [`Value`], [`Hit`], [`Filter`], [`DistanceMetric`] — is
//! re-exported from the family so it agrees across every `iqdb-*` crate.
//!
//! ## The handle
//!
//! [`Iqdb`] is the one type most callers construct. A database fixes its
//! dimensionality and [`DistanceMetric`] at open time, then exposes a small
//! surface: `upsert` / `get` / `delete` for record management, `search` /
//! `search_with` (plus batch variants) for top-`k` similarity search, and
//! `flush` / `optimize` / `close` for maintenance.
//!
//! ## Choosing an index
//!
//! Tier 1 — [`Iqdb::open_in_memory`] and [`Iqdb::open`] default to the exact
//! flat index. Tier 2 — pass an [`IqdbConfig`] to
//! [`Iqdb::open_in_memory_with`] / [`Iqdb::open_with`] to select an
//! approximate index ([`IndexKind::Hnsw`] / [`IndexKind::Ivf`]) and tune it,
//! or to attach a [`CacheConfig`]. Flat is the recall ground truth that the
//! approximate indices are measured against.
//!
//! [`sqlite`]: https://www.sqlite.org/
//! [`redb`]: https://crates.io/crates/redb
//!
//! # Examples
//!
//! Open an in-memory database, upsert a record, look it up, and search:
//!
//! ```
//! use iqdb::{DistanceMetric, Iqdb, Result, Vector, VectorId};
//!
//! fn run() -> Result<()> {
//! let db = Iqdb::open_in_memory(3, DistanceMetric::Cosine)?;
//!
//! db.upsert(VectorId::from(1u64), Vector::new(vec![0.1, 0.2, 0.3])?, None)?;
//! db.upsert(VectorId::from(2u64), Vector::new(vec![0.9, 0.1, 0.0])?, None)?;
//!
//! let hits = db.search(&Vector::new(vec![0.1, 0.2, 0.3])?, 1)?;
//! assert_eq!(hits[0].id, VectorId::from(1u64));
//! Ok(())
//! }
//! # run().unwrap();
//! ```
//!
//! Select an HNSW index and a result cache through [`IqdbConfig`]:
//!
//! ```
//! use iqdb::{CacheConfig, DistanceMetric, HnswConfig, IndexKind, Iqdb, IqdbConfig};
//!
//! # fn run() -> iqdb::Result<()> {
//! let cfg = IqdbConfig::new(128, DistanceMetric::Cosine)
//! .index(IndexKind::Hnsw(HnswConfig::default().with_ef_search(96)))
//! .cache(CacheConfig::new().capacity(10_000));
//! let db = Iqdb::open_in_memory_with(cfg)?;
//! assert!(db.is_empty());
//! # Ok(())
//! # }
//! # run().unwrap();
//! ```
// Test code is allowed to use the convenience panickers — the strict lint
// profile above is for production library code, not assertion scaffolding
// inside `#[cfg(test)]` modules.
pub use ;
pub use ;
pub use Iqdb;
// Re-export the cache-statistics type so `Iqdb::cache_stats` is usable
// without a second dependency.
pub use CacheStats;
// The shared vocabulary, re-exported from `iqdb-types` so it is identical
// across the whole iqdb family.
pub use ;