Skip to main content

uqa_storage/vector_index/query/
buffer.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7use uqa_core::memory::{BudgetedVec, MemoryReservation};
8
9use crate::{read_control::StorageReadControl, StorageBackendResult};
10
11enum Buffer<T> {
12    Ordinary(Vec<T>),
13    Controlled(BudgetedVec<T>),
14}
15
16/// Owned query output whose allocation stays charged to the selected reader when a read control is supplied. Callers may borrow the values without separating them from their lease; ordinary uncontrolled index APIs retain their existing caller-owned allocation boundary.
17pub struct VectorQueryBuffer<T>(Buffer<T>);
18
19impl<T> VectorQueryBuffer<T> {
20    pub(crate) fn new(control: Option<&StorageReadControl>) -> Self {
21        Self(match control {
22            Some(control) => Buffer::Controlled(BudgetedVec::new(control.memory())),
23            None => Buffer::Ordinary(Vec::new()),
24        })
25    }
26
27    pub(crate) fn ordinary(values: Vec<T>) -> Self {
28        Self(Buffer::Ordinary(values))
29    }
30
31    pub(crate) fn controlled(values: BudgetedVec<T>) -> Self {
32        Self(Buffer::Controlled(values))
33    }
34
35    pub(crate) fn reserve(&mut self, additional: usize) -> StorageBackendResult<()> {
36        match &mut self.0 {
37            Buffer::Ordinary(values) => values.reserve(additional),
38            Buffer::Controlled(values) => values.reserve(additional)?,
39        }
40        Ok(())
41    }
42
43    pub(crate) fn push(&mut self, value: T) -> StorageBackendResult<()> {
44        match &mut self.0 {
45            Buffer::Ordinary(values) => values.push(value),
46            Buffer::Controlled(values) => values.push(value)?,
47        }
48        Ok(())
49    }
50
51    pub(crate) fn clear(&mut self) {
52        match &mut self.0 {
53            Buffer::Ordinary(values) => values.clear(),
54            Buffer::Controlled(values) => values.clear(),
55        }
56    }
57
58    pub(crate) fn truncate(&mut self, len: usize) {
59        match &mut self.0 {
60            Buffer::Ordinary(values) => values.truncate(len),
61            Buffer::Controlled(values) => values.truncate(len),
62        }
63    }
64
65    pub(crate) fn into_parts(self) -> (Vec<T>, Option<MemoryReservation>) {
66        match self.0 {
67            Buffer::Ordinary(values) => (values, None),
68            Buffer::Controlled(values) => {
69                let (values, memory) = values.into_parts();
70                (values, Some(memory))
71            }
72        }
73    }
74}
75
76impl<T: Copy> VectorQueryBuffer<T> {
77    pub(crate) fn extend_from_slice(&mut self, source: &[T]) -> StorageBackendResult<()> {
78        match &mut self.0 {
79            Buffer::Ordinary(values) => values.extend_from_slice(source),
80            Buffer::Controlled(values) => values.extend_from_slice(source)?,
81        }
82        Ok(())
83    }
84}
85
86impl<T> std::ops::Deref for VectorQueryBuffer<T> {
87    type Target = [T];
88
89    fn deref(&self) -> &[T] {
90        match &self.0 {
91            Buffer::Ordinary(values) => values,
92            Buffer::Controlled(values) => values,
93        }
94    }
95}
96
97impl<T> std::ops::DerefMut for VectorQueryBuffer<T> {
98    fn deref_mut(&mut self) -> &mut [T] {
99        match &mut self.0 {
100            Buffer::Ordinary(values) => values,
101            Buffer::Controlled(values) => values,
102        }
103    }
104}