priority_queue/priority_queue/
mod.rs

1/*
2 *  Copyright 2017 Gianmarco Garrisi
3 *
4 *
5 *  This program is free software: you can redistribute it and/or modify
6 *  it under the terms of the GNU Lesser General Public License as published by
7 *  the Free Software Foundation, either version 3 of the License, or
8 *  (at your option) any later version, or (at your option) under the terms
9 *  of the Mozilla Public License version 2.0.
10 *
11 *  ----
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *  GNU Lesser General Public License for more details.
17 *
18 *  You should have received a copy of the GNU Lesser General Public License
19 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 *
21 *  ----
22 *
23 *  This Source Code Form is subject to the terms of the Mozilla Public License,
24 *  v. 2.0. If a copy of the MPL was not distributed with this file, You can
25 *  obtain one at http://mozilla.org/MPL/2.0/.
26 *
27 */
28
29//! This module contains the [`PriorityQueue`] type and the related iterators.
30//!
31//! See the type level documentation for more details and examples.
32
33pub mod iterators;
34
35#[cfg(not(feature = "std"))]
36use std::vec::Vec;
37
38use crate::core_iterators::*;
39use crate::store::{Index, Position, Store};
40use crate::TryReserveError;
41use iterators::*;
42
43use std::borrow::Borrow;
44use std::cmp::{Eq, Ord};
45#[cfg(feature = "std")]
46use std::collections::hash_map::RandomState;
47use std::hash::{BuildHasher, Hash};
48use std::iter::{Extend, FromIterator, IntoIterator, Iterator};
49use std::mem::replace;
50
51/// A priority queue with efficient change function to change the priority of an
52/// element.
53///
54/// The priority is of type `P`, that must implement `std::cmp::Ord`.
55///
56/// The item is of type `I`, that must implement `Hash` and `Eq`.
57///
58/// Implemented as a heap of indexes, stores the items inside an `IndexMap`
59/// to be able to retrieve them quickly.
60///
61/// # Example
62/// ```rust
63/// use priority_queue::PriorityQueue;
64///
65/// let mut pq = PriorityQueue::new();
66///
67/// assert!(pq.is_empty());
68/// pq.push("Apples", 5);
69/// pq.push("Bananas", 8);
70/// pq.push("Strawberries", 23);
71///
72/// assert_eq!(pq.peek(), Some((&"Strawberries", &23)));
73///
74/// pq.change_priority("Bananas", 25);
75/// assert_eq!(pq.peek(), Some((&"Bananas", &25)));
76///
77/// for (item, _) in pq.into_sorted_iter() {
78///     println!("{}", item);
79/// }
80/// ```
81#[derive(Clone, Debug)]
82#[cfg(feature = "std")]
83pub struct PriorityQueue<I, P, H = RandomState> {
84    pub(crate) store: Store<I, P, H>,
85}
86
87#[derive(Clone, Debug)]
88#[cfg(not(feature = "std"))]
89pub struct PriorityQueue<I, P, H> {
90    pub(crate) store: Store<I, P, H>,
91}
92
93// do not [derive(Eq)] to loosen up trait requirements for other types and impls
94impl<I, P, H> Eq for PriorityQueue<I, P, H>
95where
96    I: Hash + Eq,
97    P: Ord,
98    H: BuildHasher,
99{
100}
101
102impl<I, P, H> Default for PriorityQueue<I, P, H>
103where
104    I: Hash + Eq,
105    P: Ord,
106    H: BuildHasher + Default,
107{
108    fn default() -> Self {
109        Self::with_default_hasher()
110    }
111}
112
113#[cfg(feature = "std")]
114impl<I, P> PriorityQueue<I, P>
115where
116    P: Ord,
117    I: Hash + Eq,
118{
119    /// Creates an empty `PriorityQueue`
120    pub fn new() -> Self {
121        Self::with_capacity(0)
122    }
123
124    /// Creates an empty `PriorityQueue` with the specified capacity.
125    pub fn with_capacity(capacity: usize) -> Self {
126        Self::with_capacity_and_default_hasher(capacity)
127    }
128}
129
130impl<I, P, H> PriorityQueue<I, P, H>
131where
132    P: Ord,
133    I: Hash + Eq,
134    H: BuildHasher + Default,
135{
136    /// Creates an empty `PriorityQueue` with the default hasher
137    pub fn with_default_hasher() -> Self {
138        Self::with_capacity_and_default_hasher(0)
139    }
140
141    /// Creates an empty `PriorityQueue` with the specified capacity and default hasher
142    pub fn with_capacity_and_default_hasher(capacity: usize) -> Self {
143        Self::with_capacity_and_hasher(capacity, H::default())
144    }
145}
146
147impl<I, P, H> PriorityQueue<I, P, H>
148where
149    P: Ord,
150    I: Hash + Eq,
151    H: BuildHasher,
152{
153    /// Creates an empty `PriorityQueue` with the specified hasher
154    pub fn with_hasher(hash_builder: H) -> Self {
155        Self::with_capacity_and_hasher(0, hash_builder)
156    }
157
158    /// Creates an empty `PriorityQueue` with the specified capacity and hasher
159    ///
160    /// The internal collections will be able to hold at least `capacity`
161    /// elements without reallocating.
162    /// If `capacity` is 0, there will be no allocation.
163    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: H) -> Self {
164        Self {
165            store: Store::with_capacity_and_hasher(capacity, hash_builder),
166        }
167    }
168}
169
170impl<I, P, H> PriorityQueue<I, P, H> {
171    /// Returns an iterator in arbitrary order over the
172    /// `(item, priority)` elements in the queue
173    pub fn iter(&self) -> Iter<I, P> {
174        self.store.iter()
175    }
176
177    /// Shrinks the capacity of the internal data structures
178    /// that support this operation as much as possible.
179    pub fn shrink_to_fit(&mut self) {
180        self.store.shrink_to_fit();
181    }
182
183    /// Clears the `PriorityQueue`, returning an iterator over the removed elements in arbitrary order.
184    /// If the iterator is dropped before being fully consumed, it drops the remaining elements in arbitrary order.
185    pub fn drain(&mut self) -> Drain<I, P> {
186        self.store.drain()
187    }
188
189    /// Returns the couple `(item, priority)` with the greatest
190    /// priority in the queue, or `None` if it is empty.
191    ///
192    /// Computes in **O(1)** time
193    pub fn peek(&self) -> Option<(&I, &P)> {
194        self.store
195            .heap
196            .first()
197            .and_then(|index| self.store.map.get_index(index.0))
198    }
199
200    /// Returns the number of elements the internal map can hold without
201    /// reallocating.
202    ///
203    /// This number is a lower bound; the map might be able to hold more,
204    /// but is guaranteed to be able to hold at least this many.
205    pub fn capacity(&self) -> usize {
206        self.store.capacity()
207    }
208
209    /// Returns the number of elements in the priority queue.
210    #[inline]
211    pub fn len(&self) -> usize {
212        self.store.len()
213    }
214
215    /// Returns `true` if the priority queue contains no elements.
216    pub fn is_empty(&self) -> bool {
217        self.store.is_empty()
218    }
219
220    /// Returns the items not ordered
221    pub fn into_vec(self) -> Vec<I> {
222        self.store.into_vec()
223    }
224
225    /// Drops all items from the priority queue
226    pub fn clear(&mut self) {
227        self.store.clear();
228    }
229
230    /// Reserves capacity for at least `additional` more elements to be inserted
231    /// in the given `PriorityQueue`. The collection may reserve more space to avoid
232    /// frequent reallocations. After calling `reserve`, capacity will be
233    /// greater than or equal to `self.len() + additional`. Does nothing if
234    /// capacity is already sufficient.
235    ///
236    /// # Panics
237    ///
238    /// Panics if the new capacity overflows `usize`.
239    pub fn reserve(&mut self, additional: usize) {
240        self.store.reserve(additional);
241    }
242
243    /// Reserve capacity for `additional` more elements, without over-allocating.
244    ///
245    /// Unlike `reserve`, this does not deliberately over-allocate the entry capacity to avoid
246    /// frequent re-allocations. However, the underlying data structures may still have internal
247    /// capacity requirements, and the allocator itself may give more space than requested, so this
248    /// cannot be relied upon to be precisely minimal.
249    ///
250    /// Computes in **O(n)** time.
251    pub fn reserve_exact(&mut self, additional: usize) {
252        self.store.reserve_exact(additional);
253    }
254
255    /// Try to reserve capacity for at least `additional` more elements.
256    ///
257    /// Computes in O(n) time.
258    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
259        self.store.try_reserve(additional)
260    }
261
262    /// Try to reserve capacity for `additional` more elements, without over-allocating.
263    ///
264    /// Unlike `reserve`, this does not deliberately over-allocate the entry capacity to avoid
265    /// frequent re-allocations. However, the underlying data structures may still have internal
266    /// capacity requirements, and the allocator itself may give more space than requested, so this
267    /// cannot be relied upon to be precisely minimal.
268    ///
269    /// Computes in **O(n)** time.
270    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
271        self.store.try_reserve_exact(additional)
272    }
273}
274
275impl<I, P, H> PriorityQueue<I, P, H>
276where
277    P: Ord,
278{
279    /// Returns an iterator in arbitrary order over the
280    /// `(item, priority)` elements in the queue.
281    ///
282    /// The item and the priority are mutable references, but it's a logic error
283    /// to modify the item in a way that change the result of `Hash` or `Eq`.
284    ///
285    /// It's *not* an error, instead, to modify the priorities, because the heap
286    /// will be rebuilt once the `IterMut` goes out of scope.
287    ///
288    /// It would be rebuilt even if no priority value would have been modified,
289    /// but the procedure will not move anything, but just compare the priorities.
290    pub fn iter_mut(&mut self) -> IterMut<I, P, H> {
291        IterMut::new(self)
292    }
293
294    /// Removes the item with the greatest priority from
295    /// the priority queue and returns the pair `(item, priority)`,
296    /// or `None` if the queue is empty.
297    pub fn pop(&mut self) -> Option<(I, P)> {
298        match self.len() {
299            0 => None,
300            1 => self.store.swap_remove(Position(0)),
301            _ => {
302                let r = self.store.swap_remove(Position(0));
303                self.heapify(Position(0));
304                r
305            }
306        }
307    }
308
309    /// Implements a heap sort.
310    ///
311    /// Returns a `Vec<I>` sorted from the item associated to the highest priority to the lowest.
312    pub fn into_sorted_vec(mut self) -> Vec<I> {
313        let mut res = Vec::with_capacity(self.store.size);
314        while let Some((i, _)) = self.pop() {
315            res.push(i);
316        }
317        res
318    }
319
320    /// Generates a new iterator from `self` that
321    /// will extract the elements from the one with the highest priority
322    /// to the lowest one.
323    pub fn into_sorted_iter(self) -> IntoSortedIter<I, P, H> {
324        IntoSortedIter { pq: self }
325    }
326}
327
328impl<I, P, H> PriorityQueue<I, P, H>
329where
330    P: Ord,
331    I: Hash + Eq,
332    H: BuildHasher,
333{
334    /// Retains only the elements specified by the `predicate`.
335    ///
336    /// In other words, remove all elements e for which `predicate(&i, &p)` returns `false`.
337    /// The elements are visited in arbitrary order.
338    pub fn retain<F>(&mut self, predicate: F)
339    where
340        F: FnMut(&I, &P) -> bool,
341    {
342        self.store.retain(predicate);
343        self.heap_build();
344    }
345
346    /// Retains only the elements specified by the `predicate`.
347    ///
348    /// In other words, remove all elements e for which `predicate(&mut i, &mut p)` returns `false`.
349    /// The elements are visited in arbitrary order.
350    ///
351    /// The `predicate` receives mutable references to both the item and
352    /// the priority.
353    ///
354    /// It's a logical error to change the item in a way
355    /// that changes the result of `Hash` or `Eq`.
356    ///
357    /// The `predicate` can change the priority. If the element is retained,
358    /// it will have the updated one.
359    pub fn retain_mut<F>(&mut self, predicate: F)
360    where
361        F: FnMut(&mut I, &mut P) -> bool,
362    {
363        self.store.retain_mut(predicate);
364        self.heap_build();
365    }
366
367    /// Returns an `Iterator` removing from the queue the `(item, priority)`
368    /// pairs for which the `predicate` returns `true`, in arbitraty order.
369    ///
370    /// The `predicate` receives mutable references to both the item and
371    /// the priority.
372    ///
373    /// It's a logical error to change the item in a way
374    /// that changes the result of `Hash` or `Eq`.
375    ///
376    /// The `predicate` can change the priority. If it returns `true`, the
377    /// extracted pair will have the updated priority, otherwise, the
378    /// heap structural property will be restored once the iterator is `Drop`ped.
379    ///
380    /// # Example
381    /// ```
382    /// # use priority_queue::PriorityQueue;
383    /// let mut pq = PriorityQueue::new();
384    ///
385    /// pq.push("Apples", 5);
386    /// pq.push("Bananas", 10);
387    ///
388    /// assert_eq!(pq.extract_if(|i, p| {
389    ///   *p = 15;
390    ///   i == &"Apples"
391    /// }).collect::<Vec<_>>(), vec![("Apples", 15)]);
392    ///
393    /// assert_eq!(pq.peek(), Some((&"Bananas", &15)));
394    /// assert_eq!(pq.into_vec(), vec!["Bananas"]);
395    /// ```
396    pub fn extract_if<F>(&mut self, predicate: F) -> ExtractIf<I, P, F, H>
397    where
398        F: FnMut(&mut I, &mut P) -> bool,
399    {
400        ExtractIf::new(self, predicate)
401    }
402
403    /// Removes the item with the greatest priority from
404    /// the priority queue if the `predicate` returns `true`.
405    ///
406    /// Returns the pair `(item, priority)`, or `None` if the
407    /// queue is empty or the `predicate` returns `false`.
408    ///
409    /// The `predicate` receives mutable references to both the item
410    /// and the priority.
411    ///
412    /// It's a logical error to change the item in a way
413    /// that changes the result of `Hash` or `Eq`.
414    ///
415    /// The `predicate` can change the priority. If it returns `true`,
416    /// the returned couple will have the updated priority,
417    /// otherwise, the heap structural property will be restored.
418    ///
419    /// # Example
420    /// ```
421    /// # use priority_queue::PriorityQueue;
422    /// let mut pq = PriorityQueue::new();
423    ///
424    /// pq.push("Apples", 5);
425    /// pq.push("Bananas", 10);
426    ///
427    /// assert_eq!(pq.pop_if(|i, p| {
428    ///   *p = 3;
429    ///   false
430    /// }), None);
431    ///
432    /// assert_eq!(pq.pop(), Some(("Apples", 5)));
433    /// ```
434    pub fn pop_if<F>(&mut self, predicate: F) -> Option<(I, P)>
435    where
436        F: FnOnce(&mut I, &mut P) -> bool,
437    {
438        match self.len() {
439            0 => None,
440            1 => self.store.swap_remove_if(Position(0), predicate),
441            _ => {
442                let r = self.store.swap_remove_if(Position(0), predicate);
443                self.heapify(Position(0));
444                r
445            }
446        }
447    }
448
449    /// Insert the `(item, priority)` pair into the queue.
450    ///
451    /// If an element equal to `item` is already in the queue, its priority
452    /// is updated and the old priority is returned in `Some`; otherwise,
453    /// `item` is inserted with `priority` and `None` is returned.
454    ///
455    /// # Example
456    /// ```
457    /// # use priority_queue::PriorityQueue;
458    /// let mut pq = PriorityQueue::new();
459    /// assert_eq!(pq.push("Apples", 5), None);
460    /// assert_eq!(pq.get_priority("Apples"), Some(&5));
461    /// assert_eq!(pq.push("Apples", 6), Some(5));
462    /// assert_eq!(pq.get_priority("Apples"), Some(&6));
463    /// assert_eq!(pq.push("Apples", 4), Some(6));
464    /// assert_eq!(pq.get_priority("Apples"), Some(&4));
465    /// ```
466    ///
467    /// Computes in **O(log(N))** time.
468    pub fn push(&mut self, item: I, priority: P) -> Option<P> {
469        use indexmap::map::Entry::*;
470        let mut pos = Position(0);
471        let mut oldp = None;
472
473        match self.store.map.entry(item) {
474            Occupied(mut e) => {
475                oldp = Some(replace(e.get_mut(), priority));
476                pos = unsafe { *self.store.qp.get_unchecked(e.index()) };
477            }
478            Vacant(e) => {
479                e.insert(priority);
480            }
481        }
482
483        if oldp.is_some() {
484            self.up_heapify(pos);
485            return oldp;
486        }
487        // copy the current size of the heap
488        let i = self.len();
489        // add the new element in the qp vector as the last in the heap
490        self.store.qp.push(Position(i));
491        self.store.heap.push(Index(i));
492        self.bubble_up(Position(i), Index(i));
493        self.store.size += 1;
494        None
495    }
496
497    /// Increase the priority of an existing item in the queue, or
498    /// insert it if not present.
499    ///
500    /// If an element equal to `item` is already in the queue with a
501    /// lower priority, its priority is increased to the new one
502    /// without replacing the element and the old priority is returned
503    /// in `Some`.
504    ///
505    /// If an element equal to `item` is already in the queue with an
506    /// equal or higher priority, its priority is not changed and the
507    /// `priority` argument is returned in `Some`.
508    ///
509    /// If no element equal to `item` is already in the queue, the new
510    /// element is inserted and `None` is returned.
511    ///
512    /// # Example
513    /// ```
514    /// # use priority_queue::PriorityQueue;
515    /// let mut pq = PriorityQueue::new();
516    /// assert_eq!(pq.push_increase("Apples", 5), None);
517    /// assert_eq!(pq.get_priority("Apples"), Some(&5));
518    /// assert_eq!(pq.push_increase("Apples", 6), Some(5));
519    /// assert_eq!(pq.get_priority("Apples"), Some(&6));
520    /// // Already present with higher priority, so requested (lower)
521    /// // priority is returned.
522    /// assert_eq!(pq.push_increase("Apples", 4), Some(4));
523    /// assert_eq!(pq.get_priority("Apples"), Some(&6));
524    /// ```
525    ///
526    /// Computes in **O(log(N))** time.
527    pub fn push_increase(&mut self, item: I, priority: P) -> Option<P> {
528        if self.get_priority(&item).map_or(true, |p| priority > *p) {
529            self.push(item, priority)
530        } else {
531            Some(priority)
532        }
533    }
534
535    /// Decrease the priority of an existing item in the queue, or
536    /// insert it if not present.
537    ///
538    /// If an element equal to `item` is already in the queue with a
539    /// higher priority, its priority is decreased to the new one
540    /// without replacing the element and the old priority is returned
541    /// in `Some`.
542    ///
543    /// If an element equal to `item` is already in the queue with an
544    /// equal or lower priority, its priority is not changed and the
545    /// `priority` argument is returned in `Some`.
546    ///
547    /// If no element equal to `item` is already in the queue, the new
548    /// element is inserted and `None` is returned.
549    ///
550    /// # Example
551    /// ```
552    /// # use priority_queue::PriorityQueue;
553    /// let mut pq = PriorityQueue::new();
554    /// assert_eq!(pq.push_decrease("Apples", 5), None);
555    /// assert_eq!(pq.get_priority("Apples"), Some(&5));
556    /// assert_eq!(pq.push_decrease("Apples", 4), Some(5));
557    /// assert_eq!(pq.get_priority("Apples"), Some(&4));
558    /// // Already present with lower priority, so requested (higher)
559    /// // priority is returned.
560    /// assert_eq!(pq.push_decrease("Apples", 6), Some(6));
561    /// assert_eq!(pq.get_priority("Apples"), Some(&4));
562    /// ```
563    ///
564    /// Computes in **O(log(N))** time.
565    pub fn push_decrease(&mut self, item: I, priority: P) -> Option<P> {
566        if self.get_priority(&item).map_or(true, |p| priority < *p) {
567            self.push(item, priority)
568        } else {
569            Some(priority)
570        }
571    }
572
573    /// Change the priority of an item returning the old value of priority,
574    /// or `None` if the item wasn't in the queue.
575    ///
576    /// The argument `item` is only used for lookup, and is not used to overwrite the item's data
577    /// in the priority queue.
578    ///
579    /// # Example
580    /// ```
581    /// # use priority_queue::PriorityQueue;
582    /// let mut pq = PriorityQueue::new();
583    /// assert_eq!(pq.change_priority("Apples", 5), None);
584    /// assert_eq!(pq.get_priority("Apples"), None);
585    /// assert_eq!(pq.push("Apples", 6), None);
586    /// assert_eq!(pq.get_priority("Apples"), Some(&6));
587    /// assert_eq!(pq.change_priority("Apples", 4), Some(6));
588    /// assert_eq!(pq.get_priority("Apples"), Some(&4));
589    /// ```
590    ///
591    /// The item is found in **O(1)** thanks to the hash table.
592    /// The operation is performed in **O(log(N))** time.
593    pub fn change_priority<Q>(&mut self, item: &Q, new_priority: P) -> Option<P>
594    where
595        I: Borrow<Q>,
596        Q: Eq + Hash + ?Sized,
597    {
598        self.store
599            .change_priority(item, new_priority)
600            .map(|(r, pos)| {
601                self.up_heapify(pos);
602                r
603            })
604    }
605
606    /// Change the priority of an item using the provided function.
607    ///
608    /// Returns a boolean value where `true` means the item was in the queue and update was successful.
609    ///
610    /// The argument `item` is only used for lookup, and is not used to overwrite the item's data
611    /// in the priority queue.
612    ///
613    /// The item is found in **O(1)** thanks to the hash table.
614    /// The operation is performed in **O(log(N))** time (worst case).
615    pub fn change_priority_by<Q, F>(&mut self, item: &Q, priority_setter: F) -> bool
616    where
617        I: Borrow<Q>,
618        Q: Eq + Hash + ?Sized,
619        F: FnOnce(&mut P),
620    {
621        self.store
622            .change_priority_by(item, priority_setter)
623            .map(|pos| {
624                self.up_heapify(pos);
625            })
626            .is_some()
627    }
628
629    /// Get the priority of an item, or `None`, if the item is not in the queue
630    pub fn get_priority<Q>(&self, item: &Q) -> Option<&P>
631    where
632        I: Borrow<Q>,
633        Q: Eq + Hash + ?Sized,
634    {
635        self.store.get_priority(item)
636    }
637
638    /// Check if the queue contains `item`.
639    ///
640    /// Returns `true` if `item` is in the queue, `false` if it is not.
641    pub fn contains<Q>(&self, item: &Q) -> bool
642    where
643        I: Borrow<Q>,
644        Q: Eq + Hash + ?Sized,
645    {
646        self.store.contains(item)
647    }
648
649    /// Get the couple `(item, priority)` of an arbitrary element, as reference
650    /// or `None` if the item is not in the queue.
651    pub fn get<Q>(&self, item: &Q) -> Option<(&I, &P)>
652    where
653        I: Borrow<Q>,
654        Q: Eq + Hash + ?Sized,
655    {
656        self.store.get(item)
657    }
658
659    /// Get the couple `(item, priority)` of an arbitrary element, or `None`
660    /// if the item was not in the queue.
661    ///
662    /// The item is a mutable reference, but it's a logic error to modify it
663    /// in a way that change the result of  `Hash` or `Eq`.
664    ///
665    /// The priority cannot be modified with a call to this function.
666    /// To modify the priority use [`push`](PriorityQueue::push),
667    /// [`change_priority`](PriorityQueue::change_priority) or
668    /// [`change_priority_by`](PriorityQueue::change_priority_by).
669    pub fn get_mut<Q>(&mut self, item: &Q) -> Option<(&mut I, &P)>
670    where
671        I: Borrow<Q>,
672        Q: Eq + Hash + ?Sized,
673    {
674        self.store.get_mut(item)
675    }
676
677    /// Returns the couple `(item, priority)` with the greatest
678    /// priority in the queue, or `None` if it is empty.
679    ///
680    /// The item is a mutable reference, but it's a logic error to modify it
681    /// in a way that change the result of  `Hash` or `Eq`.
682    ///
683    /// The priority cannot be modified with a call to this function.
684    /// To modify the priority use[`push`](PriorityQueue::push),
685    /// [`change_priority`](PriorityQueue::change_priority) or
686    /// [`change_priority_by`](PriorityQueue::change_priority_by).
687    ///
688    /// Computes in **O(1)** time
689    pub fn peek_mut(&mut self) -> Option<(&mut I, &P)> {
690        use indexmap::map::MutableKeys;
691        if self.store.size == 0 {
692            return None;
693        }
694        self.store
695            .map
696            .get_index_mut2(unsafe { self.store.heap.get_unchecked(0) }.0)
697            .map(|(k, v)| (k, &*v))
698    }
699
700    /// Remove an arbitrary element from the priority queue.
701    ///
702    /// Returns the `(item, priority)` couple or `None` if the item
703    /// is not found in the queue.
704    ///
705    /// The operation is performed in **O(log(N))** time (worst case).
706    pub fn remove<Q>(&mut self, item: &Q) -> Option<(I, P)>
707    where
708        I: Borrow<Q>,
709        Q: Eq + Hash + ?Sized,
710    {
711        self.store.remove(item).map(|(item, priority, pos)| {
712            if pos.0 < self.len() {
713                self.up_heapify(pos);
714            }
715
716            (item, priority)
717        })
718    }
719
720    /// Move all items of the `other` queue to `self`
721    /// ignoring the items Eq to elements already in `self`
722    /// At the end, `other` will be empty.
723    ///
724    /// **Note** that at the end, the priority of the duplicated elements
725    /// inside `self` may be the one of the elements in `other`,
726    /// if `other` is longer than `self`
727    pub fn append(&mut self, other: &mut Self) {
728        self.store.append(&mut other.store);
729        self.heap_build();
730    }
731}
732
733impl<I, P, H> PriorityQueue<I, P, H>
734where
735    P: Ord,
736    I: Hash + Eq,
737{
738}
739
740impl<I, P, H> PriorityQueue<I, P, H>
741where
742    P: Ord,
743{
744    /**************************************************************************/
745    /*                            internal functions                          */
746
747    /// Internal function that restores the functional property of the sub-heap rooted in `i`
748    ///
749    /// Computes in **O(log(N))** time
750    fn heapify(&mut self, mut i: Position) {
751        if self.len() <= 1 {
752            return;
753        }
754
755        let (mut l, mut r) = (left(i), right(i));
756        let mut largest = i;
757
758        let mut largestp = unsafe { self.store.get_priority_from_position(i) };
759        if l.0 < self.len() {
760            let childp = unsafe { self.store.get_priority_from_position(l) };
761            if childp > largestp {
762                largest = l;
763                largestp = childp;
764            }
765
766            if r.0 < self.len() && unsafe { self.store.get_priority_from_position(r) } > largestp {
767                largest = r;
768            }
769        }
770
771        while largest != i {
772            self.store.swap(i, largest);
773
774            i = largest;
775            let mut largestp = unsafe { self.store.get_priority_from_position(i) };
776            l = left(i);
777            if l.0 < self.len() {
778                let childp = unsafe { self.store.get_priority_from_position(l) };
779                if childp > largestp {
780                    largest = l;
781                    largestp = childp;
782                }
783
784                r = right(i);
785                if r.0 < self.len()
786                    && unsafe { self.store.get_priority_from_position(r) } > largestp
787                {
788                    largest = r;
789                }
790            }
791        }
792    }
793
794    /// from the leaf go up to root or until an element with priority greater
795    /// than the new element is found
796    fn bubble_up(&mut self, mut position: Position, map_position: Index) -> Position {
797        let priority = self.store.map.get_index(map_position.0).unwrap().1;
798        let mut parent_position = Position(0);
799        while if position.0 > 0 {
800            parent_position = parent(position);
801            (unsafe { self.store.get_priority_from_position(parent_position) }) < priority
802        } else {
803            false
804        } {
805            unsafe {
806                let parent_index = *self.store.heap.get_unchecked(parent_position.0);
807                *self.store.heap.get_unchecked_mut(position.0) = parent_index;
808                *self.store.qp.get_unchecked_mut(parent_index.0) = position;
809            }
810            position = parent_position;
811        }
812        unsafe {
813            *self.store.heap.get_unchecked_mut(position.0) = map_position;
814            *self.store.qp.get_unchecked_mut(map_position.0) = position;
815        }
816        position
817    }
818
819    /// Internal function that moves a leaf in position `i` to its correct place in the heap
820    /// and restores the functional property
821    ///
822    /// Computes in **O(log(N))**
823    fn up_heapify(&mut self, i: Position) {
824        let tmp = unsafe { *self.store.heap.get_unchecked(i.0) };
825        let pos = self.bubble_up(i, tmp);
826        self.heapify(pos)
827    }
828
829    /// Internal function that transform the `heap`
830    /// vector in a heap with its properties
831    ///
832    /// Computes in **O(N)**
833    pub(crate) fn heap_build(&mut self) {
834        if self.is_empty() {
835            return;
836        }
837        for i in (0..=parent(Position(self.len())).0).rev() {
838            self.heapify(Position(i));
839        }
840    }
841}
842
843//FIXME: fails when the vector contains repeated items
844// FIXED: repeated items ignored
845impl<I, P, H> From<Vec<(I, P)>> for PriorityQueue<I, P, H>
846where
847    I: Hash + Eq,
848    P: Ord,
849    H: BuildHasher + Default,
850{
851    fn from(vec: Vec<(I, P)>) -> Self {
852        let store = Store::from(vec);
853        let mut pq = PriorityQueue { store };
854        pq.heap_build();
855        pq
856    }
857}
858
859use crate::DoublePriorityQueue;
860
861impl<I, P, H> From<DoublePriorityQueue<I, P, H>> for PriorityQueue<I, P, H>
862where
863    I: Hash + Eq,
864    P: Ord,
865    H: BuildHasher,
866{
867    fn from(pq: DoublePriorityQueue<I, P, H>) -> Self {
868        let store = pq.store;
869        let mut this = Self { store };
870        this.heap_build();
871        this
872    }
873}
874
875//FIXME: fails when the iterator contains repeated items
876// FIXED: the item inside the pq is updated
877// so there are two functions with different behaviours.
878impl<I, P, H> FromIterator<(I, P)> for PriorityQueue<I, P, H>
879where
880    I: Hash + Eq,
881    P: Ord,
882    H: BuildHasher + Default,
883{
884    fn from_iter<IT>(iter: IT) -> Self
885    where
886        IT: IntoIterator<Item = (I, P)>,
887    {
888        let store = Store::from_iter(iter);
889        let mut pq = PriorityQueue { store };
890        pq.heap_build();
891        pq
892    }
893}
894
895impl<I, P, H> IntoIterator for PriorityQueue<I, P, H>
896where
897    I: Hash + Eq,
898    P: Ord,
899    H: BuildHasher,
900{
901    type Item = (I, P);
902    type IntoIter = IntoIter<I, P>;
903    fn into_iter(self) -> IntoIter<I, P> {
904        self.store.into_iter()
905    }
906}
907
908impl<'a, I, P, H> IntoIterator for &'a PriorityQueue<I, P, H>
909where
910    I: Hash + Eq,
911    P: Ord,
912    H: BuildHasher,
913{
914    type Item = (&'a I, &'a P);
915    type IntoIter = Iter<'a, I, P>;
916    fn into_iter(self) -> Iter<'a, I, P> {
917        self.store.iter()
918    }
919}
920
921impl<'a, I, P, H> IntoIterator for &'a mut PriorityQueue<I, P, H>
922where
923    I: Hash + Eq,
924    P: Ord,
925    H: BuildHasher,
926{
927    type Item = (&'a mut I, &'a mut P);
928    type IntoIter = IterMut<'a, I, P, H>;
929    fn into_iter(self) -> IterMut<'a, I, P, H> {
930        IterMut::new(self)
931    }
932}
933
934impl<I, P, H> Extend<(I, P)> for PriorityQueue<I, P, H>
935where
936    I: Hash + Eq,
937    P: Ord,
938    H: BuildHasher,
939{
940    fn extend<T: IntoIterator<Item = (I, P)>>(&mut self, iter: T) {
941        let iter = iter.into_iter();
942        let (min, max) = iter.size_hint();
943        let rebuild = if let Some(max) = max {
944            self.reserve(max);
945            better_to_rebuild(self.len(), max)
946        } else if min != 0 {
947            self.reserve(min);
948            better_to_rebuild(self.len(), min)
949        } else {
950            false
951        };
952        if rebuild {
953            self.store.extend(iter);
954            self.heap_build();
955        } else {
956            for (item, priority) in iter {
957                self.push(item, priority);
958            }
959        }
960    }
961}
962
963use std::cmp::PartialEq;
964
965impl<I, P1, H1, P2, H2> PartialEq<PriorityQueue<I, P2, H2>> for PriorityQueue<I, P1, H1>
966where
967    I: Hash + Eq,
968    P1: Ord,
969    P1: PartialEq<P2>,
970    Option<P1>: PartialEq<Option<P2>>,
971    P2: Ord,
972    H1: BuildHasher,
973    H2: BuildHasher,
974{
975    fn eq(&self, other: &PriorityQueue<I, P2, H2>) -> bool {
976        self.store == other.store
977    }
978}
979
980/// Compute the index of the left child of an item from its index
981#[inline(always)]
982const fn left(i: Position) -> Position {
983    Position((i.0 * 2) + 1)
984}
985/// Compute the index of the right child of an item from its index
986#[inline(always)]
987const fn right(i: Position) -> Position {
988    Position((i.0 * 2) + 2)
989}
990/// Compute the index of the parent element in the heap from its index
991#[inline(always)]
992const fn parent(i: Position) -> Position {
993    Position((i.0 - 1) / 2)
994}
995
996#[inline(always)]
997const fn log2_fast(x: usize) -> usize {
998    (usize::BITS - x.leading_zeros() - 1) as usize
999}
1000
1001// `rebuild` takes O(len1 + len2) operations
1002// and about 2 * (len1 + len2) comparisons in the worst case
1003// while `extend` takes O(len2 * log_2(len1)) operations
1004// and about 1 * len2 * log_2(len1) comparisons in the worst case,
1005// assuming len1 >= len2.
1006fn better_to_rebuild(len1: usize, len2: usize) -> bool {
1007    // log(1) == 0, so the inequation always falsy
1008    // log(0) is inapplicable and produces panic
1009    if len1 <= 1 {
1010        return false;
1011    }
1012
1013    2 * (len1 + len2) < len2 * log2_fast(len1)
1014}
1015
1016#[cfg(feature = "serde")]
1017#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
1018mod serde {
1019    use std::cmp::{Eq, Ord};
1020    use std::hash::{BuildHasher, Hash};
1021
1022    use serde::de::{Deserialize, Deserializer};
1023    use serde::ser::{Serialize, Serializer};
1024
1025    use super::PriorityQueue;
1026    use crate::store::Store;
1027
1028    impl<I, P, H> Serialize for PriorityQueue<I, P, H>
1029    where
1030        I: Hash + Eq + Serialize,
1031        P: Ord + Serialize,
1032        H: BuildHasher,
1033    {
1034        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1035        where
1036            S: Serializer,
1037        {
1038            self.store.serialize(serializer)
1039        }
1040    }
1041
1042    impl<'de, I, P, H> Deserialize<'de> for PriorityQueue<I, P, H>
1043    where
1044        I: Hash + Eq + Deserialize<'de>,
1045        P: Ord + Deserialize<'de>,
1046        H: BuildHasher + Default,
1047    {
1048        fn deserialize<D>(deserializer: D) -> Result<PriorityQueue<I, P, H>, D::Error>
1049        where
1050            D: Deserializer<'de>,
1051        {
1052            Store::deserialize(deserializer).map(|store| {
1053                let mut pq = PriorityQueue { store };
1054                pq.heap_build();
1055                pq
1056            })
1057        }
1058    }
1059}