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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
//! The [`IndexCore`] and [`Index`] traits.
//!
//! [`IndexCore`] is the object-safe operational surface every index exposes;
//! the engine stores indexes through `Box<dyn IndexCore>`. [`Index`] is the
//! typed-construction sibling that carries the implementer's associated
//! `Config` and a `Self`-returning `new` — used where the concrete type is
//! known, not through `dyn`.
use Arc;
use ;
use crateIndexStats;
/// The object-safe operational surface of an index.
///
/// Every concrete index implements this trait so the engine can hold a
/// heterogeneous set of indexes as `Box<dyn IndexCore>`. The methods are
/// the read/write/diagnose surface; construction is a separate concern, in
/// [`Index`].
///
/// ## Required vs. provided
///
/// Implementers must define [`insert`](IndexCore::insert),
/// [`delete`](IndexCore::delete), [`search`](IndexCore::search),
/// [`len`](IndexCore::len), [`dim`](IndexCore::dim),
/// [`metric`](IndexCore::metric), [`flush`](IndexCore::flush), and
/// [`stats`](IndexCore::stats). [`insert_batch`](IndexCore::insert_batch),
/// [`search_batch`](IndexCore::search_batch), and
/// [`is_empty`](IndexCore::is_empty) have default implementations and may
/// be overridden when a vectorized fast path exists.
///
/// ## Concurrency contract
///
/// Implementers MUST be `Send + Sync` — that bound is on the trait
/// itself, and the engine relies on it to share `Box<dyn IndexCore>`
/// across threads inside its per-shard locks. An implementer needs only
/// to be **single-writer-internal**: the engine guards every concrete
/// index with an external `RwLock`, so the index sees either many
/// concurrent shared (`&self`) accesses OR one exclusive (`&mut self`)
/// access at a time. Indexes therefore do not need their own internal
/// locking; correctness against `&self` aliasing is enough.
///
/// In particular, [`insert`](IndexCore::insert),
/// [`delete`](IndexCore::delete), and [`flush`](IndexCore::flush) take
/// `&mut self` and are only ever called while the engine holds the
/// corresponding shard's write lock; [`search`](IndexCore::search),
/// [`len`](IndexCore::len), [`is_empty`](IndexCore::is_empty),
/// [`dim`](IndexCore::dim), [`metric`](IndexCore::metric), and
/// [`stats`](IndexCore::stats) take `&self` and may be called
/// concurrently from many threads while the shard's write lock is
/// unheld.
///
/// ## Ordering contract on `Hit.distance`
///
/// [`Hit`]'s `distance` is documented as **smaller is nearer**. Four of the
/// five metrics (Cosine, Euclidean, Manhattan, Hamming) satisfy that
/// natively. For [`DistanceMetric::DotProduct`], the raw inner product is a
/// similarity (larger is more similar), so an implementation MUST negate it
/// at the boundary — store `-dot` in `Hit.distance` — to keep one ordering
/// invariant across the index family.
///
/// ## Deletion contract
///
/// [`delete`](IndexCore::delete) is specified by **observable behavior**,
/// not by a storage mechanism. After `delete(id)`:
///
/// - `search` MUST NOT return `id` until a subsequent `insert(id, …)`
/// succeeds.
/// - Whether storage is reclaimed immediately, tombstoned, or compacted
/// later is implementation-defined and surfaced via
/// [`IndexStats::extra`].
///
/// An implementation MAY reject re-inserting a deleted id; if so, it MUST
/// document that and return [`iqdb_types::IqdbError::Duplicate`].
///
/// ## Examples
///
/// See the crate-level docs for a runnable mock implementation that
/// exercises every method of this trait.
/// Typed construction for an index.
///
/// Adds an associated [`Config`](Index::Config) and a `Self`-returning
/// [`new`](Index::new) to the operational surface from [`IndexCore`]. This
/// trait is **not object-safe** — that is by design; the engine holds
/// indexes as `Box<dyn IndexCore>` after they have been constructed
/// through [`Index::new`].
///
/// Every concrete index implements both [`IndexCore`] and `Index`.
///
/// ## Examples
///
/// See the crate-level docs for a runnable mock that implements both
/// traits.