9 个版本

0.3.5 2024年2月8日
0.3.4 2023年8月2日
0.3.3 2023年3月18日
0.2.1 2022年4月9日
0.1.0 2021年12月15日

#110 in 内存管理

每月下载量 42

MIT/Apache

47KB
963 代码行

Stele

codecov CircleCI docsrs

Stele 是一个单写多读的追加并发数据结构,支持可选的 no_std 和 Allocator API

它是如何工作的?

Stele 实质上是一个指数级增长数组的数组,其中外数组的第 n 个元素包含 2^n 个元素。这是通过将给定的索引分割成两个索引来实现的

  • 外索引是索引的 2 的对数向下取整。这是外数组指针持有请求数据的索引。

  • 内索引是输入索引和外索引之差。这是从外数组指针到索引指向的元素的偏移量。

代价是内存使用,因为数据结构必须持有包含 32 个指针的数组。例如,在 64 位系统上,外数组包含 32 个 8 字节指针,使用 256 字节内存,即使在没有任何分配的情况下。

我该如何使用它?

use std::thread;
use stele::{Stele, ReadHandle, WriteHandle};

fn example() {
    //Writers are only `Send` and not `Sync` to ensure memory safety and avoid races
    let (writer, reader1) = Stele::new();
    //Read handles are clone
    let reader2 = reader1.clone(); 
    //If you don't have any read handles left, you can create a new one from the write handle.
    let reader3 = writer.new_read_handle();
    assert!(writer.is_empty());
    writer.push(42);
    assert_eq!(writer.len(), 1);
    let t1 = thread::spawn(move || {
        // For most types, reads can only return references
        assert_eq!(reader1.read(0), &42)
    });
    let t2 = thread::spawn(move || {
        //Readers also support indexing
        assert_eq!(reader2[0], 42)
    });
    let t3 = thread::spawn(move || {
        //Supports fallible indexing via `try_read`
        assert!(reader3.try_read(1).is_none())
    });
    //`Copy` types can be copied out using `get`
    let copied = writer.get(0);
    assert_eq!(copied, 42);
}

最低支持的 Rust 版本 (MSRV)

  • 没有分配器 API,MSRV 为 1.55

  • 截至 2023-03-12,分配器 API 需要 nightly,并且没有稳定版本。一旦分配器 API 在稳定版中得到支持,这将替换为该稳定版本

依赖关系

~0–26MB
~328K SLoC