use std::ops::{self, Index};
use anyhow::Result;
use crate::merkle::Element;
use crate::store::{Store, StoreConfig};
#[derive(Debug, Clone, Default)]
pub struct VecStore<E: Element>(Vec<E>);
impl<E: Element> ops::Deref for VecStore<E> {
type Target = [E];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<E: Element> Store<E> for VecStore<E> {
fn new_with_config(size: usize, _branches: usize, _config: StoreConfig) -> Result<Self> {
Self::new(size)
}
fn new(size: usize) -> Result<Self> {
Ok(VecStore(Vec::with_capacity(size)))
}
fn write_at(&mut self, el: E, index: usize) -> Result<()> {
if self.0.len() <= index {
self.0.resize(index + 1, E::default());
}
self.0[index] = el;
Ok(())
}
fn copy_from_slice(&mut self, buf: &[u8], start: usize) -> Result<()> {
ensure!(
buf.len() % E::byte_len() == 0,
"buf size must be a multiple of {}",
E::byte_len()
);
let num_elem = buf.len() / E::byte_len();
if self.0.len() < start + num_elem {
self.0.resize(start + num_elem, E::default());
}
self.0.splice(
start..start + num_elem,
buf.chunks_exact(E::byte_len()).map(E::from_slice),
);
Ok(())
}
fn new_from_slice_with_config(
size: usize,
_branches: usize,
data: &[u8],
_config: StoreConfig,
) -> Result<Self> {
Self::new_from_slice(size, data)
}
fn new_from_slice(size: usize, data: &[u8]) -> Result<Self> {
let mut v: Vec<_> = data
.chunks_exact(E::byte_len())
.map(E::from_slice)
.collect();
let additional = size - v.len();
v.reserve(additional);
Ok(VecStore(v))
}
fn new_from_disk(_size: usize, _branches: usize, _config: &StoreConfig) -> Result<Self> {
unimplemented!("Cannot load a VecStore from disk");
}
fn read_at(&self, index: usize) -> Result<E> {
Ok(self.0[index].clone())
}
fn read_into(&self, index: usize, buf: &mut [u8]) -> Result<()> {
self.0[index].copy_to_slice(buf);
Ok(())
}
fn read_range_into(&self, _start: usize, _end: usize, _buf: &mut [u8]) -> Result<()> {
unimplemented!("Not required here");
}
fn read_range(&self, r: ops::Range<usize>) -> Result<Vec<E>> {
Ok(self.0.index(r).to_vec())
}
fn len(&self) -> usize {
self.0.len()
}
fn loaded_from_disk(&self) -> bool {
false
}
fn compact(
&mut self,
_branches: usize,
_config: StoreConfig,
_store_version: u32,
) -> Result<bool> {
self.0.shrink_to_fit();
Ok(true)
}
fn delete(_config: StoreConfig) -> Result<()> {
Ok(())
}
fn is_empty(&self) -> bool {
self.0.is_empty()
}
fn push(&mut self, el: E) -> Result<()> {
self.0.push(el);
Ok(())
}
}