use crate::archive::Struct;
use crate::arrayview::ArrayView;
use crate::error::ResourceStorageError;
use crate::memory;
use crate::storage::ResourceHandle;
use std::borrow::{Borrow, BorrowMut};
use std::fmt;
use std::io;
use std::marker;
#[derive(Clone)]
pub struct Vector<T> {
data: Vec<u8>,
_phantom: marker::PhantomData<T>,
}
impl<T> Vector<T>
where
T: for<'b> Struct<'b>,
{
#[inline]
pub fn new() -> Self {
Self::with_len(0)
}
#[inline]
pub fn with_len(len: usize) -> Self {
let size = Self::calc_size(len);
Self {
data: vec![0; size],
_phantom: marker::PhantomData,
}
}
#[inline]
pub fn size_in_bytes(&self) -> usize {
self.data.len() - memory::PADDING_SIZE
}
#[inline]
pub fn len(&self) -> usize {
self.size_in_bytes() / <T as Struct>::SIZE_IN_BYTES
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
let additional_bytes = Self::calc_size(self.len() + additional) - self.size_in_bytes();
self.data.reserve(additional_bytes)
}
#[inline]
pub fn as_view(&self) -> ArrayView<T> {
ArrayView::new(&self.data[..self.size_in_bytes()])
}
#[inline]
pub fn as_bytes(&self) -> &[u8] {
&self.data[..self.size_in_bytes()]
}
#[inline]
pub fn grow(&mut self) -> <T as Struct>::ItemMut {
let old_size = self.data.len();
self.data.resize(old_size + <T as Struct>::SIZE_IN_BYTES, 0);
let last_index = self.len() - 1;
T::create_mut(&mut self.data[last_index * <T as Struct>::SIZE_IN_BYTES..])
}
#[inline]
pub fn at(&self, index: usize) -> <T as Struct>::Item {
T::create(&self.data[index * <T as Struct>::SIZE_IN_BYTES..])
}
#[inline]
pub fn at_mut(&mut self, index: usize) -> <T as Struct>::ItemMut {
T::create_mut(&mut self.data[index * <T as Struct>::SIZE_IN_BYTES..])
}
#[inline]
fn calc_size(len: usize) -> usize {
len * <T as Struct>::SIZE_IN_BYTES + memory::PADDING_SIZE
}
}
impl<T> Default for Vector<T>
where
T: for<'b> Struct<'b>,
{
fn default() -> Self {
Vector::new()
}
}
impl<T> AsRef<[u8]> for Vector<T>
where
T: for<'b> Struct<'b>,
{
fn as_ref(&self) -> &[u8] {
self.as_bytes()
}
}
impl<T> fmt::Debug for Vector<T>
where
T: for<'b> Struct<'b>,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let view = self.as_view();
let preview: Vec<_> = view.iter().take(super::DEBUG_PREVIEW_LEN).collect();
write!(
f,
"Vector {{ len: {}, data: {:?}{} }}",
self.len(),
preview,
if self.len() <= super::DEBUG_PREVIEW_LEN {
""
} else {
"..."
}
)
}
}
pub struct ExternalVector<'a, T> {
data: Vec<u8>,
len: usize,
resource_handle: ResourceHandle<'a>,
_phantom: marker::PhantomData<T>,
}
impl<'a, T> ExternalVector<'a, T>
where
T: for<'b> Struct<'b>,
{
pub fn new(resource_handle: ResourceHandle<'a>) -> Self {
Self {
data: vec![0; memory::PADDING_SIZE],
len: 0,
resource_handle,
_phantom: marker::PhantomData,
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn grow(&mut self) -> io::Result<<T as Struct>::ItemMut> {
if self.data.len() > 1024 * 1024 * 32 {
self.flush()?;
}
let old_size = self.data.len();
self.data.resize(old_size + <T as Struct>::SIZE_IN_BYTES, 0);
self.len += 1;
Ok(T::create_mut(
&mut self.data[old_size - memory::PADDING_SIZE..],
))
}
fn flush(&mut self) -> io::Result<()> {
self.resource_handle
.borrow_mut()
.write(&self.data[..self.data.len() - memory::PADDING_SIZE])?;
self.data.resize(0, 0);
self.data.resize(memory::PADDING_SIZE, 0);
Ok(())
}
pub fn is_open(&self) -> bool {
self.resource_handle.borrow().is_open()
}
pub fn close(mut self) -> Result<ArrayView<'a, T>, ResourceStorageError> {
self.flush().map_err(|e| {
ResourceStorageError::from_io_error(e, self.resource_handle.name().into())
})?;
self.resource_handle
.close()
.map(|data| ArrayView::new(data))
}
}
impl<T> fmt::Debug for ExternalVector<'_, T>
where
T: for<'b> Struct<'b>,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ExternalVector {{ len: {} }}", self.len())
}
}
#[cfg(test)]
#[allow(dead_code)]
mod tests {
use super::*;
define_struct!(
A,
RefA,
RefMutA,
"no_schema",
4,
(x, set_x, u32, 0, 16),
(y, set_y, u32, 16, 16)
);
#[test]
fn test_vector_new() {
let v: Vector<A> = Vector::new();
assert_eq!(v.len(), 0);
}
#[test]
fn test_vector_index() {
let mut v: Vector<A> = Vector::with_len(2);
assert_eq!(v.len(), 2);
{
let mut a = v.at_mut(0);
a.set_x(1);
a.set_y(2);
assert_eq!(a.x(), 1);
assert_eq!(a.y(), 2);
}
{
let mut b = v.at_mut(1);
b.set_x(3);
b.set_y(4);
assert_eq!(b.x(), 3);
assert_eq!(b.y(), 4);
}
let a = v.at(0);
assert_eq!(a.x(), 1);
assert_eq!(a.y(), 2);
let b = v.at(1);
assert_eq!(b.x(), 3);
assert_eq!(b.y(), 4);
}
#[test]
fn test_vector_as_view() {
let mut v: Vector<A> = Vector::with_len(1);
assert_eq!(v.len(), 1);
{
let mut a = v.at_mut(0);
a.set_x(1);
assert_eq!(a.x(), 1);
a.set_y(2);
assert_eq!(a.y(), 2);
}
let view = v.as_view();
let a = view.at(0);
assert_eq!(a.x(), 1);
assert_eq!(a.y(), 2);
}
#[test]
fn test_vector_grow() {
let mut v: Vector<A> = Vector::with_len(1);
assert_eq!(v.len(), 1);
{
let mut a = v.at_mut(0);
a.set_x(1);
a.set_y(2);
assert_eq!(a.x(), 1);
assert_eq!(a.y(), 2);
}
{
let mut b = v.grow();
b.set_x(3);
b.set_y(4);
assert_eq!(b.x(), 3);
assert_eq!(b.y(), 4);
}
{
assert_eq!(v.len(), 2);
let a = &v.at(0);
assert_eq!(a.x(), 1);
assert_eq!(a.y(), 2);
let b = &v.at(1);
assert_eq!(b.x(), 3);
assert_eq!(b.y(), 4);
}
v.grow();
assert_eq!(v.len(), 3);
}
}