12 releases
0.3.2 | Dec 1, 2021 |
---|---|
0.3.1 | Nov 30, 2021 |
0.3.0 | Jun 27, 2020 |
0.2.4 | Jun 27, 2020 |
0.1.1 | Mar 5, 2018 |
#438 in Data structures
35,199 downloads per month
Used in 110 crates
(20 directly)
150KB
3K
SLoC
weak-table: weak hash maps and sets for Rust
This crate defines several kinds of weak hash maps and sets. See the full API documentation for details.
Rust version support
This crate supports Rust version 1.46 and later.
Crate features
weak-table
is built with the std
feature, which enables
functionality dependent on the std
library, enabled by default.
Optionally, the following dependency may be enabled:
ahash
: useahash
’s hasher rather than thestd
hasher
If the std
feature is disabled (for no_std) then the ahash
dependency must be enabled.
Examples
Here we create a weak hash map and demonstrate that it forgets mappings whose keys expire:
use weak_table::WeakKeyHashMap;
use std::sync::{Arc, Weak};
let mut table = <WeakKeyHashMap<Weak<str>, u32>>::new();
let one = Arc::<str>::from("one");
let two = Arc::<str>::from("two");
table.insert(one.clone(), 1);
assert_eq!( table.get("one"), Some(&1) );
assert_eq!( table.get("two"), None );
table.insert(two.clone(), 2);
*table.get_mut(&one).unwrap() += 10;
assert_eq!( table.get("one"), Some(&11) );
assert_eq!( table.get("two"), Some(&2) );
drop(one);
assert_eq!( table.get("one"), None );
assert_eq!( table.get("two"), Some(&2) );
Here we use a weak hash set to implement a simple string interning facility:
use weak_table::WeakHashSet;
use std::ops::Deref;
use std::rc::{Rc, Weak};
#[derive(Clone, Debug)]
pub struct Symbol(Rc<str>);
impl PartialEq for Symbol {
fn eq(&self, other: &Symbol) -> bool {
Rc::ptr_eq(&self.0, &other.0)
}
}
impl Eq for Symbol {}
impl Deref for Symbol {
type Target = str;
fn deref(&self) -> &str {
&self.0
}
}
#[derive(Debug, Default)]
pub struct SymbolTable(WeakHashSet<Weak<str>>);
impl SymbolTable {
pub fn new() -> Self {
Self::default()
}
pub fn intern(&mut self, name: &str) -> Symbol {
if let Some(rc) = self.0.get(name) {
Symbol(rc)
} else {
let rc = Rc::<str>::from(name);
self.0.insert(Rc::clone(&rc));
Symbol(rc)
}
}
}
#[test]
fn interning() {
let mut tab = SymbolTable::new();
let a0 = tab.intern("a");
let a1 = tab.intern("a");
let b = tab.intern("b");
assert_eq!(a0, a1);
assert_ne!(a0, b);
}
Dependencies
~160KB