use alloc::vec::{self, Vec};
use core::error::Error;
use core::fmt;
use core::iter;
use core::mem;
use core::ops::{Index, IndexMut};
use core::slice;
use core::str::FromStr;
use self::entry::{Entry, VerEntry};
mod entry;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct TagParseError;
impl Error for TagParseError {}
impl fmt::Display for TagParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("failed to parse tag")
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Tag {
idx: usize,
ver: u64,
}
impl fmt::Debug for Tag {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl fmt::Display for Tag {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}/{}", self.idx, self.ver)
}
}
impl FromStr for Tag {
type Err = TagParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut pieces = s.split('/').fuse();
if let (Some(first), Some(second), None) = (pieces.next(), pieces.next(), pieces.next()) {
if (first.len() > 1 && first.as_bytes()[0] == b'0')
|| (second.len() > 1 && second.as_bytes()[0] == b'0')
{
return Err(TagParseError);
}
if let (Ok(index), Ok(version)) = (first.parse(), second.parse()) {
return Ok(Tag {
idx: index,
ver: version,
});
}
}
Err(TagParseError)
}
}
pub struct Extend<'a, I>
where
I: Iterator,
I::Item: 'a,
{
iter: I,
stash: &'a mut UniqueStash<I::Item>,
}
impl<'a, I> Drop for Extend<'a, I>
where
I: Iterator,
I::Item: 'a,
{
fn drop(&mut self) {
for _ in self {}
}
}
impl<'a, I> Iterator for Extend<'a, I>
where
I: Iterator,
I::Item: 'a,
{
type Item = Tag;
fn next(&mut self) -> Option<Tag> {
self.iter.next().map(|v| self.stash.put(v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, I> ExactSizeIterator for Extend<'a, I>
where
I: ExactSizeIterator,
I::Item: 'a,
{
}
impl<'a, I> DoubleEndedIterator for Extend<'a, I>
where
I: DoubleEndedIterator,
I::Item: 'a,
{
fn next_back(&mut self) -> Option<Tag> {
self.iter.next_back().map(|v| self.stash.put(v))
}
}
pub struct Iter<'a, V: 'a> {
inner: iter::Enumerate<slice::Iter<'a, VerEntry<V>>>,
len: usize,
}
pub struct IterMut<'a, V: 'a> {
inner: iter::Enumerate<slice::IterMut<'a, VerEntry<V>>>,
len: usize,
}
pub struct IntoIter<V> {
inner: iter::Enumerate<vec::IntoIter<VerEntry<V>>>,
len: usize,
}
pub struct Values<'a, V: 'a> {
inner: slice::Iter<'a, VerEntry<V>>,
len: usize,
}
pub struct ValuesMut<'a, V: 'a> {
inner: slice::IterMut<'a, VerEntry<V>>,
len: usize,
}
pub struct IntoValues<V> {
inner: vec::IntoIter<VerEntry<V>>,
len: usize,
}
impl_iter!(Values, (<'a, V>), &'a V, entry::value_ref, ());
impl_iter!(ValuesMut, (<'a, V>), &'a mut V, entry::value_mut, ());
impl_iter!(IntoValues, (<V>), V, entry::value, ());
impl_iter!(Iter, (<'a, V>), (Tag, &'a V), entry::value_index_ref, ());
impl_iter!(IterMut, (<'a, V>), (Tag, &'a mut V), entry::value_index_mut, ());
impl_iter!(IntoIter, (<V>), (Tag, V), entry::value_index, ());
#[derive(Clone)]
pub struct UniqueStash<V> {
data: Vec<VerEntry<V>>,
size: usize,
next_free: usize,
}
impl<V> UniqueStash<V> {
#[inline]
pub const fn new() -> Self {
UniqueStash {
data: Vec::new(),
next_free: 0,
size: 0,
}
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
UniqueStash {
data: Vec::with_capacity(capacity),
next_free: 0,
size: 0,
}
}
#[inline]
pub fn capacity(&self) -> usize {
self.data.capacity()
}
#[inline]
pub fn len(&self) -> usize {
self.size
}
pub fn reserve(&mut self, additional: usize) {
let extra_space = self.data.len() - self.len();
if extra_space < additional {
self.data.reserve(additional - extra_space)
}
}
pub fn reserve_exact(&mut self, additional: usize) {
let extra_space = self.data.len() - self.len();
if extra_space < additional {
self.data.reserve_exact(additional - extra_space)
}
}
pub fn put(&mut self, value: V) -> Tag {
let loc = self.next_free;
debug_assert!(loc <= self.data.len());
let version;
if self.next_free == self.data.len() {
self.data.push(entry::new(value));
version = 0;
self.next_free += 1;
} else {
unsafe {
let entry = self.data.get_unchecked_mut(loc);
version = entry.version;
self.next_free = entry::fill(entry, value);
}
}
self.size += 1;
Tag {
idx: loc,
ver: version,
}
}
#[inline]
pub fn extend<I>(&mut self, iter: I) -> Extend<I>
where
I: Iterator<Item = V>,
{
let (lower, _) = iter.size_hint();
self.reserve(lower);
Extend { iter, stash: self }
}
#[inline]
pub fn iter(&self) -> Iter<V> {
Iter {
len: self.len(),
inner: self.data.iter().enumerate(),
}
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<V> {
IterMut {
len: self.len(),
inner: self.data.iter_mut().enumerate(),
}
}
#[inline]
pub fn values(&self) -> Values<V> {
Values {
len: self.len(),
inner: self.data.iter(),
}
}
#[inline]
pub fn values_mut(&mut self) -> ValuesMut<V> {
ValuesMut {
len: self.len(),
inner: self.data.iter_mut(),
}
}
#[inline]
pub fn into_values(self) -> IntoValues<V> {
IntoValues {
len: self.len(),
inner: self.data.into_iter(),
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.size == 0
}
pub fn take(&mut self, index: Tag) -> Option<V> {
match self.data.get_mut(index.idx) {
Some(VerEntry { version, entry }) if *version == index.ver => {
match mem::replace(entry, Entry::Empty(self.next_free)) {
Entry::Full(value) => {
*version += 1;
self.next_free = index.idx;
self.size -= 1;
Some(value)
}
empty => {
*entry = empty;
None
}
}
}
_ => None,
}
}
pub fn get(&self, index: Tag) -> Option<&V> {
match self.data.get(index.idx) {
Some(VerEntry {
version,
entry: Entry::Full(value),
}) if *version == index.ver => Some(value),
_ => None,
}
}
pub fn get_mut(&mut self, index: Tag) -> Option<&mut V> {
match self.data.get_mut(index.idx) {
Some(VerEntry {
version,
entry: Entry::Full(value),
}) if *version == index.ver => Some(value),
_ => None,
}
}
pub fn clear(&mut self) {
for (i, item) in self.data.iter_mut().enumerate() {
if let Entry::Empty(_) = item.entry {
continue;
}
item.version += 1;
self.next_free = i;
self.size -= 1;
item.entry = Entry::Empty(self.next_free);
}
}
}
impl<V> IntoIterator for UniqueStash<V> {
type Item = (Tag, V);
type IntoIter = IntoIter<V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
IntoIter {
len: self.len(),
inner: self.data.into_iter().enumerate(),
}
}
}
impl<'a, V> IntoIterator for &'a UniqueStash<V> {
type Item = (Tag, &'a V);
type IntoIter = Iter<'a, V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, V> IntoIterator for &'a mut UniqueStash<V> {
type Item = (Tag, &'a mut V);
type IntoIter = IterMut<'a, V>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<V> fmt::Debug for UniqueStash<V>
where
V: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_map().entries(self).finish()
}
}
impl<V> Index<Tag> for UniqueStash<V> {
type Output = V;
#[inline]
fn index(&self, index: Tag) -> &V {
self.get(index).expect("index out of bounds")
}
}
impl<V> IndexMut<Tag> for UniqueStash<V> {
#[inline]
fn index_mut(&mut self, index: Tag) -> &mut V {
self.get_mut(index).expect("index out of bounds")
}
}
impl<V> Default for UniqueStash<V> {
#[inline]
fn default() -> Self {
UniqueStash::new()
}
}
#[cfg(feature = "serialization")]
mod serialization {
use super::*;
use core::marker;
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser::{Serialize, SerializeSeq, Serializer};
impl<V> Serialize for UniqueStash<V>
where
V: Serialize,
{
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut seq = serializer.serialize_seq(Some(self.data.len()))?;
for ve in &self.data {
let option = match &ve.entry {
Entry::Full(v) => Some(v),
Entry::Empty(_) => None,
};
seq.serialize_element(&(ve.version, option))?;
}
seq.end()
}
}
impl<'de, V> Deserialize<'de> for UniqueStash<V>
where
V: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(StashVisitor::new())
}
}
struct StashVisitor<V> {
_marker: marker::PhantomData<fn(V) -> V>,
}
impl<V> StashVisitor<V> {
fn new() -> StashVisitor<V> {
StashVisitor {
_marker: marker::PhantomData,
}
}
}
impl<'de, V> Visitor<'de> for StashVisitor<V>
where
V: Deserialize<'de>,
{
type Value = UniqueStash<V>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a sequence of optional values and versions")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let initial_size = seq.size_hint().unwrap_or(8);
let mut data = Vec::with_capacity(initial_size);
let mut i = 0;
let mut next_free = 0;
let mut size = 0;
let mut first_free = None;
while let Some((version, option)) = seq.next_element()? {
match option {
Some(v) => {
data.push(VerEntry {
entry: Entry::Full(v),
version,
});
size += 1;
}
None => {
if first_free.is_none() {
first_free = Some(i);
}
data.push(VerEntry {
entry: Entry::Empty(next_free),
version,
});
next_free = i;
}
}
i += 1;
}
let opt = first_free.and_then(|e| data.get_mut(e));
if let Some(VerEntry {
entry: Entry::Empty(next),
..
}) = opt
{
*next = i;
} else {
next_free = i;
}
Ok(UniqueStash {
data,
next_free,
size,
})
}
}
}