use std::convert::TryFrom;
#[cfg(all(nightly, any(doc, feature = "unstable")))]
use alloc::collections::TryReserveError;
use alloc::collections::VecDeque;
use alloc::vec::Vec;
use core::iter::FusedIterator;
#[allow(unused_imports)] use core::mem::MaybeUninit;
use core::ops::{Index, IndexMut};
use std::sync::atomic::{Ordering, AtomicU32};
use crate::util::{Never, UnwrapUnchecked};
use pi_key_alloter::{DefaultKey, Key, key_data};
#[derive(Debug, Clone)]
struct Slot {
version: u32,
pub(crate) idx: u32, }
#[derive(Debug)]
pub struct DelaySlotMap<K: Key, V> {
keys: Vec<K>,
values: Vec<V>,
slots: Vec<Slot>,
free_head: u32,
free_vec: VecDeque<u32>,
alloc_count: AtomicU32,
}
impl<V> DelaySlotMap<DefaultKey, V> {
pub fn new() -> Self {
Self::with_capacity_and_key(0)
}
pub fn with_capacity(capacity: usize) -> DelaySlotMap<DefaultKey, V> {
Self::with_capacity_and_key(capacity)
}
}
impl<K: Key, V> DelaySlotMap<K, V> {
pub fn with_key() -> Self {
Self::with_capacity_and_key(0)
}
pub fn with_capacity_and_key(capacity: usize) -> Self {
let mut slots = Vec::with_capacity(capacity + 1);
slots.push(Slot {
idx: 0,
version: 0,
});
DelaySlotMap {
keys: Vec::with_capacity(capacity),
values: Vec::with_capacity(capacity),
slots,
free_head: 1,
free_vec: VecDeque::with_capacity(0),
alloc_count: AtomicU32::new(0),
}
}
pub fn reserve_entity(&self) -> K {
let n = self.alloc_count.fetch_add(1, Ordering::Relaxed);
if n < self.free_vec.len() as u32 {
let id = self.free_vec[n as usize];
K::from(unsafe {key_data(id, self.slots[id as usize].version | 1)})
} else {
K::from(unsafe {key_data(u32::try_from(self.slots.len() + (n as usize - self.free_vec.len())).expect("too many entities"), 1)})
}
}
fn verify_flushed(&mut self) {
debug_assert!(
!self.needs_flush(),
"flush() needs to be called before this operation is legal"
);
}
fn needs_flush(&mut self) -> bool {
*self.alloc_count.get_mut() > 0
}
pub unsafe fn flush(&mut self, mut init: impl FnMut(&mut Self, K)) {
let alloc_count = self.alloc_count.get_mut();
let current_alloc_count = *alloc_count as usize;
let count1; let count2; if current_alloc_count > self.free_vec.len() {
count1 = self.free_vec.len();
count2 = current_alloc_count - count1;
} else {
count1 = current_alloc_count;
count2 = 0;
}
for _i in 0..count1 {
let index = self.free_vec[0];
init(self, K::from(unsafe {key_data(index, self.slots[index as usize].version | 1)}));
}
let len = self.slots.len();
for i in 0..count2 {
let index = len + i;
init(self, K::from(unsafe {key_data(index as u32, 1)}));
}
self.alloc_count.swap(0, Ordering::Relaxed);
}
pub fn len(&self) -> usize {
self.keys.len()
}
pub fn is_empty(&self) -> bool {
self.keys.is_empty()
}
pub fn capacity(&self) -> usize {
self.keys.capacity()
}
pub fn reserve(&mut self, additional: usize) {
self.keys.reserve(additional);
self.values.reserve(additional);
let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);
self.slots.reserve(needed);
}
#[cfg(all(nightly, any(doc, feature = "unstable")))]
#[cfg_attr(all(nightly, doc), doc(cfg(feature = "unstable")))]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.keys.try_reserve(additional)?;
self.values.try_reserve(additional)?;
let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);
self.slots.try_reserve(needed)
}
pub fn contains_key(&self, key: K) -> bool {
let kd = key.data();
self.slots
.get(kd.index() as usize)
.map_or(false, |slot| slot.version == kd.version())
}
pub fn insert(&mut self, value: V) -> K {
self.verify_flushed();
unsafe { self.try_insert_with_key::<_, Never>(move |_| Ok(value)).unwrap_unchecked_() }
}
pub fn insert_with_key<F>(&mut self, f: F) -> K
where
F: FnOnce(K) -> V,
{
unsafe { self.try_insert_with_key::<_, Never>(move |k| Ok(f(k))).unwrap_unchecked_() }
}
pub fn try_insert_with_key<F, E>(&mut self, f: F) -> Result<K, E>
where
F: FnOnce(K) -> Result<V, E>,
{
if self.len() >= (core::u32::MAX - 1) as usize {
panic!("DenseSlotMap number of elements overflow");
}
let idx = self.free_vec.pop_front();
if let Some(idx) = idx {
let slot = unsafe{self.slots.get_unchecked_mut(idx as usize)};
let occupied_version = slot.version | 1;
let key = unsafe {key_data(idx, occupied_version)}.into();
self.values.push(f(key)?);
self.keys.push(key);
slot.version = occupied_version;
slot.idx = (self.keys.len() - 1) as u32;
return Ok(key);
}
let key = unsafe {key_data(self.slots.len() as u32, 1)}.into();
self.values.push(f(key)?);
self.keys.push(key);
self.slots.push(Slot {
version: 1,
idx: self.keys.len() as u32 - 1,
});
Ok(key)
}
fn free_slot(&mut self, slot_idx: usize) -> u32 {
let slot = &mut self.slots[slot_idx];
let value_idx = slot.idx;
slot.version = slot.version.wrapping_add(1);
slot.idx = self.free_vec.len() as u32;
self.free_vec.push_back(slot_idx as u32);
self.free_head = slot_idx as u32;
value_idx
}
fn remove_from_slot(&mut self, slot_idx: usize) -> V {
let value_idx = self.free_slot(slot_idx);
let _ = self.keys.swap_remove(value_idx as usize);
let value = self.values.swap_remove(value_idx as usize);
if let Some(k) = self.keys.get(value_idx as usize) {
self.slots[k.data().index() as usize].idx = value_idx;
}
value
}
pub fn remove(&mut self, key: K) -> Option<V> {
self.verify_flushed();
let kd = key.data();
if self.contains_key(kd.into()) {
Some(self.remove_from_slot(kd.index() as usize))
} else {
None
}
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(K, &mut V) -> bool,
{
let mut i = 0;
while i < self.keys.len() {
let (should_keep, slot_idx) = {
let (kd, mut value) = (self.keys[i].data(), &mut self.values[i]);
(f(kd.into(), &mut value), kd.index() as usize)
};
if should_keep {
i += 1;
} else {
self.remove_from_slot(slot_idx);
}
}
}
pub fn clear(&mut self) {
self.drain();
}
pub fn drain(&mut self) -> Drain<K, V> {
Drain { sm: self }
}
pub fn get(&self, key: K) -> Option<&V> {
let kd = key.data();
self.slots
.get(kd.index() as usize)
.filter(|slot| slot.version == kd.version())
.map(|slot| unsafe {
let idx = slot.idx as usize;
self.values.get_unchecked(idx)
})
}
pub unsafe fn get_unchecked(&self, key: K) -> &V {
debug_assert!(self.contains_key(key));
let idx = self.slots.get_unchecked(key.data().index() as usize).idx;
&self.values.get_unchecked(idx as usize)
}
pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
let kd = key.data();
self.slots
.get(kd.index() as usize)
.filter(|slot| slot.version == kd.version())
.map(|slot| slot.idx as usize)
.map(move |idx| unsafe {
self.values.get_unchecked_mut(idx)
})
}
pub unsafe fn get_unchecked_mut(&mut self, key: K) -> &mut V {
debug_assert!(self.contains_key(key));
let idx = self.slots.get_unchecked(key.data().index() as usize).idx;
self.values.get_unchecked_mut(idx as usize)
}
#[cfg(has_min_const_generics)]
pub fn get_disjoint_mut<const N: usize>(&mut self, keys: [K; N]) -> Option<[&mut V; N]> {
let mut ptrs: [MaybeUninit<*mut V>; N] = unsafe { MaybeUninit::uninit().assume_init() };
let mut i = 0;
while i < N {
let kd = keys[i].data();
if !self.contains_key(kd.into()) {
break;
}
unsafe {
let slot = self.slots.get_unchecked_mut(kd.index() as usize);
slot.version ^= 1;
let ptr = self.values.get_unchecked_mut(slot.idx as usize);
ptrs[i] = MaybeUninit::new(ptr);
}
i += 1;
}
for k in &keys[..i] {
let idx = k.data().index() as usize;
unsafe {
self.slots.get_unchecked_mut(idx).version ^= 1;
}
}
if i == N {
Some(unsafe { core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs) })
} else {
None
}
}
#[cfg(has_min_const_generics)]
pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(
&mut self,
keys: [K; N],
) -> [&mut V; N] {
let mut ptrs: [MaybeUninit<*mut V>; N] = MaybeUninit::uninit().assume_init();
for i in 0..N {
ptrs[i] = MaybeUninit::new(self.get_unchecked_mut(keys[i]));
}
core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs)
}
pub fn iter(&self) -> Iter<K, V> {
Iter {
inner_keys: self.keys.iter(),
inner_values: self.values.iter(),
}
}
pub fn iter_mut(&mut self) -> IterMut<K, V> {
IterMut {
inner_keys: self.keys.iter(),
inner_values: self.values.iter_mut(),
}
}
pub fn keys(&self) -> Keys<K, V> {
Keys { inner: self.iter() }
}
pub fn values(&self) -> Values<K, V> {
Values { inner: self.iter() }
}
pub fn values_mut(&mut self) -> ValuesMut<K, V> {
ValuesMut {
inner: self.iter_mut(),
}
}
}
impl<K: Key, V> Clone for DelaySlotMap<K, V>
where
V: Clone,
{
fn clone(&self) -> Self {
Self {
keys: self.keys.clone(),
values: self.values.clone(),
slots: self.slots.clone(),
free_vec: self.free_vec.clone(),
alloc_count: AtomicU32::new(self.alloc_count.load(Ordering::Relaxed)),
..*self
}
}
fn clone_from(&mut self, source: &Self) {
self.keys.clone_from(&source.keys);
self.values.clone_from(&source.values);
self.slots.clone_from(&source.slots);
self.free_head = source.free_head;
}
}
impl<K: Key, V> Default for DelaySlotMap<K, V> {
fn default() -> Self {
Self::with_key()
}
}
impl<K: Key, V> Index<K> for DelaySlotMap<K, V> {
type Output = V;
fn index(&self, key: K) -> &V {
match self.get(key) {
Some(r) => r,
None => panic!("invalid DenseSlotMap key used"),
}
}
}
impl<K: Key, V> IndexMut<K> for DelaySlotMap<K, V> {
fn index_mut(&mut self, key: K) -> &mut V {
match self.get_mut(key) {
Some(r) => r,
None => panic!("invalid DenseSlotMap key used"),
}
}
}
#[derive(Debug)]
pub struct Drain<'a, K: 'a + Key, V: 'a> {
sm: &'a mut DelaySlotMap<K, V>,
}
#[derive(Debug, Clone)]
pub struct IntoIter<K, V> {
inner_keys: alloc::vec::IntoIter<K>,
inner_values: alloc::vec::IntoIter<V>,
}
#[derive(Debug)]
pub struct Iter<'a, K: 'a + Key, V: 'a> {
inner_keys: core::slice::Iter<'a, K>,
inner_values: core::slice::Iter<'a, V>,
}
impl<'a, K: 'a + Key, V: 'a> Clone for Iter<'a, K, V> {
fn clone(&self) -> Self {
Iter {
inner_keys: self.inner_keys.clone(),
inner_values: self.inner_values.clone(),
}
}
}
#[derive(Debug)]
pub struct IterMut<'a, K: 'a + Key, V: 'a> {
inner_keys: core::slice::Iter<'a, K>,
inner_values: core::slice::IterMut<'a, V>,
}
#[derive(Debug)]
pub struct Keys<'a, K: 'a + Key, V> {
inner: Iter<'a, K, V>,
}
impl<'a, K: 'a + Key, V: 'a> Clone for Keys<'a, K, V> {
fn clone(&self) -> Self {
Keys {
inner: self.inner.clone(),
}
}
}
#[derive(Debug)]
pub struct Values<'a, K: 'a + Key, V> {
inner: Iter<'a, K, V>,
}
impl<'a, K: 'a + Key, V: 'a> Clone for Values<'a, K, V> {
fn clone(&self) -> Self {
Values {
inner: self.inner.clone(),
}
}
}
#[derive(Debug)]
pub struct ValuesMut<'a, K: 'a + Key, V: 'a> {
inner: IterMut<'a, K, V>,
}
impl<'a, K: Key, V> Iterator for Drain<'a, K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> {
let key = self.sm.keys.pop();
let value = self.sm.values.pop();
if let (Some(k), Some(v)) = (key, value) {
self.sm.free_slot(k.data().index() as usize);
Some((k, v))
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.sm.keys.len();
(len, Some(len))
}
}
impl<'a, K: Key, V> Drop for Drain<'a, K, V> {
fn drop(&mut self) {
self.for_each(|_drop| {});
}
}
impl<K: Key, V> Iterator for IntoIter<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> {
let key = self.inner_keys.next();
let value = self.inner_values.next();
if let (Some(k), Some(v)) = (key, value) {
Some((k, v))
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner_keys.size_hint()
}
}
impl<'a, K: 'a + Key, V> Iterator for Iter<'a, K, V> {
type Item = (K, &'a V);
fn next(&mut self) -> Option<(K, &'a V)> {
let key = self.inner_keys.next();
let value = self.inner_values.next();
if let (Some(k), Some(v)) = (key, value) {
Some((*k, v))
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner_keys.size_hint()
}
}
impl<'a, K: 'a + Key, V> Iterator for IterMut<'a, K, V> {
type Item = (K, &'a mut V);
fn next(&mut self) -> Option<(K, &'a mut V)> {
let key = self.inner_keys.next();
let value = self.inner_values.next();
if let (Some(k), Some(v)) = (key, value) {
Some((*k, v))
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner_keys.size_hint()
}
}
impl<'a, K: 'a + Key, V> Iterator for Keys<'a, K, V> {
type Item = K;
fn next(&mut self) -> Option<K> {
self.inner.next().map(|(key, _)| key)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<'a, K: 'a + Key, V> Iterator for Values<'a, K, V> {
type Item = &'a V;
fn next(&mut self) -> Option<&'a V> {
self.inner.next().map(|(_, value)| value)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<'a, K: 'a + Key, V> Iterator for ValuesMut<'a, K, V> {
type Item = &'a mut V;
fn next(&mut self) -> Option<&'a mut V> {
self.inner.next().map(|(_, value)| value)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<'a, K: 'a + Key, V> IntoIterator for &'a DelaySlotMap<K, V> {
type Item = (K, &'a V);
type IntoIter = Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, K: 'a + Key, V> IntoIterator for &'a mut DelaySlotMap<K, V> {
type Item = (K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<K: Key, V> IntoIterator for DelaySlotMap<K, V> {
type Item = (K, V);
type IntoIter = IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
inner_keys: self.keys.into_iter(),
inner_values: self.values.into_iter(),
}
}
}
impl<'a, K: 'a + Key, V> FusedIterator for Iter<'a, K, V> {}
impl<'a, K: 'a + Key, V> FusedIterator for IterMut<'a, K, V> {}
impl<'a, K: 'a + Key, V> FusedIterator for Keys<'a, K, V> {}
impl<'a, K: 'a + Key, V> FusedIterator for Values<'a, K, V> {}
impl<'a, K: 'a + Key, V> FusedIterator for ValuesMut<'a, K, V> {}
impl<'a, K: 'a + Key, V> FusedIterator for Drain<'a, K, V> {}
impl<K: Key, V> FusedIterator for IntoIter<K, V> {}
impl<'a, K: 'a + Key, V> ExactSizeIterator for Iter<'a, K, V> {}
impl<'a, K: 'a + Key, V> ExactSizeIterator for IterMut<'a, K, V> {}
impl<'a, K: 'a + Key, V> ExactSizeIterator for Keys<'a, K, V> {}
impl<'a, K: 'a + Key, V> ExactSizeIterator for Values<'a, K, V> {}
impl<'a, K: 'a + Key, V> ExactSizeIterator for ValuesMut<'a, K, V> {}
impl<'a, K: 'a + Key, V> ExactSizeIterator for Drain<'a, K, V> {}
impl<K: Key, V> ExactSizeIterator for IntoIter<K, V> {}
#[cfg(feature = "serde")]
mod serialize {
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use super::*;
#[derive(Serialize, Deserialize)]
struct SerdeSlot<T> {
value: Option<T>,
version: u32,
}
impl<K: Key, V: Serialize> Serialize for DelaySlotMap<K, V> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let serde_slots: Vec<_> = self
.slots
.iter()
.map(|slot| SerdeSlot {
value: if slot.version % 2 == 1 {
self.values.get(slot.idx as usize)
} else {
None
},
version: slot.version,
})
.collect();
serde_slots.serialize(serializer)
}
}
impl<'de, K: Key, V: Deserialize<'de>> Deserialize<'de> for DelaySlotMap<K, V> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let serde_slots: Vec<SerdeSlot<V>> = Deserialize::deserialize(deserializer)?;
if serde_slots.len() >= u32::max_value() as usize {
return Err(de::Error::custom(&"too many slots"));
}
if serde_slots.get(0).map_or(true, |slot| slot.version % 2 == 1) {
return Err(de::Error::custom(&"first slot not empty"));
}
let mut keys = Vec::new();
let mut values = Vec::new();
let mut slots = Vec::new();
slots.push(Slot {
idx: 0,
version: 0,
});
let mut next_free = serde_slots.len();
for (i, serde_slot) in serde_slots.into_iter().enumerate().skip(1) {
let occupied = serde_slot.version % 2 == 1;
if occupied ^ serde_slot.value.is_some() {
return Err(de::Error::custom(&"inconsistent occupation in Slot"));
}
if let Some(value) = serde_slot.value {
let kd = unsafe {key_data(i as u32, serde_slot.version)};
keys.push(kd.into());
values.push(value);
slots.push(Slot {
version: serde_slot.version,
idx: keys.len() as u32 - 1,
});
} else {
slots.push(Slot {
version: serde_slot.version,
idx: next_free as u32,
});
next_free = i;
}
}
Ok(DelaySlotMap {
keys,
values,
slots,
free_head: next_free as u32,
free_vec: VecDeque::new(),
alloc_count:AtomicU32::new(0),
})
}
}
}