velesdb_core/
vector_ref.rs1use std::borrow::Cow;
16use std::ops::Deref;
17
18pub trait VectorRef {
38 fn as_slice(&self) -> &[f32];
40
41 fn dimension(&self) -> usize {
43 self.as_slice().len()
44 }
45
46 fn is_empty(&self) -> bool {
48 self.as_slice().is_empty()
49 }
50}
51
52impl VectorRef for [f32] {
57 #[inline]
58 fn as_slice(&self) -> &[f32] {
59 self
60 }
61}
62
63impl VectorRef for Vec<f32> {
64 #[inline]
65 fn as_slice(&self) -> &[f32] {
66 self
67 }
68}
69
70impl VectorRef for &[f32] {
71 #[inline]
72 fn as_slice(&self) -> &[f32] {
73 self
74 }
75}
76
77impl VectorRef for Cow<'_, [f32]> {
78 #[inline]
79 fn as_slice(&self) -> &[f32] {
80 self
81 }
82}
83
84#[derive(Debug, Clone, Copy)]
89pub struct BorrowedVector<'a> {
90 data: &'a [f32],
91}
92
93impl<'a> BorrowedVector<'a> {
94 #[inline]
96 #[must_use]
97 pub const fn new(data: &'a [f32]) -> Self {
98 Self { data }
99 }
100
101 #[inline]
103 #[must_use]
104 pub const fn data(&self) -> &'a [f32] {
105 self.data
106 }
107}
108
109impl VectorRef for BorrowedVector<'_> {
110 #[inline]
111 fn as_slice(&self) -> &[f32] {
112 self.data
113 }
114}
115
116impl Deref for BorrowedVector<'_> {
117 type Target = [f32];
118
119 #[inline]
120 fn deref(&self) -> &Self::Target {
121 self.data
122 }
123}
124
125impl AsRef<[f32]> for BorrowedVector<'_> {
126 #[inline]
127 fn as_ref(&self) -> &[f32] {
128 self.data
129 }
130}
131
132pub struct VectorGuard<'a, G> {
137 _guard: G,
139 data: &'a [f32],
141}
142
143impl<'a, G> VectorGuard<'a, G> {
144 #[must_use]
151 pub const fn new(guard: G, data: &'a [f32]) -> Self {
152 Self {
153 _guard: guard,
154 data,
155 }
156 }
157}
158
159impl<G> VectorRef for VectorGuard<'_, G> {
160 #[inline]
161 fn as_slice(&self) -> &[f32] {
162 self.data
163 }
164}
165
166impl<G> Deref for VectorGuard<'_, G> {
167 type Target = [f32];
168
169 #[inline]
170 fn deref(&self) -> &Self::Target {
171 self.data
172 }
173}
174
175impl<G> AsRef<[f32]> for VectorGuard<'_, G> {
176 #[inline]
177 fn as_ref(&self) -> &[f32] {
178 self.data
179 }
180}
181
182#[cfg(test)]
187#[allow(clippy::float_cmp)]
188mod tests {
189 use super::*;
190
191 #[test]
196 fn test_vector_ref_slice() {
197 let data: &[f32] = &[1.0, 2.0, 3.0];
199
200 assert_eq!(data.as_slice(), &[1.0, 2.0, 3.0]);
202 assert_eq!(data.dimension(), 3);
203 assert!(!data.is_empty());
204 }
205
206 #[test]
207 fn test_vector_ref_vec() {
208 let data: Vec<f32> = vec![1.0, 2.0, 3.0, 4.0];
210
211 assert_eq!(data.as_slice(), &[1.0, 2.0, 3.0, 4.0]);
213 assert_eq!(data.dimension(), 4);
214 }
215
216 #[test]
217 fn test_vector_ref_cow_borrowed() {
218 let original = vec![1.0, 2.0];
220 let cow: Cow<[f32]> = Cow::Borrowed(&original);
221
222 assert_eq!(cow.as_slice(), &[1.0, 2.0]);
224 assert_eq!(cow.dimension(), 2);
225 }
226
227 #[test]
228 fn test_vector_ref_cow_owned() {
229 let cow: Cow<[f32]> = Cow::Owned(vec![1.0, 2.0, 3.0]);
231
232 assert_eq!(cow.as_slice(), &[1.0, 2.0, 3.0]);
234 }
235
236 #[test]
237 fn test_vector_ref_empty() {
238 let data: &[f32] = &[];
240
241 assert!(data.is_empty());
243 assert_eq!(data.dimension(), 0);
244 }
245
246 #[test]
251 fn test_borrowed_vector_new() {
252 let data = [1.0f32, 2.0, 3.0];
254
255 let borrowed = BorrowedVector::new(&data);
257
258 assert_eq!(borrowed.data(), &[1.0, 2.0, 3.0]);
260 assert_eq!(borrowed.dimension(), 3);
261 }
262
263 #[test]
264 fn test_borrowed_vector_deref() {
265 let data = [1.0f32, 2.0, 3.0];
267 let borrowed = BorrowedVector::new(&data);
268
269 let sum: f32 = borrowed.iter().sum();
271
272 assert_eq!(sum, 6.0);
274 }
275
276 #[test]
277 fn test_borrowed_vector_as_ref() {
278 let data = [1.0f32, 2.0];
280 let borrowed = BorrowedVector::new(&data);
281
282 let slice: &[f32] = borrowed.as_ref();
284
285 assert_eq!(slice, &[1.0, 2.0]);
287 }
288
289 #[test]
294 fn test_vector_guard_basic() {
295 let data = [1.0f32, 2.0, 3.0, 4.0];
297 let guard = (); let vector_guard = VectorGuard::new(guard, &data);
301
302 assert_eq!(vector_guard.as_slice(), &[1.0, 2.0, 3.0, 4.0]);
304 assert_eq!(vector_guard.dimension(), 4);
305 }
306
307 #[test]
308 fn test_vector_guard_deref() {
309 let data = [1.0f32, 2.0, 3.0];
311 let guard = VectorGuard::new((), &data);
312
313 let max = guard.iter().copied().fold(f32::NEG_INFINITY, f32::max);
315
316 assert_eq!(max, 3.0);
318 }
319
320 #[test]
321 fn test_vector_guard_with_real_lock() {
322 use parking_lot::RwLock;
323
324 static DATA: [f32; 3] = [1.0, 2.0, 3.0];
326 let lock = RwLock::new(());
327
328 let read_guard = lock.read();
330 let vector_guard = VectorGuard::new(read_guard, &DATA);
331
332 assert_eq!(vector_guard.as_slice(), &[1.0, 2.0, 3.0]);
334 }
336
337 fn generic_sum<V: VectorRef>(v: &V) -> f32 {
342 v.as_slice().iter().sum()
343 }
344
345 #[test]
346 fn test_generic_function_with_slice() {
347 let data: &[f32] = &[1.0, 2.0, 3.0];
348 assert_eq!(generic_sum(&data), 6.0);
349 }
350
351 #[test]
352 fn test_generic_function_with_vec() {
353 let data = vec![1.0f32, 2.0, 3.0, 4.0];
354 assert_eq!(generic_sum(&data), 10.0);
355 }
356
357 #[test]
358 fn test_generic_function_with_borrowed() {
359 let data = [1.0f32, 2.0];
360 let borrowed = BorrowedVector::new(&data);
361 assert_eq!(generic_sum(&borrowed), 3.0);
362 }
363
364 #[test]
365 fn test_generic_function_with_cow() {
366 let cow: Cow<[f32]> = Cow::Owned(vec![1.0, 2.0, 3.0]);
367 assert_eq!(generic_sum(&cow), 6.0);
368 }
369}