diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index f7593501959c7..d6e9c479c9b8d 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -73,6 +73,7 @@ pub mod box_region; pub mod const_cstr; pub mod flock; pub mod fx; +pub mod stable_map; pub mod graph; pub mod indexed_vec; pub mod jobserver; @@ -84,6 +85,7 @@ pub mod small_c_str; pub mod snapshot_map; pub use ena::snapshot_vec; pub mod sorted_map; +pub mod stable_set; #[macro_use] pub mod stable_hasher; pub mod sync; pub mod sharded; diff --git a/src/librustc_data_structures/stable_map.rs b/src/librustc_data_structures/stable_map.rs new file mode 100644 index 0000000000000..f69f28e14b2a1 --- /dev/null +++ b/src/librustc_data_structures/stable_map.rs @@ -0,0 +1,99 @@ +pub use rustc_hash::FxHashMap; +use std::borrow::Borrow; +use std::collections::hash_map::Entry; +use std::fmt; +use std::hash::Hash; + +/// A deterministic wrapper around FxHashMap that does not provide iteration support. +/// +/// It supports insert, remove, get and get_mut functions from FxHashMap. +/// It also allows to convert hashmap to a sorted vector with the method `into_sorted_vector()`. +#[derive(Clone)] +pub struct StableMap<K, V> { + base: FxHashMap<K, V>, +} + +impl<K, V> Default for StableMap<K, V> +where + K: Eq + Hash, +{ + fn default() -> StableMap<K, V> { + StableMap::new() + } +} + +impl<K, V> fmt::Debug for StableMap<K, V> +where + K: Eq + Hash + fmt::Debug, + V: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.base) + } +} + +impl<K, V> PartialEq for StableMap<K, V> +where + K: Eq + Hash, + V: PartialEq, +{ + fn eq(&self, other: &StableMap<K, V>) -> bool { + self.base == other.base + } +} + +impl<K, V> Eq for StableMap<K, V> +where + K: Eq + Hash, + V: Eq, +{} + +impl<K, V> StableMap<K, V> +where + K: Eq + Hash, +{ + pub fn new() -> StableMap<K, V> { + StableMap { base: FxHashMap::default() } + } + + pub fn into_sorted_vector(self) -> Vec<(K, V)> + where + K: Ord + Copy, + { + let mut vector = self.base.into_iter().collect::<Vec<_>>(); + vector.sort_unstable_by_key(|pair| pair.0); + vector + } + + pub fn entry(&mut self, k: K) -> Entry<'_, K, V> { + self.base.entry(k) + } + + pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> + where + K: Borrow<Q>, + Q: Hash + Eq, + { + self.base.get(k) + } + + pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> + where + K: Borrow<Q>, + Q: Hash + Eq, + { + self.base.get_mut(k) + } + + pub fn insert(&mut self, k: K, v: V) -> Option<V> { + self.base.insert(k, v) + } + + pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V> + where + K: Borrow<Q>, + Q: Hash + Eq, + { + self.base.remove(k) + } +} diff --git a/src/librustc_data_structures/stable_set.rs b/src/librustc_data_structures/stable_set.rs new file mode 100644 index 0000000000000..c7ca74f5fbd9d --- /dev/null +++ b/src/librustc_data_structures/stable_set.rs @@ -0,0 +1,77 @@ +pub use rustc_hash::FxHashSet; +use std::borrow::Borrow; +use std::fmt; +use std::hash::Hash; + +/// A deterministic wrapper around FxHashSet that does not provide iteration support. +/// +/// It supports insert, remove, get functions from FxHashSet. +/// It also allows to convert hashset to a sorted vector with the method `into_sorted_vector()`. +#[derive(Clone)] +pub struct StableSet<T> { + base: FxHashSet<T>, +} + +impl<T> Default for StableSet<T> +where + T: Eq + Hash, +{ + fn default() -> StableSet<T> { + StableSet::new() + } +} + +impl<T> fmt::Debug for StableSet<T> +where + T: Eq + Hash + fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.base) + } +} + +impl<T> PartialEq<StableSet<T>> for StableSet<T> +where + T: Eq + Hash, +{ + fn eq(&self, other: &StableSet<T>) -> bool { + self.base == other.base + } +} + +impl<T> Eq for StableSet<T> where T: Eq + Hash {} + +impl<T: Hash + Eq> StableSet<T> { + pub fn new() -> StableSet<T> { + StableSet { base: FxHashSet::default() } + } + + pub fn into_sorted_vector(self) -> Vec<T> + where + T: Ord, + { + let mut vector = self.base.into_iter().collect::<Vec<_>>(); + vector.sort_unstable(); + vector + } + + pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T> + where + T: Borrow<Q>, + Q: Hash + Eq, + { + self.base.get(value) + } + + pub fn insert(&mut self, value: T) -> bool { + self.base.insert(value) + } + + pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool + where + T: Borrow<Q>, + Q: Hash + Eq, + { + self.base.remove(value) + } +}