use std::mem::size_of;
use std::path::Path;
use std::marker::PhantomData;
use tokio::io::Result as TokioResult;
use crate::utils::{to_bytes, from_bytes, to_bytes_many, from_bytes_many};
use crate::seq::Seq;
pub struct Col<T> {
seq: Seq,
phantom: PhantomData<T>,
}
impl<T: Clone> Col<T> {
pub async fn new(path: impl AsRef<Path>) -> TokioResult<Self> {
let block_size = Self::block_size();
let seq = Seq::new(path, block_size).await?;
Ok(Self { seq, phantom: PhantomData })
}
pub fn block_size() -> usize {
size_of::<T>()
}
pub async fn size(&self) -> TokioResult<usize> {
self.seq.size().await
}
pub async fn resize(&self, new_size: usize) -> TokioResult<()> {
self.seq.resize(new_size).await
}
pub async fn push(&mut self, x: &T) -> TokioResult<usize> {
let block = to_bytes(x);
let ix = self.seq.push(block).await?;
Ok(ix)
}
pub async fn push_many(&mut self, x: &[T]) -> TokioResult<usize> {
let block = to_bytes_many(x);
let ix = self.seq.push(block).await?;
Ok(ix)
}
pub async fn get(&mut self, ix: usize) -> TokioResult<T> {
let mut block = vec![0u8; Self::block_size()];
self.seq.get(ix, &mut block).await?;
let x: &T = from_bytes(&block);
Ok(x.clone())
}
pub async fn get_many(&mut self, ix: usize, count: usize) ->
TokioResult<Vec<T>> {
if count > 0 {
let mut block = vec![0u8; Self::block_size() * count];
self.seq.get(ix, &mut block).await?;
let x: &[T] = from_bytes_many(&block);
Ok(x.to_vec())
} else {
Ok(vec![])
}
}
pub async fn get_all(&mut self) -> TokioResult<Vec<T>> {
let size = self.seq.size().await?;
if size > 0 {
let mut block = vec![0u8; Self::block_size() * size];
self.seq.get(0, &mut block).await?;
let x: &[T] = from_bytes_many(&block);
Ok(x.to_vec())
} else {
Ok(vec![])
}
}
pub async fn get_raw(&mut self, ix: usize, count: usize) ->
TokioResult<Vec<u8>> {
if count > 0 {
let mut block = vec![0u8; Self::block_size() * count];
self.seq.get(ix, &mut block).await?;
Ok(block)
} else {
Ok(vec![])
}
}
pub async fn update(&mut self, ix: usize, x: &T) -> TokioResult<()> {
let block = to_bytes(x);
self.seq.update(ix, &block).await
}
pub async fn update_many(&mut self, ix: usize, x: &[T]) -> TokioResult<()> {
let block = to_bytes_many(x);
self.seq.update(ix, &block).await
}
pub async fn update_raw(&mut self, ix: usize, block: &[u8]) ->
TokioResult<()> {
self.seq.update(ix, block).await
}
}