1use std::fmt::Debug;
2use std::time::Duration;
3
4use tracing::{Level, event};
5
6use base::collections::pq::KeyedReversePriorityQueue;
7use base::prelude::*;
8
9#[derive(Debug)]
10pub(crate) struct PollQueue {
11 items: KeyedReversePriorityQueue<SequenceNumber, Duration>,
12}
13
14#[derive(Debug)]
15pub(crate) enum PollQueueUpdateFailure {
16 UnknownSequence(SequenceNumber),
20}
21
22impl PollQueue {
23 pub(crate) fn new() -> PollQueue {
24 PollQueue {
25 items: KeyedReversePriorityQueue::new(),
26 }
27 }
28
29 pub(crate) fn peek(&self) -> Option<(&SequenceNumber, &Duration)> {
30 self.items.peek()
31 }
32
33 pub(crate) fn pop(&mut self) -> Option<(SequenceNumber, Duration)> {
34 self.items.pop()
35 }
36
37 pub(crate) fn push(&mut self, key: SequenceNumber, priority: Duration) -> Option<Duration> {
38 let old_pri = self.items.push(key, priority);
39 if let Some(prev) = old_pri
40 && prev < priority
41 {
42 event!(
43 Level::WARN,
44 "unit {:o} poll time pushed back from {:?} to {:?}",
45 key,
46 prev,
47 priority
48 );
49 }
50 old_pri
51 }
52
53 pub(crate) fn update(
54 &mut self,
55 key: SequenceNumber,
56 priority: Duration,
57 ) -> Result<Duration, PollQueueUpdateFailure> {
58 match self.items.set_priority(&key, priority) {
59 Ok(old_pri) => {
60 if old_pri < priority {
61 event!(
62 Level::WARN,
63 "unit {:o} poll time pushed back from {:?} to {:?}",
64 key,
65 old_pri,
66 priority
67 );
68 }
69 Ok(old_pri)
70 }
71 Err(_) => Err(PollQueueUpdateFailure::UnknownSequence(key)),
72 }
73 }
74
75 #[cfg(test)]
76 pub(crate) fn len(&self) -> usize {
77 self.items.len()
78 }
79
80 #[cfg(test)]
81 pub(crate) fn is_empty(&self) -> bool {
82 self.items.is_empty()
83 }
84}
85
86#[test]
87fn test_pollqueue_empty() {
88 let mut q = PollQueue::new();
89 assert!(q.is_empty());
90 assert_eq!(0, q.len());
91 assert_eq!(q.peek(), None);
92 assert_eq!(q.pop(), None);
93}
94
95#[test]
96fn test_pollqueue_repeat_push() {
97 let mut q = PollQueue::new();
98 assert_eq!(
99 q.push(SequenceNumber::ZERO, Duration::from_micros(200)),
100 None
101 );
102 assert_eq!(
103 q.push(SequenceNumber::ZERO, Duration::from_micros(400)),
104 Some(Duration::from_micros(200))
105 );
106 assert_eq!(
107 q.push(SequenceNumber::ZERO, Duration::from_micros(300)),
108 Some(Duration::from_micros(400))
109 );
110 assert_eq!(
111 q.pop(),
112 Some((SequenceNumber::ZERO, Duration::from_micros(300)))
113 );
114 assert!(q.is_empty());
115}