1
//! Helper types used by the [`Reactor`] for scheduling descriptor reuploads.
2

            
3
use super::*;
4

            
5
/// A type that represents when a descriptor should be republished.
6
///
7
/// A `ReuploadTimer` is "greater" than another if its `when` timestamp is earlier.
8
///
9
/// This type is used in a max-heap to extract the earliest reupload the publisher can schedule.
10
#[derive(Clone, Copy, Debug)]
11
pub(super) struct ReuploadTimer {
12
    /// The TP for which to republish the descriptor.
13
    pub(super) period: TimePeriod,
14
    /// The earliest time when the descriptor should be republished.
15
    pub(super) when: Instant,
16
}
17

            
18
impl Ord for ReuploadTimer {
19
12
    fn cmp(&self, other: &Self) -> Ordering {
20
        // Reversed, because we want the earlier
21
        // `ReuploadTimer` to be "greater".
22
12
        self.when.cmp(&other.when).reverse()
23
12
    }
24
}
25

            
26
impl PartialOrd for ReuploadTimer {
27
12
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
28
12
        Some(self.cmp(other))
29
12
    }
30
}
31

            
32
impl PartialEq for ReuploadTimer {
33
20
    fn eq(&self, other: &Self) -> bool {
34
20
        self.when == other.when
35
20
    }
36
}
37

            
38
impl Eq for ReuploadTimer {}
39

            
40
#[cfg(test)]
41
mod test {
42
    // @@ begin test lint list maintained by maint/add_warning @@
43
    #![allow(clippy::bool_assert_comparison)]
44
    #![allow(clippy::clone_on_copy)]
45
    #![allow(clippy::dbg_macro)]
46
    #![allow(clippy::mixed_attributes_style)]
47
    #![allow(clippy::print_stderr)]
48
    #![allow(clippy::print_stdout)]
49
    #![allow(clippy::single_char_pattern)]
50
    #![allow(clippy::unwrap_used)]
51
    #![allow(clippy::unchecked_time_subtraction)]
52
    #![allow(clippy::useless_vec)]
53
    #![allow(clippy::needless_pass_by_value)]
54
    #![allow(clippy::string_slice)] // See arti#2571
55
    //! <!-- @@ end test lint list maintained by maint/add_warning @@ -->
56
    use std::collections::BinaryHeap;
57

            
58
    use super::*;
59
    use web_time_compat::InstantExt;
60

            
61
    #[test]
62
    fn reupload_for_time_period_ordering() {
63
        const ONE_SEC: Duration = Duration::from_secs(1);
64

            
65
        let now = Instant::get();
66
        let later = now + ONE_SEC;
67
        let later_still = now + ONE_SEC * 2;
68
        let timer1 = ReuploadTimer {
69
            period: TimePeriod::from_parts(1, 2, 3),
70
            when: now,
71
        };
72

            
73
        let timer2 = ReuploadTimer {
74
            period: TimePeriod::from_parts(4, 5, 6),
75
            when: later,
76
        };
77

            
78
        let timer3 = ReuploadTimer {
79
            period: TimePeriod::from_parts(7, 8, 9),
80
            when: later_still,
81
        };
82

            
83
        for timer in &[timer1, timer2, timer3] {
84
            assert_eq!(timer, timer);
85
        }
86

            
87
        assert_ne!(timer1, timer2);
88
        assert_ne!(timer1, timer3);
89
        assert_ne!(timer2, timer3);
90

            
91
        assert!(timer1 > timer2);
92
        assert!(timer1 > timer3);
93
        assert!(timer2 > timer3);
94

            
95
        // A ReuploadTimer same `when`, but a different `time_period`.
96
        let mut timer4 = timer1;
97
        timer4.period = TimePeriod::from_parts(9, 9, 9);
98
        assert_ne!(timer1.period, timer4.period);
99
        assert_eq!(timer1, timer4);
100

            
101
        let mut heap = BinaryHeap::default();
102
        for timer in &[timer3, timer2, timer1] {
103
            heap.push(*timer);
104
        }
105

            
106
        assert_eq!(heap.pop(), Some(timer1));
107
        assert_eq!(heap.pop(), Some(timer2));
108
        assert_eq!(heap.pop(), Some(timer3));
109
        assert_eq!(heap.pop(), None);
110
    }
111
}