Bug: 170637881

Clone this repo:
  1. 5b9a9cf Mark ab/7061308 as merged in stage. by Xin Li · 3 months ago main-cg-testing-release master
  2. b5ceed2 [LSC] Add LOCAL_LICENSE_KINDS to external/rust/crates/weak-table am: 52db6ac03e by Bob Badour · 3 months ago
  3. 52db6ac [LSC] Add LOCAL_LICENSE_KINDS to external/rust/crates/weak-table by Bob Badour · 3 months ago android-s-preview-1
  4. 2f984ae Add Android.bp am: f1c1deef6c am: 10d25dade4 am: abb58dc31a by Joel Galenson · 7 months ago
  5. 17bf927 Add metadata files am: ea3cf837a6 am: 7c726fa76d am: 53b54c3b58 by Joel Galenson · 7 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.

This crate supports Rust version 1.32 and later.


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


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 {

#[derive(Debug, Default)]
pub struct SymbolTable(WeakHashSet<Weak<str>>);

impl SymbolTable {
    pub fn new() -> Self {

    pub fn intern(&mut self, name: &str) -> Symbol {
        if let Some(rc) = self.0.get(name) {
        } else {
            let rc = Rc::<str>::from(name);

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