#vec-deque #circular-buffer #fixed-size #ring-buffer #queue #zero-allocation

fixed-vec-deque

Rust的一种固定大小、零分配的循环缓冲区

12次发布

使用旧的Rust 2015

0.1.11 2023年3月22日
0.1.10 2023年1月2日
0.1.9 2020年4月23日
0.1.8 2019年7月28日
0.1.5 2018年11月20日

数据结构中排名第188位

Download history 138/week @ 2024-03-11 104/week @ 2024-03-18 81/week @ 2024-03-25 142/week @ 2024-04-01 67/week @ 2024-04-08 102/week @ 2024-04-15 107/week @ 2024-04-22 86/week @ 2024-04-29 150/week @ 2024-05-06 89/week @ 2024-05-13 98/week @ 2024-05-20 84/week @ 2024-05-27 84/week @ 2024-06-03 60/week @ 2024-06-10 95/week @ 2024-06-17 92/week @ 2024-06-24

每月下载量344
3crate中使用(直接使用2个)

MIT/Apache

63KB
954

fixed-vec-deque

github crates.io docs.rs build status

使用固定环形缓冲区实现的双端队列。

此队列从容器两端进行插入和删除的平均时间复杂度为O(1)。它还具有与向量类似的O(1)索引。包含的元素不需要可复制的,如果包含的类型是可发送的,则队列可发送。

FixedVecDeque的大小必须在构造时完全指定,例如

use fixed_vec_deque::FixedVecDeque;

let _ = FixedVecDeque::<[Foo; 4]>::new();

#[derive(Default)]
struct Foo;

修改只能在原地进行,这意味着队列中存储的项目必须始终实现Default

push_backpush_front不接收参数,而是返回一个可变引用,以便新插入的元素在原地修改

use fixed_vec_deque::FixedVecDeque;

let mut buf = FixedVecDeque::<[Foo; 4]>::new();
buf.push_back().data = 42;

#[derive(Default)]
struct Foo {
    data: u32,
}

同样,pop_frontpop_back返回引用而不是移动元素。

这一结果就是这种结构永远不会修改它包含的数据,即使它已经被弹出


缺少的API

一些API缺失。如果您想帮忙,请在问题中留下评论!


我应该什么时候使用FixedVecDeque

通常当以下条件成立时

  • 您需要存储的最大元素数量在短时间内。
  • 在推送时,您只需要从默认值修改元素的一部分。

传统集合要求您每次将其添加到其中时都编写一个“完整”的元素。使用FixedVecDeque,我们可以在原地修改现有元素,并跟踪我们进行了多少此类逻辑“添加”。例如

use fixed_vec_deque::FixedVecDeque;
use std::collections::VecDeque;

pub struct BigStruct {
    fields: [u64; 100],
}

impl Default for BigStruct {
    fn default() -> Self {
        BigStruct {
            fields: [0u64; 100],
        }
    }
}

let mut deq = FixedVecDeque::<[BigStruct; 0x10]>::new();

for i in 0..100 {
    deq.push_back().fields[i] = i as u64;

    let mut count = 0;

    for big in &deq {
        count += 1;
        assert_eq!(big.fields[i], i as u64);
    }

    assert_eq!(count, 1);
    deq.clear();
}

deq.clear();

// Note: modifications are still stored in the ring buffer and will be visible the next time we
// push to it unless we cleared it.
for i in 0..100 {
    assert_eq!(deq.push_back().fields[i], i as u64);
    deq.clear();
}

无运行时依赖

特性