use crate::{
error::ResourceStorageError,
structs::{NoOverlap, Overlap, Struct},
SliceExt,
};
use crate::storage::ResourceHandle;
use std::{borrow::BorrowMut, fmt, io, slice::SliceIndex};
pub struct Vector<T>
where
T: Struct,
{
data: Vec<T>,
}
impl<T> Vector<T>
where
T: Struct,
{
#[inline]
pub fn new() -> Self {
Self::with_len(0)
}
#[inline]
pub fn clear(&mut self) {
self.data.clear();
self.data.push(unsafe { T::create_unchecked() });
}
#[inline]
pub fn with_len(len: usize) -> Self {
let mut data = Vec::with_capacity(len + 1);
data.resize_with(len + 1, || unsafe { T::create_unchecked() });
Self { data }
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.data.reserve(self.data.len() + additional)
}
#[inline]
pub fn as_view(&self) -> &[T] {
if T::IS_OVERLAPPING_WITH_NEXT {
&self.data[0..self.data.len().saturating_sub(2)]
} else {
&self.data[0..self.data.len() - 1]
}
}
#[inline]
pub fn grow(&mut self) -> &mut T {
let next = self.len();
self.data.push(unsafe { T::create_unchecked() });
&mut self.data[next]
}
}
impl<T> std::ops::Deref for Vector<T>
where
T: Struct,
{
type Target = [T];
fn deref(&self) -> &[T] {
let len = self.data.len() - 1;
&self.data[0..len]
}
}
impl<T> std::ops::DerefMut for Vector<T>
where
T: Struct + NoOverlap,
{
fn deref_mut(&mut self) -> &mut [T] {
let len = self.data.len() - 1;
&mut self.data[0..len]
}
}
impl<T, Idx> std::ops::Index<Idx> for Vector<T>
where
T: Struct + Overlap,
Idx: SliceIndex<[T]>,
{
type Output = Idx::Output;
fn index(&self, index: Idx) -> &Idx::Output {
&self.data[index]
}
}
impl<T> std::ops::IndexMut<usize> for Vector<T>
where
T: Struct + Overlap,
{
fn index_mut(&mut self, index: usize) -> &mut T {
&mut self.data[index]
}
}
impl<T> Default for Vector<T>
where
T: Struct,
{
fn default() -> Self {
Vector::new()
}
}
impl<T> fmt::Debug for Vector<T>
where
T: Struct + std::fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.as_view().fmt(f)
}
}
pub struct ExternalVector<'a, T>
where
T: Struct,
{
data: Vector<T>,
len: usize,
resource_handle: ResourceHandle<'a>,
}
impl<'a, T> ExternalVector<'a, T>
where
T: Struct,
{
pub fn new(resource_handle: ResourceHandle<'a>) -> Self {
Self {
data: Vector::new(),
len: 0,
resource_handle,
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn grow(&mut self) -> io::Result<&mut T> {
if self.data.as_view().as_bytes().len() > 1024 * 1024 * 32 {
self.flush()?;
}
self.len += 1;
Ok(self.data.grow())
}
fn flush(&mut self) -> io::Result<()> {
self.resource_handle
.borrow_mut()
.write(&self.data.as_view().as_bytes())?;
self.data.clear();
Ok(())
}
pub fn close(mut self) -> Result<&'a [T], ResourceStorageError> {
if self.data.len() > 0 || self.len == 0 {
self.flush().map_err(|e| {
ResourceStorageError::from_io_error(e, self.resource_handle.name().into())
})?;
}
self.resource_handle
.close()
.map(|data| <&[T]>::from_bytes(data).expect("Corrupted data"))
}
}
impl<T> fmt::Debug for ExternalVector<'_, T>
where
T: Struct,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ExternalVector {{ len: {} }}", self.len())
}
}
#[cfg(test)]
#[allow(dead_code)]
mod tests {
use super::*;
use crate::test::{A, R};
#[test]
fn test_vector_new() {
let v: Vector<A> = Vector::new();
assert_eq!(v.len(), 0);
}
#[test]
fn test_vector_range() {
let mut v: Vector<R> = Vector::with_len(3);
v[0].set_first_x(10);
v[1].set_first_x(20);
v[2].set_first_x(30);
assert_eq!(v[0].x(), 10..20);
assert_eq!(v[1].x(), 20..30);
assert_eq!(v[2].x(), 30..0);
}
#[test]
fn test_vector_index() {
let mut v: Vector<A> = Vector::with_len(2);
assert_eq!(v.len(), 2);
{
let a = &mut v[0];
a.set_x(1);
a.set_y(2);
assert_eq!(a.x(), 1);
assert_eq!(a.y(), 2);
}
{
let b = &mut v[1];
b.set_x(3);
b.set_y(4);
assert_eq!(b.x(), 3);
assert_eq!(b.y(), 4);
}
let a = &mut v[0];
assert_eq!(a.x(), 1);
assert_eq!(a.y(), 2);
let b = &mut v[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 a = &mut v[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[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 a = &mut v[0];
a.set_x(1);
a.set_y(2);
assert_eq!(a.x(), 1);
assert_eq!(a.y(), 2);
}
{
let 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[0];
assert_eq!(a.x(), 1);
assert_eq!(a.y(), 2);
let b = &v[1];
assert_eq!(b.x(), 3);
assert_eq!(b.y(), 4);
}
v.grow();
assert_eq!(v.len(), 3);
}
#[test]
fn test_ability_to_get_mut_and_const_for_non_overlap() {
let mut v: Vector<A> = Vector::with_len(10);
let mut_v_ref = &mut v[..];
let (left, right) = mut_v_ref.split_at_mut(5);
let x = &mut left[4];
let y = &mut right[0];
y.set_x(10);
assert_eq!(y.x(), 10);
assert_eq!(x.x(), 0);
}
}