use std::{ cmp::Ordering, fmt::Debug, path::{Path, PathBuf}, }; use brk_vec::{ Compressed, DynamicVec, Error, GenericVec, Result, StoredIndex, StoredType, StoredVec, StoredVecIterator, Value, Version, }; use super::Height; #[derive(Debug, Clone)] pub struct IndexedVec where I: StoredIndex, T: StoredType, { height: Option, inner: StoredVec, } impl IndexedVec where I: StoredIndex, T: StoredType, { pub fn forced_import( path: &Path, version: Version, compressed: Compressed, ) -> brk_vec::Result { let mut inner = StoredVec::forced_import(path, version, compressed)?; inner.enable_large_cache_if_needed(); Ok(Self { height: Height::try_from(Self::path_height_(path).as_path()).ok(), inner, }) } #[inline] pub fn get(&self, index: I) -> Result>> { self.inner.get(index) } #[inline] pub fn push_if_needed(&mut self, index: I, value: T) -> Result<()> { match self.inner.len().cmp(&index.to_usize()?) { Ordering::Greater => { // dbg!(len, index, &self.pathbuf); // panic!(); Ok(()) } Ordering::Equal => { self.inner.push(value); Ok(()) } Ordering::Less => { dbg!(index, value, self.inner.len(), self.path_height()); Err(Error::IndexTooHigh) } } } pub fn truncate_if_needed(&mut self, index: I, height: Height) -> brk_vec::Result<()> { if self.height.is_none_or(|self_height| self_height != height) { height.write(&self.path_height())?; } self.inner.truncate_if_needed(index)?; Ok(()) } pub fn flush(&mut self, height: Height) -> Result<()> { height.write(&self.path_height())?; self.inner.flush() } pub fn vec(&self) -> &StoredVec { &self.inner } pub fn mut_vec(&mut self) -> &mut StoredVec { &mut self.inner } pub fn any_vec(&self) -> &dyn brk_vec::AnyStoredVec { &self.inner } pub fn len(&self) -> usize { self.inner.len() } pub fn is_empty(&self) -> bool { self.inner.is_empty() } #[inline] pub fn hasnt(&self, index: I) -> Result { self.inner.has(index).map(|b| !b) } pub fn height(&self) -> brk_core::Result { Height::try_from(self.path_height().as_path()) } fn path_height(&self) -> PathBuf { Self::path_height_(self.inner.path()) } fn path_height_(path: &Path) -> PathBuf { path.join("height") } pub fn iter(&self) -> StoredVecIterator<'_, I, T> { self.into_iter() } pub fn iter_at(&self, i: I) -> StoredVecIterator<'_, I, T> { let mut iter = self.into_iter(); iter.set(i); iter } } pub trait AnyIndexedVec: Send + Sync { fn height(&self) -> brk_core::Result; fn flush(&mut self, height: Height) -> Result<()>; } impl AnyIndexedVec for IndexedVec where I: StoredIndex, T: StoredType, { fn height(&self) -> brk_core::Result { self.height() } fn flush(&mut self, height: Height) -> Result<()> { self.flush(height) } } impl<'a, I, T> IntoIterator for &'a IndexedVec where I: StoredIndex, T: StoredType, { type Item = (I, Value<'a, T>); type IntoIter = StoredVecIterator<'a, I, T>; fn into_iter(self) -> Self::IntoIter { self.inner.into_iter() } }