use std::collections::HashMap;
use std::hash::Hash;
#[derive(Clone, Debug)]
pub(crate) struct Ordered<K, V> {
entries: Vec<Option<(K, V)>>,
index: HashMap<K, usize>,
}
impl<K, V> Default for Ordered<K, V> {
fn default() -> Self {
Ordered {
entries: Vec::new(),
index: HashMap::new(),
}
}
}
impl<K: Clone + Eq + Hash, V> Ordered<K, V> {
pub(crate) fn get<Q>(&self, key: &Q) -> Option<&V>
where
K: std::borrow::Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
let &i = self.index.get(key)?;
self.entries[i].as_ref().map(|(_, v)| v)
}
pub(crate) fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
where
K: std::borrow::Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
let &i = self.index.get(key)?;
self.entries[i].as_mut().map(|(_, v)| v)
}
pub(crate) fn has<Q>(&self, key: &Q) -> bool
where
K: std::borrow::Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.index.contains_key(key)
}
pub(crate) fn set(&mut self, key: K, value: V) {
if let Some(&i) = self.index.get(&key) {
if let Some(entry) = self.entries[i].as_mut() {
entry.1 = value;
}
return;
}
self.index.insert(key.clone(), self.entries.len());
self.entries.push(Some((key, value)));
}
pub(crate) fn delete<Q>(&mut self, key: &Q)
where
K: std::borrow::Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
if let Some(i) = self.index.remove(key) {
self.entries[i] = None;
}
}
pub(crate) fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
self.entries.iter().flatten().map(|(k, v)| (k, v))
}
pub(crate) fn values(&self) -> impl Iterator<Item = &V> {
self.iter().map(|(_, v)| v)
}
pub(crate) fn keys(&self) -> impl Iterator<Item = &K> {
self.iter().map(|(k, _)| k)
}
pub(crate) fn into_values(self) -> Vec<V> {
self.entries.into_iter().flatten().map(|(_, v)| v).collect()
}
}