sark_core/deadline/
exact.rs1use o3::depot::{
2 capacity,
3 heap::{self, keyed},
4};
5
6use crate::{deadline, manifold};
7
8pub struct Exact<K: manifold::raw::Key, P: Copy + Ord> {
10 heap: keyed::Min<K, deadline::Scheduled<P>>,
11}
12
13impl<K: manifold::raw::Key, P: Copy + Ord> Exact<K, P> {
14 pub fn try_new(capacity: capacity::Count) -> Result<Self, heap::Error> {
15 Ok(Self {
16 heap: keyed::Min::try_new(capacity)?,
17 })
18 }
19}
20
21impl<K: manifold::raw::Key, P: Copy + Ord> deadline::Book<K, P> for Exact<K, P> {
22 fn schedule(&mut self, key: K, item: deadline::Scheduled<P>) -> Result<(), deadline::Error<K>> {
23 match self.heap.entry(key) {
24 Err(error) => {
25 return Err(deadline::Error::OutOfRange {
26 key: error.key(),
27 capacity: error.capacity(),
28 });
29 }
30 Ok(keyed::Entry::Vacant(entry)) => entry.insert(item),
31 Ok(keyed::Entry::Occupied(entry)) if *entry.priority() == item => {}
32 Ok(keyed::Entry::Occupied(entry)) => entry.set(item),
33 Ok(keyed::Entry::Conflict(error)) => {
34 return Err(deadline::Error::Conflict {
35 requested: error.requested(),
36 current: error.current(),
37 });
38 }
39 }
40 Ok(())
41 }
42
43 fn cancel(&mut self, key: K) -> deadline::Mutation {
44 let heap::Probe::Occupied(entry) = self.heap.probe(key) else {
45 return deadline::Mutation::Unchanged;
46 };
47 entry.retire_min().into()
48 }
49
50 fn cancel_one(&mut self, key: K, action: deadline::Action) -> deadline::Mutation {
51 let heap::Probe::Occupied(entry) = self.heap.probe(key) else {
52 return deadline::Mutation::Unchanged;
53 };
54 if entry.priority().action != action {
55 return deadline::Mutation::Unchanged;
56 }
57 entry.retire_min().into()
58 }
59
60 fn peek(&self) -> Option<(K, deadline::Scheduled<P>)> {
61 self.heap.peek().map(|(key, item)| (key, *item))
62 }
63
64 fn poll_due(&mut self, now: P) -> deadline::Poll<deadline::Expired<K, P>> {
65 let Some(entry) = self.heap.first_entry() else {
66 return deadline::Poll::Idle;
67 };
68 if entry.priority().at > now {
69 return deadline::Poll::Idle;
70 }
71 deadline::Poll::Expired(deadline::Expired {
72 key: entry.key(),
73 scheduled: entry.remove(),
74 })
75 }
76
77 fn len(&self) -> usize {
78 self.heap.len()
79 }
80}