#map #vec #ordered #multimap

废弃 total-order-multi-map

同时保持所有元素的总插入顺序的多值映射

7 个版本

使用旧的 Rust 2015

0.4.6 2019年10月11日
0.4.5 2018年9月7日
0.4.2 2018年8月27日
0.3.0 2018年6月12日

#13 in #multimap

Download history 36/week @ 2024-03-11 32/week @ 2024-03-18 30/week @ 2024-03-25 71/week @ 2024-04-01 19/week @ 2024-04-08 36/week @ 2024-04-15 42/week @ 2024-04-22 23/week @ 2024-04-29 39/week @ 2024-05-06 31/week @ 2024-05-13 28/week @ 2024-05-20 52/week @ 2024-05-27 45/week @ 2024-06-03 70/week @ 2024-06-10 63/week @ 2024-06-17 30/week @ 2024-06-24

211 每月下载量
用于 9 个 crate (2 直接)

MIT/Apache

66KB
1.5K SLoC

total-order-multi-map Crates.io total-order-multi-map License License

这是一个多值映射,它同时保持所有元素的总插入顺序,这意味着如果您插入以下键值对: (K1, V1)(K2, V2)(K1, V3),它将记住插入顺序确实是这样的(V1V2V3)即它不会在每个键的基础上折叠插入顺序。

同时,它应该有与正常 HashMap 相似的数据访问性能(否则我们只需创建一个 Vec)。

它是通过限制其值仅限于实现 StableDeref 的值来实现的,例如通过 Box<TraitObject>,它可以通过它有多个对值的指针。虽然它在内部使用不安全性,但提供的接口是安全的。它还确保是 unwind + resume 安全的。

示例

extern crate total_order_multi_map as tomm;

use std::fmt::{self, Display};
use tomm::TotalOrderMultiMap;

/// for now the key has to be copy
type Key = &'static str;

/// the map is made for thinks which dereference
/// e.g. trait objects, through e.g. `String` or
/// `Rc<Debug>` would be fine, too.
type Value = Box<Display>;


fn main() {
    let mut map = TotalOrderMultiMap::<Key, Value>::new();

    map.add("key1", mk_box_str("val1"));
    map.add("key1", mk_my_thingy("val2"));
    map.add("key2", mk_box_str("val3"));
    map.add("key1", mk_my_thingy("val4"));
    map.add("key0", mk_box_str("val5"));

    let stringed = map
        .iter()
        // val is of type `&Display`
        .map(|(key, val)| format!("{}:{}", key, val))
        .collect::<Vec<_>>();

    // as it can be seen the total insertion order was kept
    assert_eq!(stringed, &[
        "key1:val1".to_owned(),
        "key1:val2".to_owned(),
        "key2:val3".to_owned(),
        "key1:val4".to_owned(),
        "key0:val5".to_owned()
    ]);

    // It's also still a multi map.
    // Note that the get operation has roughly the same
    // performance as in a hash map (through you then
    // iterate over the elements associated with the key
    // roughly with the speed of iterating over an `Vec`).
    {
        let values = map.get("key1").expect("key1 is in the map");
        let stringed = values
            .map(|val| format!("{}", val))
            .collect::<Vec<_>>();

        assert_eq!(stringed, &[ "val1", "val2", "val4" ]);
    }

    // but as we have an order we can remove
    // "the last inserted" element
    let (key, val) = map.pop().unwrap();
    assert_eq!(format!("{}:{}", key, val), "key0:val5");

    // or remove all for an specific key as it's
    // an multi map
    map.remove_all("key1");
    assert!(map.get("key1").is_none());

    println!("DONE (I only contain asserts)")
}

//---- some function to create dummy values for the example ----

fn mk_box_str(inp: &str) -> Box<Display> {
    // sadly we can't cast Box<str> to Box<Display>
    // (you would need non static vtables for this...)
    Box::new(inp.to_owned())
}

#[derive(Debug)]
struct MyThingy { val: String }

impl Display for MyThingy {
    fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
        write!(fter, "{}", self.val)
    }
}

fn mk_my_thingy(inp: &str) -> Box<Display> {
    Box::new(MyThingy { val: inp.to_owned() })
}

缺少的部分

以下内容可以实施并应添加到后续版本中

  • 基准测试
  • 使用 SmallVec 为多值映射
  • 允许对 &mut 访问 V::Target,如果 V: StableDeref + DerefMut
  • 索引访问
    • 索引获取键值对
    • 索引删除
    • get 的返回值中索引获取 in,即多映射组
  • 改进的条目 API
    • 允许访问具有相同键的其他值
    • 可能将条目 + 插入的结果转换为 get + unwrap 的结果
  • 改进的分组迭代,也许吧?
    • 当前实现按键分组,但未指示何时切换到下一个值
  • 允许非复制键?
    • 我们仍然不想复制/克隆键,所以我们必须在那里做一些小诡计

许可证

根据您选择的

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义,您有意提交的任何贡献,包括在您的工作中的包含,都将根据上述方式双重许可,不附加任何其他条款或条件。

更改日志

  • v0.3:
    • TotalOrderMultiMap.retain 现在接受一个接受 &V::Target 的谓词,而不是 &V
  • v0.4.1:
    • 将返回值扁平化到 get,以返回空迭代器而不是 None
    • 需要 DerefMut 而不是只是 Deref
    • 有可变访问方法,如 get_mut
    • insert 分割为 addset,其中 set 替换与键相关联的任何旧值,并返回旧值
  • v0.4.2:
    • 从可变迭代器到非可变迭代器的转换
      • 从 IterMut 迭代
      • 从 ValuesMut 获取值
      • 从 EntryValuesMut 获取 EntryValues
  • v0.4.3:
    • 添加了缺少的重新导出。Values,Values,GroupedValuesMut 现在是公共的,正如它们一开始就应该那样。
  • v0.4.4:
    • 添加了 truncate 方法,允许删除在第一个 size 元素之后插入的任何内容
  • v0.4.5:
    • 对于添加的条目 valuesvalues_mut 方法可以遍历与用于创建条目的键关联的值。

依赖关系

~26KB