Bug: 170637881

Clone this repo:
  1. 98e4076 Update weak-table to 0.3.2 am: 77e4bb9dcd am: 0a3ad2af3d am: 3f9b4dcddd by David LeGare · 6 months ago android13-dev master
  2. 3f9b4dc Update weak-table to 0.3.2 am: 77e4bb9dcd am: 0a3ad2af3d by David LeGare · 6 months ago
  3. 0a3ad2a Update weak-table to 0.3.2 am: 77e4bb9dcd by David LeGare · 6 months ago
  4. 77e4bb9 Update weak-table to 0.3.2 by David LeGare · 6 months ago
  5. 0386b92 Refresh Android.bp, cargo2android.json, TEST_MAPPING. am: 93d924b9ba am: 35a2c1fdb5 am: 43c54412d2 am: 36edcf7680 by Joel Galenson · 8 months ago

weak-table: weak hash maps and sets for Rust

Build Status Crates.io License: MIT

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: 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 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);
}