use std::sync::Arc;
use uqa_core::memory::{Budgeted, MemoryReservation};
use crate::StorageBackendError;
mod canonical_vectors;
mod documents;
mod inverted;
mod vectors;
pub struct ReadOnlySnapshot<T: ?Sized>(
Arc<T>,
Option<Arc<MemoryReservation>>,
Option<crate::read_control::StorageReadControl>,
Option<crate::vector_index::VectorReadSnapshot>,
);
impl<T> ReadOnlySnapshot<T> {
pub fn from_budgeted(snapshot: Budgeted<T>) -> crate::StorageBackendResult<Self> {
let mut pending = snapshot.into_parts();
let shared = pending.1.budget().reserve(size_of::<T>())?;
pending.1.absorb(shared);
Self::with_retention(Arc::new(pending.0), pending.1)
}
}
impl<T: ?Sized> ReadOnlySnapshot<T> {
#[must_use]
pub fn new(snapshot: Arc<T>) -> Self {
Self(snapshot, None, None, None)
}
pub(crate) fn with_retention(
snapshot: Arc<T>,
memory: MemoryReservation,
) -> crate::StorageBackendResult<Self> {
let mut pending = (snapshot, memory);
let shared = pending.1.budget().reserve(size_of::<MemoryReservation>())?;
pending.1.absorb(shared);
Ok(Self::with_shared_retention(pending.0, Arc::new(pending.1)))
}
pub(crate) fn with_shared_retention(snapshot: Arc<T>, memory: Arc<MemoryReservation>) -> Self {
Self(snapshot, Some(memory), None, None)
}
}
impl<T: ?Sized> Clone for ReadOnlySnapshot<T> {
fn clone(&self) -> Self {
Self(
Arc::clone(&self.0),
self.1.as_ref().map(Arc::clone),
self.2.clone(),
self.3.clone(),
)
}
}
impl<T: ?Sized> std::ops::Deref for ReadOnlySnapshot<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
fn read_only_error() -> StorageBackendError {
StorageBackendError::Other("cannot write a retained storage snapshot".into())
}
#[cfg(test)]
mod tests;