use crate::{Error, GenerationalIndex};
use std::collections::{HashMap, VecDeque};
use std::ops::Index;
pub struct DenseVec<T> {
vec: Vec<T>,
free: VecDeque<usize>,
generations: HashMap<usize, usize>,
}
impl<T> DenseVec<T> {
pub fn with_capacity(capacity: usize) -> DenseVec<T> {
let mut temp_deque = VecDeque::with_capacity(capacity);
let mut temp_map = HashMap::with_capacity(capacity);
let temp_vec: Vec<T> = Vec::with_capacity(capacity);
for i in 0..capacity {
temp_deque.push_back(i);
temp_map.insert(i, 0);
}
DenseVec {
vec: temp_vec,
free: temp_deque,
generations: temp_map,
}
}
pub fn get(&self, index: GenerationalIndex) -> Option<&T> {
if self.generations[&index.index()] == index.generation() {
self.vec.get(index.index())
} else {
None
}
}
pub fn insert(&mut self, value: T) -> GenerationalIndex {
if let Some(idx) = self.free.pop_front() {
self.vec.insert(idx, value);
GenerationalIndex::new(idx, self.generations[&idx])
} else {
let vec_len = self.vec.len();
self.generations.reserve(1);
self.generations.insert(vec_len, 0);
self.vec.push(value);
self.free.reserve(1);
GenerationalIndex::new(vec_len, 0)
}
}
pub fn remove(&mut self, index: GenerationalIndex) -> Result<(), Error> {
if let Some(_val) = self.vec.get(index.index()) {
if self.generations[&index.index()] == index.generation() {
let x = self.generations.get_mut(&index.index()).unwrap();
self.vec.remove(index.index());
self.free.push_back(index.index());
*x += 1;
Ok(())
} else {
Err(Error::WrongGeneration)
}
} else {
Err(Error::ElementNotFound)
}
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.vec.iter()
}
}
impl<T> IntoIterator for DenseVec<T> {
type Item = T;
type IntoIter = ::std::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.vec.into_iter()
}
}
impl<T> Index<GenerationalIndex> for DenseVec<T> {
type Output = T;
fn index(&self, index: GenerationalIndex) -> &Self::Output {
if self.generations[&index.index()] == index.generation() {
&self.vec[index.index()]
} else {
panic!(format!(
"Generation does not match!
Index generation: \u{1b}[38:5:1m{}
Current generation: \u{1b}[38:5:4m{}\n",
index.generation(),
self.generations[&index.index()]
))
}
}
}