dfir_rs/util/
priority_stack.rs1use smallvec::SmallVec;
4
5#[derive(Debug, Clone)]
8pub struct PriorityStack<T> {
9 stacks: Vec<SmallVec<[T; 1]>>,
11}
12
13impl<T> PriorityStack<T> {
14 pub fn new() -> Self {
16 Self {
17 stacks: Vec::default(),
18 }
19 }
20
21 pub fn with_priority_capacity(priority: usize) -> Self {
23 Self {
24 stacks: Vec::with_capacity(priority),
25 }
26 }
27
28 pub fn push(&mut self, priority: usize, item: T) {
30 if priority >= self.stacks.len() {
31 self.stacks.resize_with(priority + 1, Default::default);
32 }
33 self.stacks[priority].push(item);
34 }
35
36 pub fn pop(&mut self) -> Option<T> {
38 self.stacks
39 .iter_mut()
40 .rev()
41 .filter_map(SmallVec::pop)
42 .next()
43 }
44
45 pub fn pop_prio(&mut self) -> Option<(usize, T)> {
47 self.stacks
48 .iter_mut()
49 .enumerate()
50 .rev()
51 .filter_map(|(i, stack)| stack.pop().map(|x| (i, x)))
52 .next()
53 }
54
55 pub fn peek(&self) -> Option<&T> {
57 self.stacks
58 .iter()
59 .rev()
60 .filter_map(|stack| stack.last())
61 .next()
62 }
63
64 pub fn peek_prio(&self) -> Option<(usize, &T)> {
66 self.stacks
67 .iter()
68 .enumerate()
69 .rev()
70 .filter_map(|(i, stack)| stack.last().map(|x| (i, x)))
71 .next()
72 }
73
74 pub fn len(&self) -> usize {
76 self.stacks.iter().map(SmallVec::len).sum()
77 }
78
79 pub fn is_empty(&self) -> bool {
81 self.stacks.is_empty()
82 }
83}
84
85impl<T> Default for PriorityStack<T> {
86 fn default() -> Self {
87 Self::new()
88 }
89}
90
91impl<T> Extend<(usize, T)> for PriorityStack<T> {
92 fn extend<I: IntoIterator<Item = (usize, T)>>(&mut self, iter: I) {
93 for (priority, item) in iter {
94 self.push(priority, item);
95 }
96 }
97}