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 reserve(&mut self, additional: usize) -> StorageBackendResult<()> {
28        match &mut self.0 {
29            Buffer::Ordinary(values) => values.reserve(additional),
30            Buffer::Controlled(values) => values.reserve(additional)?,
31        }
32        Ok(())
33    }
34
35    pub(crate) fn push(&mut self, value: T) -> StorageBackendResult<()> {
36        match &mut self.0 {
37            Buffer::Ordinary(values) => values.push(value),
38            Buffer::Controlled(values) => values.push(value)?,
39        }
40        Ok(())
41    }
42
43    pub(crate) fn clear(&mut self) {
44        match &mut self.0 {
45            Buffer::Ordinary(values) => values.clear(),
46            Buffer::Controlled(values) => values.clear(),
47        }
48    }
49
50    pub(crate) fn truncate(&mut self, len: usize) {
51        match &mut self.0 {
52            Buffer::Ordinary(values) => values.truncate(len),
53            Buffer::Controlled(values) => values.truncate(len),
54        }
55    }
56
57    pub(crate) fn into_parts(self) -> (Vec<T>, Option<MemoryReservation>) {
58        match self.0 {
59            Buffer::Ordinary(values) => (values, None),
60            Buffer::Controlled(values) => {
61                let (values, memory) = values.into_parts();
62                (values, Some(memory))
63            }
64        }
65    }
66}
67
68impl<T: Copy> VectorQueryBuffer<T> {
69    pub(crate) fn extend_from_slice(&mut self, source: &[T]) -> StorageBackendResult<()> {
70        match &mut self.0 {
71            Buffer::Ordinary(values) => values.extend_from_slice(source),
72            Buffer::Controlled(values) => values.extend_from_slice(source)?,
73        }
74        Ok(())
75    }
76}
77
78impl<T> std::ops::Deref for VectorQueryBuffer<T> {
79    type Target = [T];
80
81    fn deref(&self) -> &[T] {
82        match &self.0 {
83            Buffer::Ordinary(values) => values,
84            Buffer::Controlled(values) => values,
85        }
86    }
87}
88
89impl<T> std::ops::DerefMut for VectorQueryBuffer<T> {
90    fn deref_mut(&mut self) -> &mut [T] {
91        match &mut self.0 {
92            Buffer::Ordinary(values) => values,
93            Buffer::Controlled(values) => values,
94        }
95    }
96}