1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use crate::enums::{FieldType, IndexType, MetricType};
4use crate::error::{VectorDBError, Result};
5
6pub type SparseVector = Vec<Vec<f64>>;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct HNSWParams {
10 #[serde(rename = "M")]
11 pub m: u32,
12 #[serde(rename = "efConstruction")]
13 pub ef_construction: u32,
14}
15
16impl HNSWParams {
17 pub fn new(m: u32, ef_construction: u32) -> Self {
18 Self { m, ef_construction }
19 }
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct IVFFLATParams {
24 pub nlist: u32,
25}
26
27impl IVFFLATParams {
28 pub fn new(nlist: u32) -> Self {
29 Self { nlist }
30 }
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct IVFPQParams {
35 #[serde(rename = "M")]
36 pub m: u32,
37 pub nlist: u32,
38}
39
40impl IVFPQParams {
41 pub fn new(nlist: u32, m: u32) -> Self {
42 Self { m, nlist }
43 }
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct IVFSQ8Params {
48 pub nlist: u32,
49}
50
51impl IVFSQ8Params {
52 pub fn new(nlist: u32) -> Self {
53 Self { nlist }
54 }
55}
56
57pub type IVFSQ4Params = IVFSQ8Params;
58pub type IVFSQ16Params = IVFSQ8Params;
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
61#[serde(untagged)]
62pub enum IndexParams {
63 HNSW(HNSWParams),
64 IVFFLAT(IVFFLATParams),
65 IVFPQ(IVFPQParams),
66 IVFSQ8(IVFSQ8Params),
67 IVFSQ4(IVFSQ4Params),
68 IVFSQ16(IVFSQ16Params),
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct IndexField {
73 #[serde(rename = "fieldName")]
74 pub name: String,
75 #[serde(rename = "fieldType")]
76 pub field_type: FieldType,
77 #[serde(rename = "indexType", skip_serializing_if = "Option::is_none")]
78 pub index_type: Option<IndexType>,
79}
80
81impl IndexField {
82 pub fn new(name: impl Into<String>, field_type: FieldType, index_type: Option<IndexType>) -> Self {
83 Self {
84 name: name.into(),
85 field_type,
86 index_type,
87 }
88 }
89
90 pub fn is_vector_field(&self) -> bool {
91 matches!(
92 self.field_type,
93 FieldType::Vector | FieldType::BinaryVector | FieldType::Float16Vector | FieldType::BFloat16Vector
94 )
95 }
96
97 pub fn is_sparse_vector_field(&self) -> bool {
98 matches!(self.field_type, FieldType::SparseVector)
99 }
100
101 pub fn is_primary_key(&self) -> bool {
102 matches!(self.index_type, Some(IndexType::PRIMARY_KEY))
103 }
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct VectorIndex {
108 #[serde(flatten)]
109 pub base: IndexField,
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub dimension: Option<u32>,
112 #[serde(rename = "metricType", skip_serializing_if = "Option::is_none")]
113 pub metric_type: Option<MetricType>,
114 #[serde(skip_serializing_if = "Option::is_none")]
115 pub params: Option<IndexParams>,
116 #[serde(rename = "indexedCount", skip_serializing_if = "Option::is_none")]
117 pub indexed_count: Option<u64>,
118}
119
120impl VectorIndex {
121 pub fn new(
122 name: impl Into<String>,
123 dimension: u32,
124 index_type: IndexType,
125 metric_type: MetricType,
126 params: Option<IndexParams>,
127 ) -> Self {
128 Self {
129 base: IndexField::new(name, FieldType::Vector, Some(index_type)),
130 dimension: Some(dimension),
131 metric_type: Some(metric_type),
132 params,
133 indexed_count: None,
134 }
135 }
136
137 pub fn with_field_type(
138 name: impl Into<String>,
139 dimension: u32,
140 index_type: IndexType,
141 metric_type: MetricType,
142 field_type: FieldType,
143 params: Option<IndexParams>,
144 ) -> Self {
145 Self {
146 base: IndexField::new(name, field_type, Some(index_type)),
147 dimension: Some(dimension),
148 metric_type: Some(metric_type),
149 params,
150 indexed_count: None,
151 }
152 }
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct FilterIndex {
157 #[serde(flatten)]
158 pub base: IndexField,
159 #[serde(rename = "autoId", skip_serializing_if = "Option::is_none")]
160 pub auto_id: Option<String>,
161}
162
163impl FilterIndex {
164 pub fn new(name: impl Into<String>, field_type: FieldType, index_type: IndexType) -> Self {
165 Self {
166 base: IndexField::new(name, field_type, Some(index_type)),
167 auto_id: None,
168 }
169 }
170
171 pub fn with_auto_id(mut self, auto_id: impl Into<String>) -> Self {
172 self.auto_id = Some(auto_id.into());
173 self
174 }
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
178pub struct SparseIndex {
179 #[serde(flatten)]
180 pub base: IndexField,
181 #[serde(rename = "metricType")]
182 pub metric_type: MetricType,
183}
184
185impl SparseIndex {
186 pub fn new(
187 name: impl Into<String>,
188 index_type: IndexType,
189 metric_type: MetricType,
190 ) -> Self {
191 Self {
192 base: IndexField::new(name, FieldType::SparseVector, Some(index_type)),
193 metric_type,
194 }
195 }
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
199#[serde(untagged)]
200pub enum IndexDefinition {
201 Vector(VectorIndex),
202 Filter(FilterIndex),
203 Sparse(SparseIndex),
204}
205
206impl IndexDefinition {
207 pub fn name(&self) -> &str {
208 match self {
209 IndexDefinition::Vector(idx) => &idx.base.name,
210 IndexDefinition::Filter(idx) => &idx.base.name,
211 IndexDefinition::Sparse(idx) => &idx.base.name,
212 }
213 }
214
215 pub fn is_primary_key(&self) -> bool {
216 match self {
217 IndexDefinition::Vector(idx) => idx.base.is_primary_key(),
218 IndexDefinition::Filter(idx) => idx.base.is_primary_key(),
219 IndexDefinition::Sparse(idx) => idx.base.is_primary_key(),
220 }
221 }
222}
223
224#[derive(Debug, Clone, Default)]
225pub struct Index {
226 indexes: HashMap<String, IndexDefinition>,
227 primary_field: Option<String>,
228}
229
230impl Index {
231 pub fn new() -> Self {
232 Self::default()
233 }
234
235 pub fn add_vector_index(&mut self, index: VectorIndex) -> Result<&mut Self> {
236 let name = index.base.name.clone();
237 if self.indexes.contains_key(&name) {
238 return Err(VectorDBError::server_error(
239 15000,
240 "fieldName must exist and be unique",
241 ));
242 }
243
244 if index.base.is_primary_key() {
245 self.primary_field = Some(name.clone());
246 }
247
248 self.indexes.insert(name, IndexDefinition::Vector(index));
249 Ok(self)
250 }
251
252 pub fn add_filter_index(&mut self, index: FilterIndex) -> Result<&mut Self> {
253 let name = index.base.name.clone();
254 if self.indexes.contains_key(&name) {
255 return Err(VectorDBError::server_error(
256 15000,
257 "fieldName must exist and be unique",
258 ));
259 }
260
261 if index.base.is_primary_key() {
262 self.primary_field = Some(name.clone());
263 }
264
265 self.indexes.insert(name, IndexDefinition::Filter(index));
266 Ok(self)
267 }
268
269 pub fn add_sparse_index(&mut self, index: SparseIndex) -> Result<&mut Self> {
270 let name = index.base.name.clone();
271 if self.indexes.contains_key(&name) {
272 return Err(VectorDBError::server_error(
273 15000,
274 "fieldName must exist and be unique",
275 ));
276 }
277
278 if index.base.is_primary_key() {
279 self.primary_field = Some(name.clone());
280 }
281
282 self.indexes.insert(name, IndexDefinition::Sparse(index));
283 Ok(self)
284 }
285
286 pub fn remove(&mut self, index_name: &str) -> &mut Self {
287 self.indexes.remove(index_name);
288 self
289 }
290
291 pub fn get(&self, name: &str) -> Option<&IndexDefinition> {
292 self.indexes.get(name)
293 }
294
295 pub fn list(&self) -> Vec<&IndexDefinition> {
296 self.indexes.values().collect()
297 }
298
299 pub fn primary_field(&self) -> Option<&str> {
300 self.primary_field.as_deref()
301 }
302
303 pub fn is_empty(&self) -> bool {
304 self.indexes.is_empty()
305 }
306}
307
308impl Serialize for Index {
309 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
310 where
311 S: serde::Serializer,
312 {
313 self.indexes.serialize(serializer)
314 }
315}
316
317impl<'de> Deserialize<'de> for Index {
318 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
319 where
320 D: serde::Deserializer<'de>,
321 {
322 let indexes: HashMap<String, IndexDefinition> = HashMap::deserialize(deserializer)?;
323 let primary_field = indexes
324 .values()
325 .find(|idx| idx.is_primary_key())
326 .map(|idx| idx.name().to_string());
327
328 Ok(Self {
329 indexes,
330 primary_field,
331 })
332 }
333}