//! This library offers a variety of weak hash tables: //! //! - For a hash map where the keys are held by weak pointers and compared by key value, see //! [`WeakKeyHashMap`](struct.WeakKeyHashMap.html). //! //! - For a hash map where the keys are held by weak pointers and compared by pointer, see //! [`PtrWeakKeyHashMap`](struct.PtrWeakKeyHashMap.html). //! //! - For a hash map where the values are held by weak pointers, see //! [`WeakValueHashMap`](struct.WeakValueHashMap.html). //! //! - For a hash map where the keys and values are both held by weak pointers and the keys are //! compared by value, see //! [`WeakWeakHashMap`](struct.WeakWeakHashMap.html). //! //! - For a hash map where the keys and values are both held by weak pointers and the keys are //! compared by pointer, see //! [`PtrWeakWeakHashMap`](struct.PtrWeakWeakHashMap.html). //! //! - For a hash set where the elements are held by weak pointers and compared by element value, see //! [`WeakHashSet`](struct.WeakHashSet.html). //! //! - For a hash set where the elements are held by weak pointers and compared by pointer, see //! [`PtrWeakHashSet`](struct.PtrWeakHashSet.html). //! //! To add support for your own weak pointers, see //! [the traits `WeakElement` and `WeakKey`](traits/). //! //! ## Rust version support //! //! This crate supports Rust version 1.46 and later. //! //! ## Asymptotic complexity //! //! Most operations have documented asymptotic time complexities. When time complexities are //! given in big-*O* notation, the following parameters are used consistently: //! //! - *n*: the *capacity* of the map or set being accessed or constructed //! //! - *m*: the *capacity* of a second map/set involved in a submap/subset operation //! //! - *p*: the length of the probe sequence for the key in question //! //! Note that *p* ∈ *O*(*n*), but we expect it to be *O*(1). //! //! # 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`: use `ahash`’s hasher rather than the `std` hasher //! //! If the `std` feature is disabled (for no_std) then the `ahash` dependency **must** be enabled. //! //! # Examples //! //! Here we create a weak hash table mapping strings to integers. //! Note that after dropping `one`, the key `"one"` is no longer present in the map. //! This is because the map holds the strings as `std::sync::Weak`s. //! //! ``` //! use weak_table::WeakKeyHashMap; //! use std::sync::{Arc, Weak}; //! //! let mut table = , u32>>::new(); //! let one = Arc::::from("one"); //! let two = Arc::::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); //! //! 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>); //! //! 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::::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); //! } //! ``` #![doc(html_root_url = "https://docs.rs/weak-table/0.3.2")] #![cfg_attr(not(feature = "std"), no_std)] use self::compat::*; pub mod traits; pub mod weak_key_hash_map; pub mod ptr_weak_key_hash_map; pub mod weak_value_hash_map; pub mod weak_weak_hash_map; pub mod ptr_weak_weak_hash_map; pub mod weak_hash_set; pub mod ptr_weak_hash_set; mod compat; mod util; mod by_ptr; mod size_policy; #[derive(Copy, Clone, Debug, PartialEq, Eq)] struct HashCode(u64); type FullBucket = (K, V, HashCode); type Bucket = Option>; type TablePtr = Box<[Bucket]>; /// A hash map with weak keys, hashed on key value. /// /// When a weak pointer expires, its mapping is lazily removed. #[derive(Clone)] pub struct WeakKeyHashMap { hash_builder: S, inner: WeakKeyInnerMap, } #[derive(Clone)] struct WeakKeyInnerMap { buckets: TablePtr, len: usize, } /// A hash map with weak keys, hashed on key pointer. /// /// When a weak pointer expires, its mapping is lazily removed. /// /// # Examples /// /// ``` /// use weak_table::PtrWeakKeyHashMap; /// use std::rc::{Rc, Weak}; /// /// type Table = PtrWeakKeyHashMap, usize>; /// /// let mut map = Table::new(); /// let a = Rc::::from("hello"); /// let b = Rc::::from("hello"); /// /// map.insert(a.clone(), 5); /// /// assert_eq!( map.get(&a), Some(&5) ); /// assert_eq!( map.get(&b), None ); /// /// map.insert(b.clone(), 7); /// /// assert_eq!( map.get(&a), Some(&5) ); /// assert_eq!( map.get(&b), Some(&7) ); /// ``` #[derive(Clone)] pub struct PtrWeakKeyHashMap( WeakKeyHashMap, V, S> ); /// A hash map with weak values. /// /// When a weak pointer expires, its mapping is lazily removed. #[derive(Clone)] pub struct WeakValueHashMap { hash_builder: S, inner: WeakValueInnerMap, } #[derive(Clone)] struct WeakValueInnerMap { buckets: TablePtr, len: usize, } /// A hash map with weak keys and weak values, hashed on key value. /// /// When a weak pointer expires, its mapping is lazily removed. #[derive(Clone)] pub struct WeakWeakHashMap { hash_builder: S, inner: WeakWeakInnerMap, } #[derive(Clone)] struct WeakWeakInnerMap { buckets: TablePtr, len: usize, } /// A hash map with weak keys and weak values, hashed on key pointer. /// /// When a weak pointer expires, its mapping is lazily removed. #[derive(Clone)] pub struct PtrWeakWeakHashMap( WeakWeakHashMap, V, S> ); /// A hash set with weak elements, hashed on element value. /// /// When a weak pointer expires, its mapping is lazily removed. #[derive(Clone)] pub struct WeakHashSet(WeakKeyHashMap); /// A hash set with weak elements, hashed on element pointer. /// /// When a weak pointer expires, its mapping is lazily removed. #[derive(Clone)] pub struct PtrWeakHashSet(PtrWeakKeyHashMap);