1//! A priority queue in which elements of the same priority are popped in a LIFO order.
23use smallvec::SmallVec;
45/// A priority stack in which elements of the same priority are popped in a LIFO order.
6// TODO(mingwei): Keep an upper bound on current priority to avoid scanning all stacks?
7#[derive(Debug, Clone)]
8pub struct PriorityStack<T> {
9/// Note: inner stack `Vec`s may be empty.
10stacks: Vec<SmallVec<[T; 1]>>,
11}
1213impl<T> PriorityStack<T> {
14/// Creates a new, empty `PriorityStack`.
15pub fn new() -> Self {
16Self {
17 stacks: Vec::default(),
18 }
19 }
2021/// Creates a new, empty `PriorityStack` with pre-allocated capacity up to the given priority.
22pub fn with_priority_capacity(priority: usize) -> Self {
23Self {
24 stacks: Vec::with_capacity(priority),
25 }
26 }
2728/// Pushes an element onto the stack with the given priority.
29pub fn push(&mut self, priority: usize, item: T) {
30if priority >= self.stacks.len() {
31self.stacks.resize_with(priority + 1, Default::default);
32 }
33self.stacks[priority].push(item);
34 }
3536/// Pops an element from the stack with the highest priority.
37pub fn pop(&mut self) -> Option<T> {
38self.stacks
39 .iter_mut()
40 .rev()
41 .filter_map(SmallVec::pop)
42 .next()
43 }
4445/// Pops an element from the stack and return `(priority, item)`.
46pub fn pop_prio(&mut self) -> Option<(usize, T)> {
47self.stacks
48 .iter_mut()
49 .enumerate()
50 .rev()
51 .filter_map(|(i, stack)| stack.pop().map(|x| (i, x)))
52 .next()
53 }
5455/// Returns the item with the highest priority without removing it.
56pub fn peek(&self) -> Option<&T> {
57self.stacks
58 .iter()
59 .rev()
60 .filter_map(|stack| stack.last())
61 .next()
62 }
6364/// Returns the item with the highest priority and its priority without removing it.
65pub fn peek_prio(&self) -> Option<(usize, &T)> {
66self.stacks
67 .iter()
68 .enumerate()
69 .rev()
70 .filter_map(|(i, stack)| stack.last().map(|x| (i, x)))
71 .next()
72 }
7374/// Returns the number of elements in the `PriorityStack`.
75pub fn len(&self) -> usize {
76self.stacks.iter().map(SmallVec::len).sum()
77 }
7879/// Returns true if the `PriorityStack` is empty.
80pub fn is_empty(&self) -> bool {
81self.stacks.is_empty()
82 }
83}
8485impl<T> Default for PriorityStack<T> {
86fn default() -> Self {
87Self::new()
88 }
89}
9091impl<T> Extend<(usize, T)> for PriorityStack<T> {
92fn extend<I: IntoIterator<Item = (usize, T)>>(&mut self, iter: I) {
93for (priority, item) in iter {
94self.push(priority, item);
95 }
96 }
97}