use parry::partitioning::IndexedData;
use std::cmp;
use std::iter::{self, Extend, FromIterator, FusedIterator};
use std::mem;
use std::ops;
use std::slice;
use std::vec;
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct Arena<T> {
items: Vec<Entry<T>>,
generation: u64,
free_list_head: Option<usize>,
len: usize,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
enum Entry<T> {
Free { next_free: Option<usize> },
Occupied { generation: u64, value: T },
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct Index {
index: usize,
generation: u64,
}
impl IndexedData for Index {
fn default() -> Self {
Self::from_raw_parts(crate::INVALID_USIZE, crate::INVALID_U64)
}
fn index(&self) -> usize {
self.into_raw_parts().0
}
}
impl Index {
pub fn from_raw_parts(a: usize, b: u64) -> Index {
Index {
index: a,
generation: b,
}
}
pub fn into_raw_parts(self) -> (usize, u64) {
(self.index, self.generation)
}
}
const DEFAULT_CAPACITY: usize = 4;
impl<T> Default for Arena<T> {
fn default() -> Arena<T> {
Arena::new()
}
}
impl<T> Arena<T> {
pub fn new() -> Arena<T> {
Arena::with_capacity(DEFAULT_CAPACITY)
}
pub fn with_capacity(n: usize) -> Arena<T> {
let n = cmp::max(n, 1);
let mut arena = Arena {
items: Vec::new(),
generation: 0,
free_list_head: None,
len: 0,
};
arena.reserve(n);
arena
}
pub fn clear(&mut self) {
self.items.clear();
let end = self.items.capacity();
self.items.extend((0..end).map(|i| {
if i == end - 1 {
Entry::Free { next_free: None }
} else {
Entry::Free {
next_free: Some(i + 1),
}
}
}));
self.free_list_head = Some(0);
self.len = 0;
}
#[inline]
pub fn try_insert(&mut self, value: T) -> Result<Index, T> {
match self.try_alloc_next_index() {
None => Err(value),
Some(index) => {
self.items[index.index] = Entry::Occupied {
generation: self.generation,
value,
};
Ok(index)
}
}
}
#[inline]
pub fn try_insert_with<F: FnOnce(Index) -> T>(&mut self, create: F) -> Result<Index, F> {
match self.try_alloc_next_index() {
None => Err(create),
Some(index) => {
self.items[index.index] = Entry::Occupied {
generation: self.generation,
value: create(index),
};
Ok(index)
}
}
}
#[inline]
fn try_alloc_next_index(&mut self) -> Option<Index> {
match self.free_list_head {
None => None,
Some(i) => match self.items[i] {
Entry::Occupied { .. } => panic!("corrupt free list"),
Entry::Free { next_free } => {
self.free_list_head = next_free;
self.len += 1;
Some(Index {
index: i,
generation: self.generation,
})
}
},
}
}
#[inline]
pub fn insert(&mut self, value: T) -> Index {
match self.try_insert(value) {
Ok(i) => i,
Err(value) => self.insert_slow_path(value),
}
}
#[inline]
pub fn insert_with(&mut self, create: impl FnOnce(Index) -> T) -> Index {
match self.try_insert_with(create) {
Ok(i) => i,
Err(create) => self.insert_with_slow_path(create),
}
}
#[inline(never)]
fn insert_slow_path(&mut self, value: T) -> Index {
let len = self.items.len();
self.reserve(len);
self.try_insert(value)
.map_err(|_| ())
.expect("inserting will always succeed after reserving additional space")
}
#[inline(never)]
fn insert_with_slow_path(&mut self, create: impl FnOnce(Index) -> T) -> Index {
let len = self.items.len();
self.reserve(len);
self.try_insert_with(create)
.map_err(|_| ())
.expect("inserting will always succeed after reserving additional space")
}
pub fn remove(&mut self, i: Index) -> Option<T> {
if i.index >= self.items.len() {
return None;
}
match self.items[i.index] {
Entry::Occupied { generation, .. } if i.generation == generation => {
let entry = mem::replace(
&mut self.items[i.index],
Entry::Free {
next_free: self.free_list_head,
},
);
self.generation += 1;
self.free_list_head = Some(i.index);
self.len -= 1;
match entry {
Entry::Occupied {
generation: _,
value,
} => Some(value),
_ => unreachable!(),
}
}
_ => None,
}
}
pub fn retain(&mut self, mut predicate: impl FnMut(Index, &mut T) -> bool) {
for i in 0..self.capacity() {
let remove = match &mut self.items[i] {
Entry::Occupied { generation, value } => {
let index = Index {
index: i,
generation: *generation,
};
if predicate(index, value) {
None
} else {
Some(index)
}
}
_ => None,
};
if let Some(index) = remove {
self.remove(index);
}
}
}
pub fn contains(&self, i: Index) -> bool {
self.get(i).is_some()
}
pub fn get(&self, i: Index) -> Option<&T> {
match self.items.get(i.index) {
Some(Entry::Occupied { generation, value }) if *generation == i.generation => {
Some(value)
}
_ => None,
}
}
pub fn get_mut(&mut self, i: Index) -> Option<&mut T> {
match self.items.get_mut(i.index) {
Some(Entry::Occupied { generation, value }) if *generation == i.generation => {
Some(value)
}
_ => None,
}
}
pub fn get2_mut(&mut self, i1: Index, i2: Index) -> (Option<&mut T>, Option<&mut T>) {
let len = self.items.len();
if i1.index == i2.index {
assert!(i1.generation != i2.generation);
if i1.generation > i2.generation {
return (self.get_mut(i1), None);
}
return (None, self.get_mut(i2));
}
if i1.index >= len {
return (None, self.get_mut(i2));
} else if i2.index >= len {
return (self.get_mut(i1), None);
}
let (raw_item1, raw_item2) = {
let (xs, ys) = self.items.split_at_mut(cmp::max(i1.index, i2.index));
if i1.index < i2.index {
(&mut xs[i1.index], &mut ys[0])
} else {
(&mut ys[0], &mut xs[i2.index])
}
};
let item1 = match raw_item1 {
Entry::Occupied { generation, value } if *generation == i1.generation => Some(value),
_ => None,
};
let item2 = match raw_item2 {
Entry::Occupied { generation, value } if *generation == i2.generation => Some(value),
_ => None,
};
(item1, item2)
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn capacity(&self) -> usize {
self.items.len()
}
pub fn reserve(&mut self, additional_capacity: usize) {
let start = self.items.len();
let end = self.items.len() + additional_capacity;
let old_head = self.free_list_head;
self.items.reserve_exact(additional_capacity);
self.items.extend((start..end).map(|i| {
if i == end - 1 {
Entry::Free {
next_free: old_head,
}
} else {
Entry::Free {
next_free: Some(i + 1),
}
}
}));
self.free_list_head = Some(start);
}
pub fn iter(&self) -> Iter<T> {
Iter {
len: self.len,
inner: self.items.iter().enumerate(),
}
}
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut {
len: self.len,
inner: self.items.iter_mut().enumerate(),
}
}
pub fn drain(&mut self) -> Drain<T> {
Drain {
inner: self.items.drain(..).enumerate(),
}
}
pub fn get_unknown_gen(&self, i: usize) -> Option<(&T, Index)> {
match self.items.get(i) {
Some(Entry::Occupied { generation, value }) => Some((
value,
Index {
generation: *generation,
index: i,
},
)),
_ => None,
}
}
pub fn get_unknown_gen_mut(&mut self, i: usize) -> Option<(&mut T, Index)> {
match self.items.get_mut(i) {
Some(Entry::Occupied { generation, value }) => Some((
value,
Index {
generation: *generation,
index: i,
},
)),
_ => None,
}
}
}
impl<T> IntoIterator for Arena<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
len: self.len,
inner: self.items.into_iter(),
}
}
}
#[derive(Clone, Debug)]
pub struct IntoIter<T> {
len: usize,
inner: vec::IntoIter<Entry<T>>,
}
impl<T> Iterator for IntoIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.inner.next() {
Some(Entry::Free { .. }) => continue,
Some(Entry::Occupied { value, .. }) => {
self.len -= 1;
return Some(value);
}
None => {
debug_assert_eq!(self.len, 0);
return None;
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl<T> DoubleEndedIterator for IntoIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
match self.inner.next_back() {
Some(Entry::Free { .. }) => continue,
Some(Entry::Occupied { value, .. }) => {
self.len -= 1;
return Some(value);
}
None => {
debug_assert_eq!(self.len, 0);
return None;
}
}
}
}
}
impl<T> ExactSizeIterator for IntoIter<T> {
fn len(&self) -> usize {
self.len
}
}
impl<T> FusedIterator for IntoIter<T> {}
impl<'a, T> IntoIterator for &'a Arena<T> {
type Item = (Index, &'a T);
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[derive(Clone, Debug)]
pub struct Iter<'a, T: 'a> {
len: usize,
inner: iter::Enumerate<slice::Iter<'a, Entry<T>>>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = (Index, &'a T);
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.inner.next() {
Some((_, &Entry::Free { .. })) => continue,
Some((
index,
&Entry::Occupied {
generation,
ref value,
},
)) => {
self.len -= 1;
let idx = Index { index, generation };
return Some((idx, value));
}
None => {
debug_assert_eq!(self.len, 0);
return None;
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
match self.inner.next_back() {
Some((_, &Entry::Free { .. })) => continue,
Some((
index,
&Entry::Occupied {
generation,
ref value,
},
)) => {
self.len -= 1;
let idx = Index { index, generation };
return Some((idx, value));
}
None => {
debug_assert_eq!(self.len, 0);
return None;
}
}
}
}
}
impl<'a, T> ExactSizeIterator for Iter<'a, T> {
fn len(&self) -> usize {
self.len
}
}
impl<'a, T> FusedIterator for Iter<'a, T> {}
impl<'a, T> IntoIterator for &'a mut Arena<T> {
type Item = (Index, &'a mut T);
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
#[derive(Debug)]
pub struct IterMut<'a, T: 'a> {
len: usize,
inner: iter::Enumerate<slice::IterMut<'a, Entry<T>>>,
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = (Index, &'a mut T);
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.inner.next() {
Some((_, &mut Entry::Free { .. })) => continue,
Some((
index,
&mut Entry::Occupied {
generation,
ref mut value,
},
)) => {
self.len -= 1;
let idx = Index { index, generation };
return Some((idx, value));
}
None => {
debug_assert_eq!(self.len, 0);
return None;
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
loop {
match self.inner.next_back() {
Some((_, &mut Entry::Free { .. })) => continue,
Some((
index,
&mut Entry::Occupied {
generation,
ref mut value,
},
)) => {
self.len -= 1;
let idx = Index { index, generation };
return Some((idx, value));
}
None => {
debug_assert_eq!(self.len, 0);
return None;
}
}
}
}
}
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
fn len(&self) -> usize {
self.len
}
}
impl<'a, T> FusedIterator for IterMut<'a, T> {}
#[derive(Debug)]
pub struct Drain<'a, T: 'a> {
inner: iter::Enumerate<vec::Drain<'a, Entry<T>>>,
}
impl<'a, T> Iterator for Drain<'a, T> {
type Item = (Index, T);
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.inner.next() {
Some((_, Entry::Free { .. })) => continue,
Some((index, Entry::Occupied { generation, value })) => {
let idx = Index { index, generation };
return Some((idx, value));
}
None => return None,
}
}
}
}
impl<T> Extend<T> for Arena<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
for t in iter {
self.insert(t);
}
}
}
impl<T> FromIterator<T> for Arena<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let iter = iter.into_iter();
let (lower, upper) = iter.size_hint();
let cap = upper.unwrap_or(lower);
let cap = cmp::max(cap, 1);
let mut arena = Arena::with_capacity(cap);
arena.extend(iter);
arena
}
}
impl<T> ops::Index<Index> for Arena<T> {
type Output = T;
fn index(&self, index: Index) -> &Self::Output {
self.get(index).expect("No element at index")
}
}
impl<T> ops::IndexMut<Index> for Arena<T> {
fn index_mut(&mut self, index: Index) -> &mut Self::Output {
self.get_mut(index).expect("No element at index")
}
}