Insert into an IVF-PQ index, returning the assigned vector ID.
(
&mut self,
task: &ExecutionTask,
index_key: &(TenantId, String),
vector: &[f32],
dim: usize,
surrogate: Surrogate,
)
| 132 | |
| 133 | /// Insert into an IVF-PQ index, returning the assigned vector ID. |
| 134 | fn ivf_insert( |
| 135 | &mut self, |
| 136 | task: &ExecutionTask, |
| 137 | index_key: &(TenantId, String), |
| 138 | vector: &[f32], |
| 139 | dim: usize, |
| 140 | surrogate: Surrogate, |
| 141 | ) -> Response { |
| 142 | let ivf = self |
| 143 | .ivf_indexes |
| 144 | .entry(index_key.clone()) |
| 145 | .or_insert_with(|| { |
| 146 | let cfg = self |
| 147 | .index_configs |
| 148 | .get(index_key) |
| 149 | .cloned() |
| 150 | .unwrap_or_default(); |
| 151 | let params = cfg.to_ivf_params(); |
| 152 | debug!( |
| 153 | core = self.core_id, |
| 154 | key = %index_key.1, |
| 155 | "creating IVF-PQ index" |
| 156 | ); |
| 157 | crate::engine::vector::ivf::IvfPqIndex::new(dim, params) |
| 158 | }); |
| 159 | |
| 160 | // IVF-PQ requires training before the first insert. |
| 161 | if ivf.n_cells() == 0 { |
| 162 | let refs: Vec<&[f32]> = vec![vector]; |
| 163 | ivf.train(&refs); |
| 164 | } |
| 165 | |
| 166 | let vector_id = ivf.add(vector); |
| 167 | |
| 168 | // Register surrogate mapping using the actual IVF-assigned vector ID. |
| 169 | if surrogate != Surrogate::ZERO { |
| 170 | let coll = self |
| 171 | .vector_collections |
| 172 | .entry(index_key.clone()) |
| 173 | .or_insert_with(|| VectorCollection::new(dim, Default::default())); |
| 174 | coll.surrogate_map.insert(vector_id, surrogate); |
| 175 | coll.surrogate_to_local.insert(surrogate, vector_id); |
| 176 | } |
| 177 | |
| 178 | self.checkpoint_coordinator.mark_dirty("vector", 1); |
| 179 | self.response_ok(task) |
| 180 | } |
| 181 | |
| 182 | /// Execute batch vector insert (always to the default/unnamed field). |
| 183 | pub(in crate::data::executor) fn execute_vector_batch_insert( |
no test coverage detected