diff --git a/src/secondary.rs b/src/secondary.rs index f6f6f65..2f2b0de 100644 --- a/src/secondary.rs +++ b/src/secondary.rs @@ -1,13 +1,14 @@ -//! TODO +//! Trait definition for secondary maps from keys to values with default elements. -use std::iter::FusedIterator; +use std::collections::HashSet; +use std::{hash::Hash, iter::FusedIterator}; use bitvec::{ slice::{BitSlice, IterOnes}, vec::BitVec, }; -/// A map from keys to values that does not manage it's indices. +/// A map from keys to values with default elements. /// /// Querying a key that has not been set returns a default value. pub trait SecondaryMap { @@ -31,9 +32,6 @@ pub trait SecondaryMap { /// Increases the capacity of the secondary map to `capacity`. fn ensure_capacity(&mut self, capacity: usize); - /// Resizes the secondary map to `new_len`. - fn resize(&mut self, new_len: usize); - /// Returns the maximum index the secondary map can contain without allocating. fn capacity(&self) -> usize; @@ -62,10 +60,26 @@ pub trait SecondaryMap { /// /// [`PortGraph::set_num_ports`]: crate::portgraph::PortGraph::set_num_ports /// [`PortGraph::compact_nodes`]: crate::portgraph::PortGraph::compact_nodes - fn rekey(&mut self, old: K, new: Option); + #[inline] + fn rekey(&mut self, old: K, new: Option) { + let val = self.take(old); + if let Some(key) = new { + self.set(key, val); + } + } /// Swaps the values of two keys. - fn swap(&mut self, key0: K, key1: K); + #[inline] + fn swap(&mut self, key0: K, key1: K) + where + K: Clone, + V: Clone, + { + let val0 = self.get(key0.clone()).clone(); + let val1 = self.get(key1.clone()).clone(); + self.set(key0, val1); + self.set(key1, val0); + } /// Returns an iterator over the non-default entries of the secondary map. fn iter<'a>(&'a self) -> Self::Iter<'a> @@ -100,11 +114,6 @@ where BitVec::reserve(self, capacity.saturating_sub(self.capacity())); } - #[inline] - fn resize(&mut self, new_len: usize) { - BitVec::resize(self, new_len, false) - } - #[inline] fn capacity(&self) -> usize { BitVec::capacity(self) @@ -228,4 +237,99 @@ where impl<'a, K> FusedIterator for BitVecIter<'a, K> where K: TryFrom {} -// TODO: Implementations for HashSet, BTreeSet, HashMap, BTreeMap. +impl SecondaryMap for HashSet +where + K: Hash + Eq + Clone, +{ + type Iter<'a> = HashSetIter<'a, K> where Self: 'a, K: 'a; + + #[inline] + fn new() -> Self { + HashSet::new() + } + + #[inline] + fn with_capacity(capacity: usize) -> Self { + HashSet::with_capacity(capacity) + } + + #[inline] + fn default_value(&self) -> bool { + false + } + + #[inline] + fn ensure_capacity(&mut self, capacity: usize) { + HashSet::reserve(self, capacity.saturating_sub(self.capacity())); + } + + #[inline] + fn capacity(&self) -> usize { + HashSet::capacity(self) + } + + #[inline] + fn get(&self, key: K) -> &bool { + if HashSet::contains(self, &key) { + &true + } else { + &false + } + } + + #[inline] + fn set(&mut self, key: K, val: bool) { + match val { + true => HashSet::insert(self, key), + false => HashSet::remove(self, &key), + }; + } + + #[inline] + fn take(&mut self, key: K) -> bool { + HashSet::take(self, &key).is_some() + } + + #[inline] + fn iter<'a>(&'a self) -> Self::Iter<'a> + where + K: 'a, + { + HashSetIter { + iter: HashSet::iter(self), + } + } +} + +/// Iterator over non-default entries of a bit vector secondary map. +#[derive(Debug, Clone)] +pub struct HashSetIter<'a, K> { + iter: std::collections::hash_set::Iter<'a, K>, +} + +impl<'a, K> Iterator for HashSetIter<'a, K> +where + K: Clone, +{ + type Item = (K, &'a bool); + + #[inline] + fn next(&mut self) -> Option { + self.iter.next().map(|k| (k.clone(), &true)) + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + self.iter.nth(n).map(|k| (k.clone(), &true)) + } + + #[inline] + fn count(self) -> usize { + self.iter.count() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} diff --git a/src/unmanaged.rs b/src/unmanaged.rs index 4065800..419bb07 100644 --- a/src/unmanaged.rs +++ b/src/unmanaged.rs @@ -47,7 +47,6 @@ //! ``` use std::{ - cmp::Ordering, iter::{Enumerate, FusedIterator}, marker::PhantomData, mem::{self, MaybeUninit}, @@ -340,15 +339,6 @@ where UnmanagedDenseMap::ensure_capacity(self, capacity) } - #[inline] - fn resize(&mut self, new_len: usize) { - match self.data.len().cmp(&new_len) { - Ordering::Less => self.ensure_capacity(new_len), - Ordering::Greater => self.shrink_to(new_len), - _ => {} - } - } - #[inline] fn capacity(&self) -> usize { UnmanagedDenseMap::capacity(self)