1use std::cmp::Reverse;
2use std::collections::{BinaryHeap, HashMap, VecDeque};
3use std::hash::Hash;
4
5#[derive(Clone, Eq, PartialEq)]
6struct EventEntry<T> {
7 priority: i8,
8 counter: usize,
9 item: T,
10}
11
12impl<T: Eq + PartialEq> EventEntry<T> {
13 fn new(priority: i8, counter: usize, item: T) -> Self {
14 Self {
15 priority,
16 counter,
17 item,
18 }
19 }
20}
21
22impl<T: Eq + PartialEq> Ord for EventEntry<T> {
23 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
24 Reverse(self.priority)
26 .cmp(&Reverse(other.priority))
27 .then(self.counter.cmp(&other.counter))
28 }
29}
30
31impl<T: Eq + PartialEq> PartialOrd for EventEntry<T> {
32 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
33 Some(self.cmp(other))
34 }
35}
36
37pub struct EventQueue<T: PartialEq + Hash + Clone> {
38 heap: BinaryHeap<EventEntry<T>>,
39 entry_finder: HashMap<T, Option<EventEntry<T>>>,
40 counter: usize,
41 order_queue: VecDeque<T>,
42}
43
44impl<T: Eq + Hash + Clone> EventQueue<T> {
45 pub fn new() -> Self {
46 Self {
47 heap: BinaryHeap::new(),
48 entry_finder: HashMap::new(),
49 counter: 0,
50 order_queue: VecDeque::new(),
51 }
52 }
53
54 pub fn push(&mut self, priority: i8, item: T) {
55 if self.entry_finder.contains_key(&item) {
56 self.remove(&item);
57 }
58 let entry = EventEntry::new(priority, self.counter, item.clone());
59 self.counter += 1;
60 self.entry_finder.insert(item.clone(), Some(entry.clone()));
61 self.heap.push(entry);
62 self.order_queue.push_front(item);
63 }
64
65 pub fn pop(&mut self) -> Option<T> {
66 while let Some(EventEntry { item, .. }) = self.heap.pop() {
67 if let Some(Some(_)) = self.entry_finder.remove(&item) {
68 self.order_queue.retain(|x| x != &item);
69 return Some(item);
70 }
71 }
72 None
73 }
74
75 pub fn remove(&mut self, item: &T) {
76 if let Some(Some(mut entry)) = self.entry_finder.remove(item) {
77 entry.item = item.clone(); self.order_queue.retain(|x| x != item);
79 }
80 }
81
82 pub fn is_empty(&self) -> bool {
83 self.heap.is_empty()
84 }
85
86 pub fn len(&self) -> usize {
87 self.heap.len()
88 }
89}
90
91impl<T: Eq + Hash + Clone> Default for EventQueue<T> {
92 fn default() -> Self {
93 Self::new()
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn test_event_queue() {
103 let mut queue = EventQueue::new();
104 queue.push(1, "a");
105 queue.push(2, "b");
106 queue.push(3, "c");
107 queue.push(2, "d");
108 queue.push(1, "e");
109 assert_eq!(queue.pop(), Some("e"));
110 assert_eq!(queue.pop(), Some("a"));
111 assert_eq!(queue.pop(), Some("d"));
112 assert_eq!(queue.pop(), Some("b"));
113 assert_eq!(queue.pop(), Some("c"));
114 assert_eq!(queue.pop(), None);
115 }
116}