Skip to main content

komora_sync/
priority_queue.rs

1use std::collections::BinaryHeap;
2use std::sync::{Condvar, Mutex};
3
4use crate::Prioritized;
5
6#[derive(Debug)]
7pub struct PriorityQueue<T> {
8    q: Mutex<BinaryHeap<Prioritized<T>>>,
9    cv: Condvar,
10}
11
12impl<T> Default for PriorityQueue<T> {
13    fn default() -> Self {
14        Self::new()
15    }
16}
17
18impl<T> PriorityQueue<T> {
19    pub fn new() -> PriorityQueue<T> {
20        PriorityQueue {
21            q: Mutex::default(),
22            cv: Condvar::new(),
23        }
24    }
25
26    /// Higher priority gets popped first.
27    ///
28    /// # Examples
29    /// ```
30    /// let pq = komora_sync::PriorityQueue::new();
31    /// pq.push(2, 2);
32    /// pq.push(1, 1);
33    /// pq.push(4, 4);
34    /// pq.push(1, 1);
35    /// assert_eq!(pq.pop(), 4);
36    /// assert_eq!(pq.pop(), 2);
37    /// assert_eq!(pq.pop(), 1);
38    /// assert_eq!(pq.pop(), 1);
39    /// ```
40    pub fn push(&self, t: T, priority: u64) {
41        let mut q = self.q.lock().unwrap();
42        q.push(Prioritized { t, priority });
43        drop(q);
44        self.cv.notify_one();
45    }
46
47    pub fn pop(&self) -> T {
48        let mut q = self.q.lock().unwrap();
49
50        while q.is_empty() {
51            q = self.cv.wait(q).unwrap();
52        }
53
54        q.pop().unwrap().t
55    }
56}