#queue #calendar #idea #scheduler #structure #data

calendar_queue

本包实现了“日历队列调度器”数据结构的概念。

1 个不稳定版本

使用旧的 Rust 2015

0.0.1 2015年11月25日

#36#idea

MIT 许可证

15KB
145

日历队列调度器

Build Status Coverage Status

本包实现了“日历队列调度器”数据结构。

日历队列调度器是公平地从多个 mpsc::Receiver 中接收数据的有效方法。这种实现有意识地非常通用、实用和简单。

待办事项:PR 的想法或未来的乐趣

  • 处理溢出(简单的第一个 PR!)
  • 实现各种模拟的伪接口?(读? TcpSocket?)
  • 优化 next() 以适应生产,使其不仅仅重复调用 tick()

可以这样想象

    (The Sorter)              (The flows)
         +
         |
         |
       +-v-+
       |   |
       | ∅ |
       |   |
       +-+-+
         |
+---+  +-+-+
|   |  |   |
| 2 +--+ 3 |
|   |  |   |
+---+  +-+-+        |              |              |
         |          |              |              |
       +-+-+  +-----v-----+  +-----v-----+  +-----v-----+
       |   |  |           |  |           |  |           |
       | 1 |  | Channel 1 |  | Channel 2 |  | Channel 3 |
       |   |  |           |  |           |  |           |
       +-+-+  +-----------+  +-----------+  +-----------+
         |
         |
         v

排序器,在左侧,维护一个与通道匹配的键列表。在日历的每个“tick”时,它可能有一个或多个计划中的通道。使用这种数据结构以这种方式允许进行模拟,因为可以有效地模拟类似路由器的东西。

队列还实现了 Iterator 特性,并可以在代码中按您喜欢的任何方式用作泛型迭代器。队列的迭代器将简单地重复调用 tick,直到完成整个“周期”,并且(仍然公平地)给了每个通道发送的机会,(然后)迭代器最终耗尽。

示例

use calendar_queue::CalendarQueue;

// `id`s and `value`s are generic. Think of this as a hashmap of channels.
let mut queue = CalendarQueue::<u64, String>::new();

// Each `Reciever` is one channel to the queue.
// Here we give our reciever to the queue, with a cycle of 3 ticks.
let (sender_1, receiver_1) = std::sync::mpsc::channel();
queue.add_channel(receiver_1, 1, 3)
    .unwrap();
// We can also just pull one out.
let sender_2 = queue.create_channel(2, 5)
    .unwrap();

// The `Sender`s behave as you might expect.
for _ in 0..3 {
    sender_1.send("Foo".into())
        .unwrap();
}

for _ in 0..5 {
    sender_2.send("Bar".into())
        .unwrap();
}

// The zero-th clock tick has two items!
assert_eq!(queue.tick(), Some("Foo".into()));
assert_eq!(queue.tick(), Some("Bar".into()));
// First tick has none!
assert_eq!(queue.tick(), None);
// Second tick has none either!
assert_eq!(queue.tick(), None);
// The third tick will be "Foo" because of it's cycle time.
assert_eq!(queue.tick(), Some("Foo".into()));
// We can use `.next()` (and other iterator goodies) to fast forward over empty gaps.
// This will tick over 4 and move on to 5.
assert_eq!(queue.next(), Some("Bar".into()));
// Tick 6 now.
assert_eq!(queue.tick(), Some("Foo".into()));

无运行时依赖