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
//! CRUD and index-mutation operations for `VectorCollection`.
use crate::error::Result;
use crate::point::Point;
use super::VectorCollection;
impl VectorCollection {
/// Bulk insert optimized for high-throughput import.
///
/// # Errors
///
/// Returns an error if any point has a mismatched dimension.
pub fn upsert_bulk(&self, points: &[Point]) -> Result<usize> {
self.inner.upsert_bulk(points)
}
/// Bulk insert from contiguous flat slices (zero-copy from numpy / FFI).
///
/// Accepts a flat `f32` slice of shape `(n, dimension)` in row-major order
/// plus a matching `u64` ID slice of length `n`. Avoids per-row `Vec<f32>`
/// allocation, saving ~293 MB for 100K vectors at 768D.
///
/// # Errors
///
/// - Returns [`Error::InvalidVector`] if `vectors.len() != ids.len() * dimension`.
/// - Returns [`Error::DimensionMismatch`] if `dimension` mismatches the collection.
pub fn upsert_bulk_from_raw(
&self,
vectors: &[f32],
ids: &[u64],
dimension: usize,
payloads: Option<&[Option<serde_json::Value>]>,
) -> Result<usize> {
self.inner
.upsert_bulk_from_raw(vectors, ids, dimension, payloads)
}
/// Inserts or updates points in the collection.
///
/// # Errors
///
/// - Returns an error if any point's dimension does not match the collection.
/// - Returns an error if storage operations fail.
///
/// # Examples
///
/// ```rust,no_run
/// # use velesdb_core::{VectorCollection, DistanceMetric, Point, StorageMode};
/// # use serde_json::json;
/// # let coll = VectorCollection::create("./data/v".into(), "v", 128, DistanceMetric::Cosine, StorageMode::Full)?;
/// coll.upsert(vec![
/// Point::new(1, vec![0.1; 128], Some(json!({"title": "Hello"}))),
/// Point::new(2, vec![0.2; 128], None),
/// ])?;
/// # Ok::<(), velesdb_core::Error>(())
/// ```
pub fn upsert(&self, points: impl IntoIterator<Item = Point>) -> Result<()> {
self.inner.upsert(points)
}
/// Retrieves points by IDs, returning `None` for missing entries.
///
/// # Examples
///
/// ```rust,no_run
/// # use velesdb_core::{VectorCollection, DistanceMetric, StorageMode};
/// # let coll = VectorCollection::create("./data/v".into(), "v", 128, DistanceMetric::Cosine, StorageMode::Full)?;
/// let points = coll.get(&[1, 2, 3]);
/// for (id, maybe_point) in [1, 2, 3].iter().zip(&points) {
/// if let Some(p) = maybe_point {
/// println!("Found point {id} with payload {:?}", p.payload);
/// }
/// }
/// # Ok::<(), velesdb_core::Error>(())
/// ```
#[must_use]
pub fn get(&self, ids: &[u64]) -> Vec<Option<Point>> {
self.inner.get(ids)
}
/// Deletes points by IDs.
///
/// Missing IDs are silently ignored.
///
/// # Errors
///
/// - Returns an error if storage operations fail.
///
/// # Examples
///
/// ```rust,no_run
/// # use velesdb_core::{VectorCollection, DistanceMetric, StorageMode};
/// # let coll = VectorCollection::create("./data/v".into(), "v", 128, DistanceMetric::Cosine, StorageMode::Full)?;
/// coll.delete(&[1, 2, 3])?;
/// # Ok::<(), velesdb_core::Error>(())
/// ```
pub fn delete(&self, ids: &[u64]) -> Result<()> {
self.inner.delete(ids)
}
/// Inserts or updates metadata-only points (no vectors).
///
/// # Errors
///
/// - Returns an error if storage operations fail.
pub fn upsert_metadata(
&self,
points: impl IntoIterator<Item = crate::point::Point>,
) -> Result<()> {
self.inner.upsert_metadata(points)
}
/// Creates a secondary metadata index on a payload field.
///
/// # Errors
///
/// - Returns an error if the index already exists or storage fails.
pub fn create_index(&self, field: &str) -> Result<()> {
self.inner.create_index(field)
}
/// Creates a property index for O(1) equality lookups.
///
/// # Errors
///
/// - Returns an error if the index already exists or storage fails.
pub fn create_property_index(&self, label: &str, property: &str) -> Result<()> {
self.inner.create_property_index(label, property)
}
/// Creates a range index for O(log n) range queries.
///
/// # Errors
///
/// - Returns an error if the index already exists or storage fails.
pub fn create_range_index(&self, label: &str, property: &str) -> Result<()> {
self.inner.create_range_index(label, property)
}
/// Drops an index, returning `true` if an index was removed.
///
/// # Errors
///
/// - Returns an error if the drop operation fails.
pub fn drop_index(&self, label: &str, property: &str) -> Result<bool> {
self.inner.drop_index(label, property)
}
}