#timestamp #atomic #sequence #increment #event-loop #data-structures

incr

简单的、快速且自包含的数据结构,用于检查新值是否大于之前的最大值

5 个版本

使用旧的 Rust 2015

0.2.1 2023年9月13日
0.2.0 2018年6月14日
0.2.0-rc.12018年4月28日
0.1.1 2018年4月7日
0.1.0 2018年4月6日

#206 in 并发

自定义许可

26KB
318

incr

简单的、快速且自包含的结构体,用于跟踪新观察到的值(u64)是否大于之前观察到的最大值。

使用案例包括消息序列号、时间戳以及其他需要快速评估传入数据是否“新”的情况,即其编号是否大于任何之前的值。

所有结构体都包含一个 is_new 函数,如果传入的值是新最大值,则返回 true,同时将新值存储以供未来值检查。

其中两个 is_new 实现的函数(IncrMap)需要一个 &mut self 签名,而 RcIncrAtomicIncr 由于 RcIncr 的内部可变性以及 AtomicIncr 的线程安全同步,只需要 &self

检查新值的开销极小:单线程实现的 0-2ns,以及 AtomicIncr 的 ~5-10ns,除非在病态竞争的情况下。在最坏情况下,对 AtomicIncr 的噩梦场景基准测试中,可能会引起数百纳秒的延迟。在更现实的 24 个线程竞争递增原子但每次迭代都释放的情况下,检查在 ~5-10ns 范围内。

启用“nightly”功能(默认开启)允许将 AtomicU64 作为 AtomicIncr 的后端存储(与 AtomicUsize 相反)。另外,需要 nightly 才能运行基准测试。

用法

将以下内容添加到您的 Cargo.toml

[dependencies]
incr = "0.2"

示例

简单用法

use incr::Incr;
let mut last = Incr::default();
assert_eq!(last.is_new(1), true);
assert_eq!(last.is_new(1), false);
assert_eq!(last.is_new(2), true);
assert_eq!(last.get(), 2);

AtomicIncr 提供一个线程安全的实现

extern crate incr;

use std::thread::{spawn, JoinHandle};
use std::sync::{Arc, Barrier};
use incr::AtomicIncr;

fn main() {
    let last: AtomicIncr = Default::default();
    let barrier = Arc::new(Barrier::new(2));
    let thread: JoinHandle<u64> = {
        let barrier = Arc::clone(&barrier);
        let last = last.clone();
        spawn(move || {
            assert_eq!(last.is_new(2), true);
            assert_eq!(last.is_new(3), true);
            assert_eq!(last.is_new(3), false);
            barrier.wait();
            last.get()
        })
    };
    barrier.wait();
    assert_eq!(last.is_new(3), false);
    assert_eq!(thread.join().unwrap(), 3);
}

依赖项