12个版本

0.3.2 2021年12月1日
0.3.1 2021年11月30日
0.3.0 2020年6月27日
0.2.4 2020年6月27日
0.1.1 2018年3月5日

#282 in 数据结构

Download history 6985/week @ 2024-04-26 7769/week @ 2024-05-03 7823/week @ 2024-05-10 7192/week @ 2024-05-17 5338/week @ 2024-05-24 5853/week @ 2024-05-31 5068/week @ 2024-06-07 7029/week @ 2024-06-14 7390/week @ 2024-06-21 7540/week @ 2024-06-28 7670/week @ 2024-07-05 6726/week @ 2024-07-12 7274/week @ 2024-07-19 9204/week @ 2024-07-26 9850/week @ 2024-08-02 7964/week @ 2024-08-09

35,441 每月下载量
84 软件包中使用 (直接使用 20 个)

MIT 许可证

150KB
3K SLoC

weak-table:Rust的弱哈希映射和集合

Build Status Crates.io License: MIT

该软件包定义了多种弱哈希映射和集合。有关详细信息,请参阅完整的API文档

Rust版本支持

该软件包支持Rust版本1.46及更高版本。

软件包功能

weak-table 是与 std 功能一起构建的,该功能启用依赖于 std 库的功能,默认启用。可选地,可以启用以下依赖项

  • ahash:使用 ahash 的哈希器而不是 std 的哈希器

如果禁用了 std 功能(无std),则必须启用 ahash 依赖项。

示例

在这里,我们创建一个弱哈希映射,并演示它忘记了过期的键的映射

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

在这里,我们使用弱哈希集合实现一个简单的字符串内部化设施

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

依赖项

~160KB