oxihuman_core/
update_queue.rs1#![allow(dead_code)]
4
5use std::cmp::Reverse;
8use std::collections::BinaryHeap;
9
10#[allow(dead_code)]
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct UpdateItem {
14 pub priority: u32,
15 pub id: u32,
16 pub tag: String,
17}
18
19impl PartialOrd for UpdateItem {
20 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
21 Some(self.cmp(other))
22 }
23}
24
25impl Ord for UpdateItem {
26 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
27 Reverse(self.priority).cmp(&Reverse(other.priority))
28 }
29}
30
31#[allow(dead_code)]
33#[derive(Debug, Clone, Default)]
34pub struct UpdateQueue {
35 heap: BinaryHeap<UpdateItem>,
36 total_enqueued: u64,
37}
38
39#[allow(dead_code)]
41pub fn new_update_queue() -> UpdateQueue {
42 UpdateQueue::default()
43}
44
45#[allow(dead_code)]
47pub fn uq_enqueue(q: &mut UpdateQueue, id: u32, priority: u32, tag: &str) {
48 q.heap.push(UpdateItem {
49 priority,
50 id,
51 tag: tag.to_string(),
52 });
53 q.total_enqueued += 1;
54}
55
56#[allow(dead_code)]
58pub fn uq_dequeue(q: &mut UpdateQueue) -> Option<UpdateItem> {
59 q.heap.pop()
60}
61
62#[allow(dead_code)]
64pub fn uq_peek(q: &UpdateQueue) -> Option<&UpdateItem> {
65 q.heap.peek()
66}
67
68#[allow(dead_code)]
70pub fn uq_len(q: &UpdateQueue) -> usize {
71 q.heap.len()
72}
73
74#[allow(dead_code)]
76pub fn uq_is_empty(q: &UpdateQueue) -> bool {
77 q.heap.is_empty()
78}
79
80#[allow(dead_code)]
82pub fn uq_total_enqueued(q: &UpdateQueue) -> u64 {
83 q.total_enqueued
84}
85
86#[allow(dead_code)]
88pub fn uq_drain_all(q: &mut UpdateQueue) -> Vec<UpdateItem> {
89 let mut items = Vec::new();
90 while let Some(item) = q.heap.pop() {
91 items.push(item);
92 }
93 items
94}
95
96#[allow(dead_code)]
98pub fn uq_clear(q: &mut UpdateQueue) {
99 q.heap.clear();
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_empty() {
108 let q = new_update_queue();
109 assert!(uq_is_empty(&q));
110 }
111
112 #[test]
113 fn test_enqueue_and_len() {
114 let mut q = new_update_queue();
115 uq_enqueue(&mut q, 1, 5, "x");
116 assert_eq!(uq_len(&q), 1);
117 }
118
119 #[test]
120 fn test_priority_order() {
121 let mut q = new_update_queue();
122 uq_enqueue(&mut q, 1, 10, "low");
123 uq_enqueue(&mut q, 2, 1, "high");
124 let first = uq_dequeue(&mut q).expect("should succeed");
125 assert_eq!(first.id, 2);
126 }
127
128 #[test]
129 fn test_peek_does_not_remove() {
130 let mut q = new_update_queue();
131 uq_enqueue(&mut q, 1, 3, "x");
132 uq_peek(&q);
133 assert_eq!(uq_len(&q), 1);
134 }
135
136 #[test]
137 fn test_drain_all() {
138 let mut q = new_update_queue();
139 uq_enqueue(&mut q, 3, 5, "c");
140 uq_enqueue(&mut q, 1, 1, "a");
141 uq_enqueue(&mut q, 2, 3, "b");
142 let items = uq_drain_all(&mut q);
143 assert_eq!(items.len(), 3);
144 assert!(uq_is_empty(&q));
145 assert_eq!(items[0].id, 1);
146 }
147
148 #[test]
149 fn test_clear() {
150 let mut q = new_update_queue();
151 uq_enqueue(&mut q, 1, 1, "x");
152 uq_clear(&mut q);
153 assert!(uq_is_empty(&q));
154 }
155
156 #[test]
157 fn test_total_enqueued() {
158 let mut q = new_update_queue();
159 uq_enqueue(&mut q, 1, 1, "a");
160 uq_enqueue(&mut q, 2, 2, "b");
161 assert_eq!(uq_total_enqueued(&q), 2);
162 }
163
164 #[test]
165 fn test_dequeue_empty() {
166 let mut q = new_update_queue();
167 assert!(uq_dequeue(&mut q).is_none());
168 }
169
170 #[test]
171 fn test_tag_preserved() {
172 let mut q = new_update_queue();
173 uq_enqueue(&mut q, 1, 0, "mytag");
174 let item = uq_dequeue(&mut q).expect("should succeed");
175 assert_eq!(item.tag, "mytag".to_string());
176 }
177}