#队列 #数字 #固定 #统计 #容量 #项目 #保持

sum-queue

通过时间而非容量来保持固定数量项目的时间队列,并允许获取其内容的汇总统计信息

3个版本 (1个稳定版)

1.0.0 2021年7月7日
0.2.0 2021年4月20日
0.1.0 2020年7月10日

#1226 in 数据结构

LGPL-3.0

28KB
307

sum-queue

SumQueue 是一个 Rust 队列类型,通过时间而非容量来保持固定数量的项目,类似于缓存,但实现更简单、更快速。它还允许在任意时间获取其上值的汇总统计信息。

示例

use std::time::Duration;
use std::thread;
use sum_queue::SumQueue;

// creates a queue where elements expire after 2 seconds
let mut queue: SumQueue<i32> = SumQueue::new(Duration::from_secs(2));
queue.push(1);
queue.push(10);
queue.push(3);

// Check the peek without removing the element
assert_eq!(queue.peek(), Some(&1));
// elements are removed in the same order were pushed
assert_eq!(queue.pop(), Some(1));
assert_eq!(queue.pop(), Some(10));
assert_eq!(queue.pop(), Some(3));
assert_eq!(queue.pop(), None);

// Lets puts elements again
queue.push(1);
queue.push(5);
queue.push(2);
// Elements can be iterated as many times as you want
println!("heap data: {:?}", queue.iter().collect::<Vec<_>>());  // [1, 5, 2]

// Check stats
let stats = queue.stats();
println!("Stats - min value in queue: {}", stats.min.unwrap());         // 1
println!("Stats - max value in queue: {}", stats.max.unwrap());         // 5
println!("Stats - sum all values in queue: {}", stats.sum.unwrap());    // 8
println!("Stats - length of queue: {}", stats.len);                     // 3

assert_eq!(queue.pop(), Some(1));
assert_eq!(queue.iter().collect::<Vec<_>>(), vec![&5, &2]);
println!("Elements after pop: {:?}", queue.iter().collect::<Vec<_>>()); // [5, 2]

// After a second the elements are still the same
thread::sleep(Duration::from_secs(1));
println!("Same after 1 sec: {:?}", queue.iter().collect::<Vec<_>>());   // [5, 2]

queue.push(50); // Add an element 1 second younger than the rest of elements
println!("Same elements + 50: {:?}", queue.iter().collect::<Vec<_>>()); // [5, 2, 50]

// Now let sleep 1 sec so the first elements expire
thread::sleep(Duration::from_secs(1));
println!("Just 50: {:?}", queue.iter().collect::<Vec<_>>());            // [50]

// 1 second more later the last element also expires
thread::sleep(Duration::from_secs(1));
println!("No elements: {:?}", queue.iter().collect::<Vec<_>>());        // []

实现

底层使用 BinaryHeap 结构来保持值,并实现了相同的方法:push()pop()peek() 等。尽管值得注意的是,SumQueue 类型的实现会捕获 self 引用的可变所有权(例如,peek(&mut self) -> Option<&T>)。这是因为队列中过期元素的清理会在每次调用读取或写入值的方法时发生,包括调用 len() 方法。

只要您只管理一个SumQueue实例,就不会存在内存分配过大的风险,因为当您使用push()方法推送元素,或者调用任何其他方法来读取队列时,您会注意移除和释放过期的元素,但如果您使用多个实例,向某些队列推送过多元素而未访问其他队列,由于您没有访问这些队列来推送、弹出或获取其状态,内存使用量可能会随着未释放的过期元素而增长。在这种情况下,您至少可以尝试频繁调用len()方法来强制未使用的队列移除和释放过期元素。

关于

来源: https://github.com/mrsarm/rust-sum-queue

作者: (2020-2021) Mariano Ruiz [email protected]

文档: https://docs.rs/sum-queue/

许可证: LGPL-3

无运行时依赖