diff options
| author | Valerii Lashmanov <vflashm@gmail.com> | 2020-09-23 23:32:11 -0500 |
|---|---|---|
| committer | Valerii Lashmanov <vflashm@gmail.com> | 2020-09-26 14:30:05 -0500 |
| commit | 5c224a484dc6ba2a70c9cd0d73a04849f6d7aa68 (patch) | |
| tree | 16919ad7dbdbb6ba195ac59da944d37d93bb6c18 /compiler/rustc_data_structures/src/sso | |
| parent | 6f9a8a7f9b9732c55511d2a2a3914e8feafc7c52 (diff) | |
MiniSet/MiniMap moved and renamed into SsoHashSet/SsoHashMap
It is a more descriptive name and with upcoming changes there will be nothing "mini" about them.
Diffstat (limited to 'compiler/rustc_data_structures/src/sso')
| -rw-r--r-- | compiler/rustc_data_structures/src/sso/map.rs | 61 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sso/mod.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_data_structures/src/sso/set.rs | 41 |
3 files changed, 107 insertions, 0 deletions
diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs new file mode 100644 index 00000000000..c253e9d6616 --- /dev/null +++ b/compiler/rustc_data_structures/src/sso/map.rs @@ -0,0 +1,61 @@ +use crate::fx::FxHashMap; +use arrayvec::ArrayVec; + +use std::hash::Hash; + +/// Small-storage-optimized implementation of a map +/// made specifically for caching results. +/// +/// Stores elements in a small array up to a certain length +/// and switches to `HashMap` when that length is exceeded. +pub enum SsoHashMap<K, V> { + Array(ArrayVec<[(K, V); 8]>), + Map(FxHashMap<K, V>), +} + +impl<K: Eq + Hash, V> SsoHashMap<K, V> { + /// Creates an empty `SsoHashMap`. + pub fn new() -> Self { + SsoHashMap::Array(ArrayVec::new()) + } + + /// Inserts or updates value in the map. + pub fn insert(&mut self, key: K, value: V) { + match self { + SsoHashMap::Array(array) => { + for pair in array.iter_mut() { + if pair.0 == key { + pair.1 = value; + return; + } + } + if let Err(error) = array.try_push((key, value)) { + let mut map: FxHashMap<K, V> = array.drain(..).collect(); + let (key, value) = error.element(); + map.insert(key, value); + *self = SsoHashMap::Map(map); + } + } + SsoHashMap::Map(map) => { + map.insert(key, value); + } + } + } + + /// Return value by key if any. + pub fn get(&self, key: &K) -> Option<&V> { + match self { + SsoHashMap::Array(array) => { + for pair in array { + if pair.0 == *key { + return Some(&pair.1); + } + } + return None; + } + SsoHashMap::Map(map) => { + return map.get(key); + } + } + } +} diff --git a/compiler/rustc_data_structures/src/sso/mod.rs b/compiler/rustc_data_structures/src/sso/mod.rs new file mode 100644 index 00000000000..ef634b9adce --- /dev/null +++ b/compiler/rustc_data_structures/src/sso/mod.rs @@ -0,0 +1,5 @@ +mod map; +mod set; + +pub use map::SsoHashMap; +pub use set::SsoHashSet; diff --git a/compiler/rustc_data_structures/src/sso/set.rs b/compiler/rustc_data_structures/src/sso/set.rs new file mode 100644 index 00000000000..b403c9dcc33 --- /dev/null +++ b/compiler/rustc_data_structures/src/sso/set.rs @@ -0,0 +1,41 @@ +use crate::fx::FxHashSet; +use arrayvec::ArrayVec; +use std::hash::Hash; +/// Small-storage-optimized implementation of a set. +/// +/// Stores elements in a small array up to a certain length +/// and switches to `HashSet` when that length is exceeded. +pub enum SsoHashSet<T> { + Array(ArrayVec<[T; 8]>), + Set(FxHashSet<T>), +} + +impl<T: Eq + Hash> SsoHashSet<T> { + /// Creates an empty `SsoHashSet`. + pub fn new() -> Self { + SsoHashSet::Array(ArrayVec::new()) + } + + /// Adds a value to the set. + /// + /// If the set did not have this value present, true is returned. + /// + /// If the set did have this value present, false is returned. + pub fn insert(&mut self, elem: T) -> bool { + match self { + SsoHashSet::Array(array) => { + if array.iter().any(|e| *e == elem) { + false + } else { + if let Err(error) = array.try_push(elem) { + let mut set: FxHashSet<T> = array.drain(..).collect(); + set.insert(error.element()); + *self = SsoHashSet::Set(set); + } + true + } + } + SsoHashSet::Set(set) => set.insert(elem), + } + } +} |
