3个版本 (破坏性更新)

0.3.0 2022年3月4日
0.2.0 2020年12月28日
0.1.0 2020年12月3日

#676 in 数据结构

Zlib OR Apache-2.0

545KB
8K SLoC

coca - 固定容量的数据结构

Crates.io Documentation Min. rustc version 1.59.0

不进行分配,仅使用所给内存的数据结构。

[dependencies]
coca = "0.3"

概述

Rust的标准集合库提供了常见通用编程数据结构的有效实现。通过使用标准实现,两个库应该可以在不进行重大数据转换的情况下进行通信。

然而,这些标准实现使用一个分配器来管理自己的内存,默认使用全局堆。这通常很方便,但在某些情况下可能会出现问题,例如在(软)实时应用中,或者在内存受限的嵌入式系统中,其中可能连alloc包都可能不可用。

coca旨在在这样的环境中提供替代品,通过提供在给定后端内存块上操作的数据结构,而不进行自己的分配。它们对存储类型是通用的,可以是以下任何一种

  • InlineStorage:在结构体内部存储内容,不使用间接引用。需要真正的struct容量,即在编译时静态已知的。
  • AllocStorage:在全局分配的内存中存储内容。需要alloc功能标志。
  • SliceStorage:仅适用于类似数组的结构,在任意给定的未初始化内存切片中存储内容。
  • ArenaStoragecoca包括一个区域分配器,并允许使用区域分配的内存作为存储来构建数据结构。

在这个范式下,提供以下类型的直接类似物

此外,coca还包括以下容器类型

  • ListSet,一个作为 Vec 实现的集合。
  • ListMap,一个作为一对并行数组实现的关联列表。
  • CacheTable,一个具有可配置驱逐策略的遗忘哈希表;因其适用于缓存而得名。
  • OptionGroup,一个可选值的元组或数组,其占用标志打包到一个单独的位图字段中。
  • InlineObject,一个静态大小的容器,用于动态大小的类型,主要是特质对象;这需要不稳定的语言特性,因此需要启用 unstable 功能标志。

与其他库的比较

首先,除非你试图避免击中全局分配器,或者在目标环境中没有分配器,否则你几乎肯定可以使用 Rust 的标准集合,或者在使用 coca::collections::pool 的情况下,使用 slotmap crate。然而,在这种场景中,也有几个 crate 填补了类似的空白,比 coca 更加成熟。

coca::arenabumpalo

  • Bumpalo 是一个 no_std crate,但它确实有一个对 alloc crate 的硬依赖,它使用该依赖在存储空间不足时自动将其存储区域添加到其存储区域中。这有助于避免失败的分配,但使得限制内存使用变得更加困难。相比之下,cocaalloc 的依赖是可选的;一个 coca::arena::Arena 总是在空间不足时返回 None(或者根据你的选择恐慌),但可以从任何可变字节切片中构建。
  • Bumpalo 有自己的 Rust 标准的 VecString 分支,使用其 Bump 分配器,并可选择支持仅限夜间构建的 Allocator API 以兼容其他标准集合。在稳定的 Rust 中,coca::arena 支持更广泛的数据结构,但不会从 feature(allocator_api) 的稳定化中受益。
  • 独特的是,coca 的存储区域可以嵌套,允许具有类似堆栈的分配/释放模式。

coca::collectionsheapless

  • heapless 提供了具有静态已知容量的各种数据结构,相当于 cocaInlineStorage。它不支持动态分配。
  • heapless 提供了与 std::collections::HashMapHashSet 直接对应的类似物,而 coca 则没有(尚无)。
  • coca 的所有数据结构都不是线程安全的,而 heapless 提供了多种同步机制:一个无锁的内存池,具有原子引用计数的指针,以及 MPMC 和 SPSC 无锁队列。
  • heapless 不提供与 std::collections::VecDequeslotmap::SlotMapslotmap::DenseSlotMap 的等效功能,而 coca 则提供了,并且还支持更小众的数据结构(如 CacheTableOptionGroupInlineObject)。

coca::collections::vectinyvecarrayvec

  • tinyvec 不使用任何不安全代码,但要求元素类型实现 Default 特性。而 coca 没有这样的限制,并提供与 tinyvec::ArrayVectinyvec::SliceVec 的等效功能,但不包括 tinyvec::TinyVec,这是一个具有重新分配能力的优化小型向量。此外,coca 还需要比 tinyvec 更新的 Rust 版本(至少 1.59),而 tinyvec 的最低版本为 1.34。
  • arrayvec 和 tinyvec 都有可选的 serde 支持,而 coca 则没有。
  • coca::collections::Vec 仅使用一个实现就支持更多的存储模式,这意味着其实例之间的交互更加容易,你可以编写泛型代码来处理所有这些模式。它也针对索引类型进行泛型化,类似于 typed_index_collections crate 提供的功能。

功能标志

  • alloc:默认情况下,coca 与 no_std 兼容;此功能标志启用了一些 trait 实现以便方便地使用堆分配存储。
  • profile:启用在区域中的内存分析;请参阅模块级文档以获取详细信息。
  • unstable:如果您正在使用 nightly Rust 工具链,并且不介意依赖于不稳定的功能,则可以启用此功能以获取对 InlineObject 的访问权限,允许您创建没有间接引用的 trait 对象。

许可

许可协议为 Apache License, Version 2.0 或 Zlib 许可证,由您选择。

除非您明确声明,否则您有意提交以包含在此 crate 中的任何贡献,根据 Apache-2.0 许可证定义,均应按上述方式双许可,而无需任何额外的条款或条件。

无运行时依赖