Android mainline 12.0.0 release 96
[automerger skipped] Mark ab/7061308 as merged in stage. am: 5b9a9cfabc -s ours am: a6ed6b0b06 -s ours am: e62de8e679 -s ours

am skip reason: Change-Id I2846299f6aa23e80ad9befa98ec0ae6b53ba4400 with SHA-1 2f984ae8fe is in history

Original change: undetermined

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ia8b307c3dfbbcd0bda9023c061fb30f80babc6cb
tree: f32d89028ab9efbc8f60d4a24af0f7f26f270740
  1. src/
  2. tests/
  3. .cargo_vcs_info.json
  4. .gitignore
  5. .travis.yml
  6. Android.bp
  7. Cargo.toml
  8. Cargo.toml.orig
  9. CMakeLists.txt
  10. LICENSE
  11. Makefile
  12. METADATA
  13. MODULE_LICENSE_MIT
  14. OWNERS
  15. README.md
  16. release.toml
README.md

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.

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