Custom VecMap and VecSet collections for cache-friendly linear search
Does HashMap and HashSet already implement these optimizations? Almost certainly...main
parent
397b60b18c
commit
f83b79bda5
@ -0,0 +1,124 @@
|
||||
/// A vec-backed set for cache-friendly queries
|
||||
#[derive(Debug)]
|
||||
pub struct VecSet<T: PartialEq> {
|
||||
inner: Vec<Option<T>>
|
||||
}
|
||||
|
||||
impl<T: PartialEq> VecSet<T> {
|
||||
pub fn insert(&mut self, value: T) {
|
||||
// Check if value already in set, otherwise add it
|
||||
if !self.contains(&value) {
|
||||
self.inner.push(Some(value))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, value: &T) {
|
||||
self.inner.iter_mut().for_each(|val| {
|
||||
if val.as_ref() == Some(value) {
|
||||
*val = None;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compact(&mut self) {
|
||||
self.inner.retain(|val| val.is_some())
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.inner.clear();
|
||||
}
|
||||
|
||||
pub fn contains(&self, value: &T) -> bool {
|
||||
self.iter().any(|v| v == value)
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &T> {
|
||||
self.inner.iter().filter_map(|v| v.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialEq> FromIterator<T> for VecSet<T> {
|
||||
fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self {
|
||||
VecSet::<T> {
|
||||
inner: iter.into_iter().map(|this| Some(this)).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialEq> Default for VecSet<T> {
|
||||
fn default() -> Self {
|
||||
VecSet { inner: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
/// A vec-backed map for cache-friendly queries
|
||||
#[derive(Debug)]
|
||||
pub struct VecMap<K: PartialEq, V> {
|
||||
inner: Vec<Option<(K, V)>>
|
||||
}
|
||||
|
||||
impl<K: PartialEq, V> VecMap<K, V> {
|
||||
pub fn insert(&mut self, key: K, val: V) {
|
||||
// Check and remove/overwrite existing entry
|
||||
if let Some(v) = self.get_mut(&key) {
|
||||
// Update value at key
|
||||
*v = val;
|
||||
} else {
|
||||
self.inner.push(Some((key, val)));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, key: &K) -> Option<&V> {
|
||||
self.iter().find_map(|(k, v)| (k == key).then_some(v))
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
|
||||
self.iter_mut().find_map(|(k, v)| (k == key).then_some(v))
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: &K) {
|
||||
self.get_mut(key).take();
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &(K,V)> {
|
||||
self.inner.iter().filter_map(|kv| kv.as_ref())
|
||||
}
|
||||
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut (K,V)> {
|
||||
self.inner.iter_mut().filter_map(|kv| kv.as_mut())
|
||||
}
|
||||
|
||||
pub fn compact(&mut self) {
|
||||
self.inner.retain(|v| v.is_some());
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.inner.clear();
|
||||
}
|
||||
|
||||
pub fn keys(&self) -> impl Iterator<Item = &K> {
|
||||
self.inner.iter().filter_map(|this| this.as_ref().map(|(k,_)| k))
|
||||
}
|
||||
|
||||
pub fn contains_key(&self, key: &K) -> bool {
|
||||
self.keys().any(|k| k == key)
|
||||
}
|
||||
|
||||
pub fn values(&self) -> impl Iterator<Item = &V> {
|
||||
self.inner.iter().filter_map(|this| this.as_ref().map(|(_,v)| v))
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: PartialEq,V> FromIterator<(K,V)> for VecMap<K,V> {
|
||||
fn from_iter<I: IntoIterator<Item=(K,V)>>(iter: I) -> Self {
|
||||
VecMap::<K,V> {
|
||||
inner: iter.into_iter().map(|this| Some(this)).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: PartialEq, V> Default for VecMap<K, V> {
|
||||
fn default() -> Self {
|
||||
VecMap { inner: Vec::new() }
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue