heapless/
binary_heap.rs

1//! A priority queue implemented with a binary heap.
2//!
3//! Insertion and popping the largest element have `O(log n)` time complexity. Checking the largest
4//! / smallest element is `O(1)`.
5
6// TODO not yet implemented
7// Converting a vector to a binary heap can be done in-place, and has `O(n)` complexity. A binary
8// heap can also be converted to a sorted vector in-place, allowing it to be used for an `O(n log
9// n)` in-place heapsort.
10
11use core::{
12    cmp::Ordering,
13    fmt,
14    marker::PhantomData,
15    mem::{self, ManuallyDrop},
16    ops::{Deref, DerefMut},
17    ptr, slice,
18};
19
20use crate::vec::Vec;
21
22/// Min-heap
23pub enum Min {}
24
25/// Max-heap
26pub enum Max {}
27
28/// The binary heap kind: min-heap or max-heap
29pub trait Kind: private::Sealed {
30    #[doc(hidden)]
31    fn ordering() -> Ordering;
32}
33
34impl Kind for Min {
35    fn ordering() -> Ordering {
36        Ordering::Less
37    }
38}
39
40impl Kind for Max {
41    fn ordering() -> Ordering {
42        Ordering::Greater
43    }
44}
45
46/// Sealed traits
47mod private {
48    pub trait Sealed {}
49}
50
51impl private::Sealed for Max {}
52impl private::Sealed for Min {}
53
54/// A priority queue implemented with a binary heap.
55///
56/// This can be either a min-heap or a max-heap.
57///
58/// It is a logic error for an item to be modified in such a way that the item's ordering relative
59/// to any other item, as determined by the `Ord` trait, changes while it is in the heap. This is
60/// normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
61///
62/// ```
63/// use heapless::binary_heap::{BinaryHeap, Max};
64///
65/// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
66///
67/// // We can use peek to look at the next item in the heap. In this case,
68/// // there's no items in there yet so we get None.
69/// assert_eq!(heap.peek(), None);
70///
71/// // Let's add some scores...
72/// heap.push(1).unwrap();
73/// heap.push(5).unwrap();
74/// heap.push(2).unwrap();
75///
76/// // Now peek shows the most important item in the heap.
77/// assert_eq!(heap.peek(), Some(&5));
78///
79/// // We can check the length of a heap.
80/// assert_eq!(heap.len(), 3);
81///
82/// // We can iterate over the items in the heap, although they are returned in
83/// // a random order.
84/// for x in &heap {
85///     println!("{}", x);
86/// }
87///
88/// // If we instead pop these scores, they should come back in order.
89/// assert_eq!(heap.pop(), Some(5));
90/// assert_eq!(heap.pop(), Some(2));
91/// assert_eq!(heap.pop(), Some(1));
92/// assert_eq!(heap.pop(), None);
93///
94/// // We can clear the heap of any remaining items.
95/// heap.clear();
96///
97/// // The heap should now be empty.
98/// assert!(heap.is_empty())
99/// ```
100
101pub struct BinaryHeap<T, K, const N: usize> {
102    pub(crate) _kind: PhantomData<K>,
103    pub(crate) data: Vec<T, N>,
104}
105
106impl<T, K, const N: usize> BinaryHeap<T, K, N> {
107    /* Constructors */
108    /// Creates an empty BinaryHeap as a $K-heap.
109    ///
110    /// ```
111    /// use heapless::binary_heap::{BinaryHeap, Max};
112    ///
113    /// // allocate the binary heap on the stack
114    /// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
115    /// heap.push(4).unwrap();
116    ///
117    /// // allocate the binary heap in a static variable
118    /// static mut HEAP: BinaryHeap<i32, Max, 8> = BinaryHeap::new();
119    /// ```
120    pub const fn new() -> Self {
121        Self {
122            _kind: PhantomData,
123            data: Vec::new(),
124        }
125    }
126}
127
128impl<T, K, const N: usize> BinaryHeap<T, K, N>
129where
130    T: Ord,
131    K: Kind,
132{
133    /* Public API */
134    /// Returns the capacity of the binary heap.
135    pub fn capacity(&self) -> usize {
136        self.data.capacity()
137    }
138
139    /// Drops all items from the binary heap.
140    ///
141    /// ```
142    /// use heapless::binary_heap::{BinaryHeap, Max};
143    ///
144    /// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
145    /// heap.push(1).unwrap();
146    /// heap.push(3).unwrap();
147    ///
148    /// assert!(!heap.is_empty());
149    ///
150    /// heap.clear();
151    ///
152    /// assert!(heap.is_empty());
153    /// ```
154    pub fn clear(&mut self) {
155        self.data.clear()
156    }
157
158    /// Returns the length of the binary heap.
159    ///
160    /// ```
161    /// use heapless::binary_heap::{BinaryHeap, Max};
162    ///
163    /// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
164    /// heap.push(1).unwrap();
165    /// heap.push(3).unwrap();
166    ///
167    /// assert_eq!(heap.len(), 2);
168    /// ```
169    pub fn len(&self) -> usize {
170        self.data.len()
171    }
172
173    /// Checks if the binary heap is empty.
174    ///
175    /// ```
176    /// use heapless::binary_heap::{BinaryHeap, Max};
177    ///
178    /// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
179    ///
180    /// assert!(heap.is_empty());
181    ///
182    /// heap.push(3).unwrap();
183    /// heap.push(5).unwrap();
184    /// heap.push(1).unwrap();
185    ///
186    /// assert!(!heap.is_empty());
187    /// ```
188    pub fn is_empty(&self) -> bool {
189        self.len() == 0
190    }
191
192    /// Returns an iterator visiting all values in the underlying vector, in arbitrary order.
193    ///
194    /// ```
195    /// use heapless::binary_heap::{BinaryHeap, Max};
196    ///
197    /// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
198    /// heap.push(1).unwrap();
199    /// heap.push(2).unwrap();
200    /// heap.push(3).unwrap();
201    /// heap.push(4).unwrap();
202    ///
203    /// // Print 1, 2, 3, 4 in arbitrary order
204    /// for x in heap.iter() {
205    ///     println!("{}", x);
206    ///
207    /// }
208    /// ```
209    pub fn iter(&self) -> slice::Iter<'_, T> {
210        self.data.as_slice().iter()
211    }
212
213    /// Returns a mutable iterator visiting all values in the underlying vector, in arbitrary order.
214    ///
215    /// **WARNING** Mutating the items in the binary heap can leave the heap in an inconsistent
216    /// state.
217    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
218        self.data.as_mut_slice().iter_mut()
219    }
220
221    /// Returns the *top* (greatest if max-heap, smallest if min-heap) item in the binary heap, or
222    /// None if it is empty.
223    ///
224    /// ```
225    /// use heapless::binary_heap::{BinaryHeap, Max};
226    ///
227    /// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
228    /// assert_eq!(heap.peek(), None);
229    ///
230    /// heap.push(1).unwrap();
231    /// heap.push(5).unwrap();
232    /// heap.push(2).unwrap();
233    /// assert_eq!(heap.peek(), Some(&5));
234    /// ```
235    pub fn peek(&self) -> Option<&T> {
236        self.data.as_slice().get(0)
237    }
238
239    /// Returns a mutable reference to the greatest item in the binary heap, or
240    /// `None` if it is empty.
241    ///
242    /// Note: If the `PeekMut` value is leaked, the heap may be in an
243    /// inconsistent state.
244    ///
245    /// # Examples
246    ///
247    /// Basic usage:
248    ///
249    /// ```
250    /// use heapless::binary_heap::{BinaryHeap, Max};
251    ///
252    /// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
253    /// assert!(heap.peek_mut().is_none());
254    ///
255    /// heap.push(1);
256    /// heap.push(5);
257    /// heap.push(2);
258    /// {
259    ///     let mut val = heap.peek_mut().unwrap();
260    ///     *val = 0;
261    /// }
262    ///
263    /// assert_eq!(heap.peek(), Some(&2));
264    /// ```
265    pub fn peek_mut(&mut self) -> Option<PeekMut<'_, T, K, N>> {
266        if self.is_empty() {
267            None
268        } else {
269            Some(PeekMut {
270                heap: self,
271                sift: true,
272            })
273        }
274    }
275
276    /// Removes the *top* (greatest if max-heap, smallest if min-heap) item from the binary heap and
277    /// returns it, or None if it is empty.
278    ///
279    /// ```
280    /// use heapless::binary_heap::{BinaryHeap, Max};
281    ///
282    /// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
283    /// heap.push(1).unwrap();
284    /// heap.push(3).unwrap();
285    ///
286    /// assert_eq!(heap.pop(), Some(3));
287    /// assert_eq!(heap.pop(), Some(1));
288    /// assert_eq!(heap.pop(), None);
289    /// ```
290    pub fn pop(&mut self) -> Option<T> {
291        if self.is_empty() {
292            None
293        } else {
294            Some(unsafe { self.pop_unchecked() })
295        }
296    }
297
298    /// Removes the *top* (greatest if max-heap, smallest if min-heap) item from the binary heap and
299    /// returns it, without checking if the binary heap is empty.
300    pub unsafe fn pop_unchecked(&mut self) -> T {
301        let mut item = self.data.pop_unchecked();
302
303        if !self.is_empty() {
304            mem::swap(&mut item, self.data.as_mut_slice().get_unchecked_mut(0));
305            self.sift_down_to_bottom(0);
306        }
307        item
308    }
309
310    /// Pushes an item onto the binary heap.
311    ///
312    /// ```
313    /// use heapless::binary_heap::{BinaryHeap, Max};
314    ///
315    /// let mut heap: BinaryHeap<_, Max, 8> = BinaryHeap::new();
316    /// heap.push(3).unwrap();
317    /// heap.push(5).unwrap();
318    /// heap.push(1).unwrap();
319    ///
320    /// assert_eq!(heap.len(), 3);
321    /// assert_eq!(heap.peek(), Some(&5));
322    /// ```
323    pub fn push(&mut self, item: T) -> Result<(), T> {
324        if self.data.is_full() {
325            return Err(item);
326        }
327
328        unsafe { self.push_unchecked(item) }
329        Ok(())
330    }
331
332    /// Pushes an item onto the binary heap without first checking if it's full.
333    pub unsafe fn push_unchecked(&mut self, item: T) {
334        let old_len = self.len();
335        self.data.push_unchecked(item);
336        self.sift_up(0, old_len);
337    }
338
339    /// Returns the underlying ```Vec<T,N>```. Order is arbitrary and time is O(1).
340    pub fn into_vec(self) -> Vec<T, N> {
341        self.data
342    }
343
344    /* Private API */
345    fn sift_down_to_bottom(&mut self, mut pos: usize) {
346        let end = self.len();
347        let start = pos;
348        unsafe {
349            let mut hole = Hole::new(self.data.as_mut_slice(), pos);
350            let mut child = 2 * pos + 1;
351            while child < end {
352                let right = child + 1;
353                // compare with the greater of the two children
354                if right < end && hole.get(child).cmp(hole.get(right)) != K::ordering() {
355                    child = right;
356                }
357                hole.move_to(child);
358                child = 2 * hole.pos() + 1;
359            }
360            pos = hole.pos;
361        }
362        self.sift_up(start, pos);
363    }
364
365    fn sift_up(&mut self, start: usize, pos: usize) -> usize {
366        unsafe {
367            // Take out the value at `pos` and create a hole.
368            let mut hole = Hole::new(self.data.as_mut_slice(), pos);
369
370            while hole.pos() > start {
371                let parent = (hole.pos() - 1) / 2;
372                if hole.element().cmp(hole.get(parent)) != K::ordering() {
373                    break;
374                }
375                hole.move_to(parent);
376            }
377            hole.pos()
378        }
379    }
380}
381
382/// Hole represents a hole in a slice i.e. an index without valid value
383/// (because it was moved from or duplicated).
384/// In drop, `Hole` will restore the slice by filling the hole
385/// position with the value that was originally removed.
386struct Hole<'a, T> {
387    data: &'a mut [T],
388    /// `elt` is always `Some` from new until drop.
389    elt: ManuallyDrop<T>,
390    pos: usize,
391}
392
393impl<'a, T> Hole<'a, T> {
394    /// Create a new Hole at index `pos`.
395    ///
396    /// Unsafe because pos must be within the data slice.
397    #[inline]
398    unsafe fn new(data: &'a mut [T], pos: usize) -> Self {
399        debug_assert!(pos < data.len());
400        let elt = ptr::read(data.get_unchecked(pos));
401        Hole {
402            data,
403            elt: ManuallyDrop::new(elt),
404            pos,
405        }
406    }
407
408    #[inline]
409    fn pos(&self) -> usize {
410        self.pos
411    }
412
413    /// Returns a reference to the element removed.
414    #[inline]
415    fn element(&self) -> &T {
416        &self.elt
417    }
418
419    /// Returns a reference to the element at `index`.
420    ///
421    /// Unsafe because index must be within the data slice and not equal to pos.
422    #[inline]
423    unsafe fn get(&self, index: usize) -> &T {
424        debug_assert!(index != self.pos);
425        debug_assert!(index < self.data.len());
426        self.data.get_unchecked(index)
427    }
428
429    /// Move hole to new location
430    ///
431    /// Unsafe because index must be within the data slice and not equal to pos.
432    #[inline]
433    unsafe fn move_to(&mut self, index: usize) {
434        debug_assert!(index != self.pos);
435        debug_assert!(index < self.data.len());
436        let ptr = self.data.as_mut_ptr();
437        let index_ptr: *const _ = ptr.add(index);
438        let hole_ptr = ptr.add(self.pos);
439        ptr::copy_nonoverlapping(index_ptr, hole_ptr, 1);
440        self.pos = index;
441    }
442}
443
444/// Structure wrapping a mutable reference to the greatest item on a
445/// `BinaryHeap`.
446///
447/// This `struct` is created by [`BinaryHeap::peek_mut`].
448/// See its documentation for more.
449pub struct PeekMut<'a, T, K, const N: usize>
450where
451    T: Ord,
452    K: Kind,
453{
454    heap: &'a mut BinaryHeap<T, K, N>,
455    sift: bool,
456}
457
458impl<T, K, const N: usize> Drop for PeekMut<'_, T, K, N>
459where
460    T: Ord,
461    K: Kind,
462{
463    fn drop(&mut self) {
464        if self.sift {
465            self.heap.sift_down_to_bottom(0);
466        }
467    }
468}
469
470impl<T, K, const N: usize> Deref for PeekMut<'_, T, K, N>
471where
472    T: Ord,
473    K: Kind,
474{
475    type Target = T;
476    fn deref(&self) -> &T {
477        debug_assert!(!self.heap.is_empty());
478        // SAFE: PeekMut is only instantiated for non-empty heaps
479        unsafe { self.heap.data.as_slice().get_unchecked(0) }
480    }
481}
482
483impl<T, K, const N: usize> DerefMut for PeekMut<'_, T, K, N>
484where
485    T: Ord,
486    K: Kind,
487{
488    fn deref_mut(&mut self) -> &mut T {
489        debug_assert!(!self.heap.is_empty());
490        // SAFE: PeekMut is only instantiated for non-empty heaps
491        unsafe { self.heap.data.as_mut_slice().get_unchecked_mut(0) }
492    }
493}
494
495impl<'a, T, K, const N: usize> PeekMut<'a, T, K, N>
496where
497    T: Ord,
498    K: Kind,
499{
500    /// Removes the peeked value from the heap and returns it.
501    pub fn pop(mut this: PeekMut<'a, T, K, N>) -> T {
502        let value = this.heap.pop().unwrap();
503        this.sift = false;
504        value
505    }
506}
507
508impl<'a, T> Drop for Hole<'a, T> {
509    #[inline]
510    fn drop(&mut self) {
511        // fill the hole again
512        unsafe {
513            let pos = self.pos;
514            ptr::write(self.data.get_unchecked_mut(pos), ptr::read(&*self.elt));
515        }
516    }
517}
518
519impl<T, K, const N: usize> Default for BinaryHeap<T, K, N>
520where
521    T: Ord,
522    K: Kind,
523{
524    fn default() -> Self {
525        Self::new()
526    }
527}
528
529impl<T, K, const N: usize> Clone for BinaryHeap<T, K, N>
530where
531    K: Kind,
532    T: Ord + Clone,
533{
534    fn clone(&self) -> Self {
535        Self {
536            _kind: self._kind,
537            data: self.data.clone(),
538        }
539    }
540}
541
542impl<T, K, const N: usize> fmt::Debug for BinaryHeap<T, K, N>
543where
544    K: Kind,
545    T: Ord + fmt::Debug,
546{
547    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
548        f.debug_list().entries(self.iter()).finish()
549    }
550}
551
552impl<'a, T, K, const N: usize> IntoIterator for &'a BinaryHeap<T, K, N>
553where
554    K: Kind,
555    T: Ord,
556{
557    type Item = &'a T;
558    type IntoIter = slice::Iter<'a, T>;
559
560    fn into_iter(self) -> Self::IntoIter {
561        self.iter()
562    }
563}
564
565#[cfg(test)]
566mod tests {
567    use std::vec::Vec;
568
569    use crate::binary_heap::{BinaryHeap, Max, Min};
570
571    #[test]
572    fn static_new() {
573        static mut _B: BinaryHeap<i32, Min, 16> = BinaryHeap::new();
574    }
575
576    #[test]
577    fn drop() {
578        droppable!();
579
580        {
581            let mut v: BinaryHeap<Droppable, Max, 2> = BinaryHeap::new();
582            v.push(Droppable::new()).ok().unwrap();
583            v.push(Droppable::new()).ok().unwrap();
584            v.pop().unwrap();
585        }
586
587        assert_eq!(Droppable::count(), 0);
588
589        {
590            let mut v: BinaryHeap<Droppable, Max, 2> = BinaryHeap::new();
591            v.push(Droppable::new()).ok().unwrap();
592            v.push(Droppable::new()).ok().unwrap();
593        }
594
595        assert_eq!(Droppable::count(), 0);
596
597        {
598            let mut v: BinaryHeap<Droppable, Min, 2> = BinaryHeap::new();
599            v.push(Droppable::new()).ok().unwrap();
600            v.push(Droppable::new()).ok().unwrap();
601            v.pop().unwrap();
602        }
603
604        assert_eq!(Droppable::count(), 0);
605
606        {
607            let mut v: BinaryHeap<Droppable, Min, 2> = BinaryHeap::new();
608            v.push(Droppable::new()).ok().unwrap();
609            v.push(Droppable::new()).ok().unwrap();
610        }
611
612        assert_eq!(Droppable::count(), 0);
613    }
614
615    #[test]
616    fn into_vec() {
617        droppable!();
618
619        let mut h: BinaryHeap<Droppable, Max, 2> = BinaryHeap::new();
620        h.push(Droppable::new()).ok().unwrap();
621        h.push(Droppable::new()).ok().unwrap();
622        h.pop().unwrap();
623
624        assert_eq!(Droppable::count(), 1);
625
626        let v = h.into_vec();
627
628        assert_eq!(Droppable::count(), 1);
629
630        core::mem::drop(v);
631
632        assert_eq!(Droppable::count(), 0);
633    }
634
635    #[test]
636    fn min() {
637        let mut heap = BinaryHeap::<_, Min, 16>::new();
638        heap.push(1).unwrap();
639        heap.push(2).unwrap();
640        heap.push(3).unwrap();
641        heap.push(17).unwrap();
642        heap.push(19).unwrap();
643        heap.push(36).unwrap();
644        heap.push(7).unwrap();
645        heap.push(25).unwrap();
646        heap.push(100).unwrap();
647
648        assert_eq!(
649            heap.iter().cloned().collect::<Vec<_>>(),
650            [1, 2, 3, 17, 19, 36, 7, 25, 100]
651        );
652
653        assert_eq!(heap.pop(), Some(1));
654
655        assert_eq!(
656            heap.iter().cloned().collect::<Vec<_>>(),
657            [2, 17, 3, 25, 19, 36, 7, 100]
658        );
659
660        assert_eq!(heap.pop(), Some(2));
661        assert_eq!(heap.pop(), Some(3));
662        assert_eq!(heap.pop(), Some(7));
663        assert_eq!(heap.pop(), Some(17));
664        assert_eq!(heap.pop(), Some(19));
665        assert_eq!(heap.pop(), Some(25));
666        assert_eq!(heap.pop(), Some(36));
667        assert_eq!(heap.pop(), Some(100));
668        assert_eq!(heap.pop(), None);
669
670        assert!(heap.peek_mut().is_none());
671
672        heap.push(1).unwrap();
673        heap.push(2).unwrap();
674        heap.push(10).unwrap();
675
676        {
677            let mut val = heap.peek_mut().unwrap();
678            *val = 7;
679        }
680
681        assert_eq!(heap.pop(), Some(2));
682        assert_eq!(heap.pop(), Some(7));
683        assert_eq!(heap.pop(), Some(10));
684        assert_eq!(heap.pop(), None);
685    }
686
687    #[test]
688    fn max() {
689        let mut heap = BinaryHeap::<_, Max, 16>::new();
690        heap.push(1).unwrap();
691        heap.push(2).unwrap();
692        heap.push(3).unwrap();
693        heap.push(17).unwrap();
694        heap.push(19).unwrap();
695        heap.push(36).unwrap();
696        heap.push(7).unwrap();
697        heap.push(25).unwrap();
698        heap.push(100).unwrap();
699
700        assert_eq!(
701            heap.iter().cloned().collect::<Vec<_>>(),
702            [100, 36, 19, 25, 3, 2, 7, 1, 17]
703        );
704
705        assert_eq!(heap.pop(), Some(100));
706
707        assert_eq!(
708            heap.iter().cloned().collect::<Vec<_>>(),
709            [36, 25, 19, 17, 3, 2, 7, 1]
710        );
711
712        assert_eq!(heap.pop(), Some(36));
713        assert_eq!(heap.pop(), Some(25));
714        assert_eq!(heap.pop(), Some(19));
715        assert_eq!(heap.pop(), Some(17));
716        assert_eq!(heap.pop(), Some(7));
717        assert_eq!(heap.pop(), Some(3));
718        assert_eq!(heap.pop(), Some(2));
719        assert_eq!(heap.pop(), Some(1));
720        assert_eq!(heap.pop(), None);
721
722        assert!(heap.peek_mut().is_none());
723
724        heap.push(1).unwrap();
725        heap.push(9).unwrap();
726        heap.push(10).unwrap();
727
728        {
729            let mut val = heap.peek_mut().unwrap();
730            *val = 7;
731        }
732
733        assert_eq!(heap.pop(), Some(9));
734        assert_eq!(heap.pop(), Some(7));
735        assert_eq!(heap.pop(), Some(1));
736        assert_eq!(heap.pop(), None);
737    }
738}