Coverage Report

Created: 2024-12-17 06:15

/rust/registry/src/index.crates.io-6f17d22bba15001f/futures-timer-3.0.3/src/native/heap.rs
Line
Count
Source (jump to first uncovered line)
1
//! A simple binary heap with support for removal of arbitrary elements
2
//!
3
//! This heap is used to manage timer state in the event loop. All timeouts go
4
//! into this heap and we also cancel timeouts from this heap. The crucial
5
//! feature of this heap over the standard library's `BinaryHeap` is the ability
6
//! to remove arbitrary elements. (e.g. when a timer is canceled)
7
//!
8
//! Note that this heap is not at all optimized right now, it should hopefully
9
//! just work.
10
11
use std::mem;
12
13
pub struct Heap<T> {
14
    // Binary heap of items, plus the slab index indicating what position in the
15
    // list they're in.
16
    items: Vec<(T, usize)>,
17
18
    // A map from a slab index (assigned to an item above) to the actual index
19
    // in the array the item appears at.
20
    index: Vec<SlabSlot<usize>>,
21
    next_index: usize,
22
}
23
24
enum SlabSlot<T> {
25
    Empty { next: usize },
26
    Full { value: T },
27
}
28
29
pub struct Slot {
30
    idx: usize,
31
}
32
33
impl<T: Ord> Heap<T> {
34
0
    pub fn new() -> Heap<T> {
35
0
        Heap {
36
0
            items: Vec::new(),
37
0
            index: Vec::new(),
38
0
            next_index: 0,
39
0
        }
40
0
    }
41
42
    /// Pushes an element onto this heap, returning a slot token indicating
43
    /// where it was pushed on to.
44
    ///
45
    /// The slot can later get passed to `remove` to remove the element from the
46
    /// heap, but only if the element was previously not removed from the heap.
47
0
    pub fn push(&mut self, t: T) -> Slot {
48
0
        self.assert_consistent();
49
0
        let len = self.items.len();
50
0
        let slot = SlabSlot::Full { value: len };
51
0
        let slot_idx = if self.next_index == self.index.len() {
52
0
            self.next_index += 1;
53
0
            self.index.push(slot);
54
0
            self.index.len() - 1
55
        } else {
56
0
            match mem::replace(&mut self.index[self.next_index], slot) {
57
0
                SlabSlot::Empty { next } => mem::replace(&mut self.next_index, next),
58
0
                SlabSlot::Full { .. } => panic!(),
59
            }
60
        };
61
0
        self.items.push((t, slot_idx));
62
0
        self.percolate_up(len);
63
0
        self.assert_consistent();
64
0
        Slot { idx: slot_idx }
65
0
    }
66
67
0
    pub fn peek(&self) -> Option<&T> {
68
0
        self.assert_consistent();
69
0
        self.items.first().map(|i| &i.0)
70
0
    }
71
72
0
    pub fn pop(&mut self) -> Option<T> {
73
0
        self.assert_consistent();
74
0
        if self.items.is_empty() {
75
0
            return None;
76
0
        }
77
0
        let slot = Slot {
78
0
            idx: self.items[0].1,
79
0
        };
80
0
        Some(self.remove(slot))
81
0
    }
82
83
0
    pub fn remove(&mut self, slot: Slot) -> T {
84
0
        self.assert_consistent();
85
0
        let empty = SlabSlot::Empty {
86
0
            next: self.next_index,
87
0
        };
88
0
        let idx = match mem::replace(&mut self.index[slot.idx], empty) {
89
0
            SlabSlot::Full { value } => value,
90
0
            SlabSlot::Empty { .. } => panic!(),
91
        };
92
0
        self.next_index = slot.idx;
93
0
        let (item, slot_idx) = self.items.swap_remove(idx);
94
0
        debug_assert_eq!(slot.idx, slot_idx);
95
0
        if idx < self.items.len() {
96
0
            set_index(&mut self.index, self.items[idx].1, idx);
97
0
            if self.items[idx].0 < item {
98
0
                self.percolate_up(idx);
99
0
            } else {
100
0
                self.percolate_down(idx);
101
0
            }
102
0
        }
103
0
        self.assert_consistent();
104
0
        item
105
0
    }
106
107
0
    fn percolate_up(&mut self, mut idx: usize) -> usize {
108
0
        while idx > 0 {
109
0
            let parent = (idx - 1) / 2;
110
0
            if self.items[idx].0 >= self.items[parent].0 {
111
0
                break;
112
0
            }
113
0
            let (a, b) = self.items.split_at_mut(idx);
114
0
            mem::swap(&mut a[parent], &mut b[0]);
115
0
            set_index(&mut self.index, a[parent].1, parent);
116
0
            set_index(&mut self.index, b[0].1, idx);
117
0
            idx = parent;
118
        }
119
0
        idx
120
0
    }
121
122
0
    fn percolate_down(&mut self, mut idx: usize) -> usize {
123
        loop {
124
0
            let left = 2 * idx + 1;
125
0
            let right = 2 * idx + 2;
126
0
127
0
            let mut swap_left = true;
128
0
            match (self.items.get(left), self.items.get(right)) {
129
0
                (Some(left), None) => {
130
0
                    if left.0 >= self.items[idx].0 {
131
0
                        break;
132
0
                    }
133
                }
134
0
                (Some(left), Some(right)) => {
135
0
                    if left.0 < self.items[idx].0 {
136
0
                        if right.0 < left.0 {
137
0
                            swap_left = false;
138
0
                        }
139
0
                    } else if right.0 < self.items[idx].0 {
140
0
                        swap_left = false;
141
0
                    } else {
142
0
                        break;
143
                    }
144
                }
145
146
0
                (None, None) => break,
147
0
                (None, Some(_right)) => panic!("not possible"),
148
            }
149
150
0
            let (a, b) = if swap_left {
151
0
                self.items.split_at_mut(left)
152
            } else {
153
0
                self.items.split_at_mut(right)
154
            };
155
0
            mem::swap(&mut a[idx], &mut b[0]);
156
0
            set_index(&mut self.index, a[idx].1, idx);
157
0
            set_index(&mut self.index, b[0].1, a.len());
158
0
            idx = a.len();
159
        }
160
0
        idx
161
0
    }
162
163
0
    fn assert_consistent(&self) {
164
0
        if !cfg!(assert_timer_heap_consistent) {
165
0
            return;
166
0
        }
167
0
168
0
        assert_eq!(
169
0
            self.items.len(),
170
0
            self.index
171
0
                .iter()
172
0
                .filter(|slot| {
173
0
                    match **slot {
174
0
                        SlabSlot::Full { .. } => true,
175
0
                        SlabSlot::Empty { .. } => false,
176
                    }
177
0
                })
178
0
                .count()
179
0
        );
180
181
0
        for (i, &(_, j)) in self.items.iter().enumerate() {
182
0
            let index = match self.index[j] {
183
0
                SlabSlot::Full { value } => value,
184
0
                SlabSlot::Empty { .. } => panic!(),
185
            };
186
0
            if index != i {
187
0
                panic!(
188
0
                    "self.index[j] != i : i={} j={} self.index[j]={}",
189
0
                    i, j, index
190
0
                );
191
0
            }
192
        }
193
194
0
        for (i, (item, _)) in self.items.iter().enumerate() {
195
0
            if i > 0 {
196
0
                assert!(*item >= self.items[(i - 1) / 2].0, "bad at index: {}", i);
197
0
            }
198
0
            if let Some(left) = self.items.get(2 * i + 1) {
199
0
                assert!(*item <= left.0, "bad left at index: {}", i);
200
0
            }
201
0
            if let Some(right) = self.items.get(2 * i + 2) {
202
0
                assert!(*item <= right.0, "bad right at index: {}", i);
203
0
            }
204
        }
205
0
    }
206
}
207
208
0
fn set_index<T>(slab: &mut Vec<SlabSlot<T>>, slab_slot: usize, val: T) {
209
0
    match slab[slab_slot] {
210
0
        SlabSlot::Full { ref mut value } => *value = val,
211
0
        SlabSlot::Empty { .. } => panic!(),
212
    }
213
0
}
214
215
#[cfg(test)]
216
mod tests {
217
    use super::Heap;
218
219
    #[test]
220
    fn simple() {
221
        let mut h = Heap::new();
222
        h.push(1);
223
        h.push(2);
224
        h.push(8);
225
        h.push(4);
226
        assert_eq!(h.pop(), Some(1));
227
        assert_eq!(h.pop(), Some(2));
228
        assert_eq!(h.pop(), Some(4));
229
        assert_eq!(h.pop(), Some(8));
230
        assert_eq!(h.pop(), None);
231
        assert_eq!(h.pop(), None);
232
    }
233
234
    #[test]
235
    fn simple2() {
236
        let mut h = Heap::new();
237
        h.push(5);
238
        h.push(4);
239
        h.push(3);
240
        h.push(2);
241
        h.push(1);
242
        assert_eq!(h.pop(), Some(1));
243
        h.push(8);
244
        assert_eq!(h.pop(), Some(2));
245
        h.push(1);
246
        assert_eq!(h.pop(), Some(1));
247
        assert_eq!(h.pop(), Some(3));
248
        assert_eq!(h.pop(), Some(4));
249
        h.push(5);
250
        assert_eq!(h.pop(), Some(5));
251
        assert_eq!(h.pop(), Some(5));
252
        assert_eq!(h.pop(), Some(8));
253
    }
254
255
    #[test]
256
    fn remove() {
257
        let mut h = Heap::new();
258
        h.push(5);
259
        h.push(4);
260
        h.push(3);
261
        let two = h.push(2);
262
        h.push(1);
263
        assert_eq!(h.pop(), Some(1));
264
        assert_eq!(h.remove(two), 2);
265
        h.push(1);
266
        assert_eq!(h.pop(), Some(1));
267
        assert_eq!(h.pop(), Some(3));
268
    }
269
270
    fn vec2heap<T: Ord>(v: Vec<T>) -> Heap<T> {
271
        let mut h = Heap::new();
272
        for t in v {
273
            h.push(t);
274
        }
275
        h
276
    }
277
278
    #[test]
279
    fn test_peek_and_pop() {
280
        let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
281
        let mut sorted = data.clone();
282
        sorted.sort();
283
        let mut heap = vec2heap(data);
284
        while heap.peek().is_some() {
285
            assert_eq!(heap.peek().unwrap(), sorted.first().unwrap());
286
            assert_eq!(heap.pop().unwrap(), sorted.remove(0));
287
        }
288
    }
289
290
    #[test]
291
    fn test_push() {
292
        let mut heap = Heap::new();
293
        heap.push(-2);
294
        heap.push(-4);
295
        heap.push(-9);
296
        assert!(*heap.peek().unwrap() == -9);
297
        heap.push(-11);
298
        assert!(*heap.peek().unwrap() == -11);
299
        heap.push(-5);
300
        assert!(*heap.peek().unwrap() == -11);
301
        heap.push(-27);
302
        assert!(*heap.peek().unwrap() == -27);
303
        heap.push(-3);
304
        assert!(*heap.peek().unwrap() == -27);
305
        heap.push(-103);
306
        assert!(*heap.peek().unwrap() == -103);
307
    }
308
309
    fn check_to_vec(mut data: Vec<i32>) {
310
        let mut heap = Heap::new();
311
        for data in data.iter() {
312
            heap.push(*data);
313
        }
314
        data.sort();
315
        let mut v = Vec::new();
316
        while let Some(i) = heap.pop() {
317
            v.push(i);
318
        }
319
        assert_eq!(v, data);
320
    }
321
322
    #[test]
323
    fn test_to_vec() {
324
        check_to_vec(vec![]);
325
        check_to_vec(vec![5]);
326
        check_to_vec(vec![3, 2]);
327
        check_to_vec(vec![2, 3]);
328
        check_to_vec(vec![5, 1, 2]);
329
        check_to_vec(vec![1, 100, 2, 3]);
330
        check_to_vec(vec![1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
331
        check_to_vec(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
332
        check_to_vec(vec![9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
333
        check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
334
        check_to_vec(vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
335
        check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
336
        check_to_vec(vec![5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
337
    }
338
339
    #[test]
340
    fn test_empty_pop() {
341
        let mut heap = Heap::<i32>::new();
342
        assert!(heap.pop().is_none());
343
    }
344
345
    #[test]
346
    fn test_empty_peek() {
347
        let empty = Heap::<i32>::new();
348
        assert!(empty.peek().is_none());
349
    }
350
}