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    /// Get the couple `(item, priority)` of an arbitrary element, as reference
639    /// or `None` if the item is not in the queue.
640    pub fn get<Q>(&self, item: &Q) -> Option<(&I, &P)>
641    where
642        I: Borrow<Q>,
643        Q: Eq + Hash + ?Sized,
644    {
645        self.store.get(item)
646    }
647
648    /// Get the couple `(item, priority)` of an arbitrary element, or `None`
649    /// if the item was not in the queue.
650    ///
651    /// The item is a mutable reference, but it's a logic error to modify it
652    /// in a way that change the result of  `Hash` or `Eq`.
653    ///
654    /// The priority cannot be modified with a call to this function.
655    /// To modify the priority use [`push`](PriorityQueue::push),
656    /// [`change_priority`](PriorityQueue::change_priority) or
657    /// [`change_priority_by`](PriorityQueue::change_priority_by).
658    pub fn get_mut<Q>(&mut self, item: &Q) -> Option<(&mut I, &P)>
659    where
660        I: Borrow<Q>,
661        Q: Eq + Hash + ?Sized,
662    {
663        self.store.get_mut(item)
664    }
665
666    /// Returns the couple `(item, priority)` with the greatest
667    /// priority in the queue, or `None` if it is empty.
668    ///
669    /// The item is a mutable reference, but it's a logic error to modify it
670    /// in a way that change the result of  `Hash` or `Eq`.
671    ///
672    /// The priority cannot be modified with a call to this function.
673    /// To modify the priority use[`push`](PriorityQueue::push),
674    /// [`change_priority`](PriorityQueue::change_priority) or
675    /// [`change_priority_by`](PriorityQueue::change_priority_by).
676    ///
677    /// Computes in **O(1)** time
678    pub fn peek_mut(&mut self) -> Option<(&mut I, &P)> {
679        use indexmap::map::MutableKeys;
680        if self.store.size == 0 {
681            return None;
682        }
683        self.store
684            .map
685            .get_index_mut2(unsafe { self.store.heap.get_unchecked(0) }.0)
686            .map(|(k, v)| (k, &*v))
687    }
688
689    /// Remove an arbitrary element from the priority queue.
690    ///
691    /// Returns the `(item, priority)` couple or `None` if the item
692    /// is not found in the queue.
693    ///
694    /// The operation is performed in **O(log(N))** time (worst case).
695    pub fn remove<Q>(&mut self, item: &Q) -> Option<(I, P)>
696    where
697        I: Borrow<Q>,
698        Q: Eq + Hash + ?Sized,
699    {
700        self.store.remove(item).map(|(item, priority, pos)| {
701            if pos.0 < self.len() {
702                self.up_heapify(pos);
703            }
704
705            (item, priority)
706        })
707    }
708
709    /// Move all items of the `other` queue to `self`
710    /// ignoring the items Eq to elements already in `self`
711    /// At the end, `other` will be empty.
712    ///
713    /// **Note** that at the end, the priority of the duplicated elements
714    /// inside `self` may be the one of the elements in `other`,
715    /// if `other` is longer than `self`
716    pub fn append(&mut self, other: &mut Self) {
717        self.store.append(&mut other.store);
718        self.heap_build();
719    }
720}
721
722impl<I, P, H> PriorityQueue<I, P, H>
723where
724    P: Ord,
725    I: Hash + Eq,
726{
727}
728
729impl<I, P, H> PriorityQueue<I, P, H>
730where
731    P: Ord,
732{
733    /**************************************************************************/
734    /*                            internal functions                          */
735
736    /// Internal function that restores the functional property of the sub-heap rooted in `i`
737    ///
738    /// Computes in **O(log(N))** time
739    fn heapify(&mut self, mut i: Position) {
740        if self.len() <= 1 {
741            return;
742        }
743
744        let (mut l, mut r) = (left(i), right(i));
745        let mut largest = i;
746
747        let mut largestp = unsafe { self.store.get_priority_from_position(i) };
748        if l.0 < self.len() {
749            let childp = unsafe { self.store.get_priority_from_position(l) };
750            if childp > largestp {
751                largest = l;
752                largestp = childp;
753            }
754
755            if r.0 < self.len() && unsafe { self.store.get_priority_from_position(r) } > largestp {
756                largest = r;
757            }
758        }
759
760        while largest != i {
761            self.store.swap(i, largest);
762
763            i = largest;
764            let mut largestp = unsafe { self.store.get_priority_from_position(i) };
765            l = left(i);
766            if l.0 < self.len() {
767                let childp = unsafe { self.store.get_priority_from_position(l) };
768                if childp > largestp {
769                    largest = l;
770                    largestp = childp;
771                }
772
773                r = right(i);
774                if r.0 < self.len()
775                    && unsafe { self.store.get_priority_from_position(r) } > largestp
776                {
777                    largest = r;
778                }
779            }
780        }
781    }
782
783    /// from the leaf go up to root or until an element with priority greater
784    /// than the new element is found
785    fn bubble_up(&mut self, mut position: Position, map_position: Index) -> Position {
786        let priority = self.store.map.get_index(map_position.0).unwrap().1;
787        let mut parent_position = Position(0);
788        while if position.0 > 0 {
789            parent_position = parent(position);
790            (unsafe { self.store.get_priority_from_position(parent_position) }) < priority
791        } else {
792            false
793        } {
794            unsafe {
795                let parent_index = *self.store.heap.get_unchecked(parent_position.0);
796                *self.store.heap.get_unchecked_mut(position.0) = parent_index;
797                *self.store.qp.get_unchecked_mut(parent_index.0) = position;
798            }
799            position = parent_position;
800        }
801        unsafe {
802            *self.store.heap.get_unchecked_mut(position.0) = map_position;
803            *self.store.qp.get_unchecked_mut(map_position.0) = position;
804        }
805        position
806    }
807
808    /// Internal function that moves a leaf in position `i` to its correct place in the heap
809    /// and restores the functional property
810    ///
811    /// Computes in **O(log(N))**
812    fn up_heapify(&mut self, i: Position) {
813        let tmp = unsafe { *self.store.heap.get_unchecked(i.0) };
814        let pos = self.bubble_up(i, tmp);
815        self.heapify(pos)
816    }
817
818    /// Internal function that transform the `heap`
819    /// vector in a heap with its properties
820    ///
821    /// Computes in **O(N)**
822    pub(crate) fn heap_build(&mut self) {
823        if self.is_empty() {
824            return;
825        }
826        for i in (0..=parent(Position(self.len())).0).rev() {
827            self.heapify(Position(i));
828        }
829    }
830}
831
832//FIXME: fails when the vector contains repeated items
833// FIXED: repeated items ignored
834impl<I, P, H> From<Vec<(I, P)>> for PriorityQueue<I, P, H>
835where
836    I: Hash + Eq,
837    P: Ord,
838    H: BuildHasher + Default,
839{
840    fn from(vec: Vec<(I, P)>) -> Self {
841        let store = Store::from(vec);
842        let mut pq = PriorityQueue { store };
843        pq.heap_build();
844        pq
845    }
846}
847
848use crate::DoublePriorityQueue;
849
850impl<I, P, H> From<DoublePriorityQueue<I, P, H>> for PriorityQueue<I, P, H>
851where
852    I: Hash + Eq,
853    P: Ord,
854    H: BuildHasher,
855{
856    fn from(pq: DoublePriorityQueue<I, P, H>) -> Self {
857        let store = pq.store;
858        let mut this = Self { store };
859        this.heap_build();
860        this
861    }
862}
863
864//FIXME: fails when the iterator contains repeated items
865// FIXED: the item inside the pq is updated
866// so there are two functions with different behaviours.
867impl<I, P, H> FromIterator<(I, P)> for PriorityQueue<I, P, H>
868where
869    I: Hash + Eq,
870    P: Ord,
871    H: BuildHasher + Default,
872{
873    fn from_iter<IT>(iter: IT) -> Self
874    where
875        IT: IntoIterator<Item = (I, P)>,
876    {
877        let store = Store::from_iter(iter);
878        let mut pq = PriorityQueue { store };
879        pq.heap_build();
880        pq
881    }
882}
883
884impl<I, P, H> IntoIterator for PriorityQueue<I, P, H>
885where
886    I: Hash + Eq,
887    P: Ord,
888    H: BuildHasher,
889{
890    type Item = (I, P);
891    type IntoIter = IntoIter<I, P>;
892    fn into_iter(self) -> IntoIter<I, P> {
893        self.store.into_iter()
894    }
895}
896
897impl<'a, I, P, H> IntoIterator for &'a PriorityQueue<I, P, H>
898where
899    I: Hash + Eq,
900    P: Ord,
901    H: BuildHasher,
902{
903    type Item = (&'a I, &'a P);
904    type IntoIter = Iter<'a, I, P>;
905    fn into_iter(self) -> Iter<'a, I, P> {
906        self.store.iter()
907    }
908}
909
910impl<'a, I, P, H> IntoIterator for &'a mut PriorityQueue<I, P, H>
911where
912    I: Hash + Eq,
913    P: Ord,
914    H: BuildHasher,
915{
916    type Item = (&'a mut I, &'a mut P);
917    type IntoIter = IterMut<'a, I, P, H>;
918    fn into_iter(self) -> IterMut<'a, I, P, H> {
919        IterMut::new(self)
920    }
921}
922
923impl<I, P, H> Extend<(I, P)> for PriorityQueue<I, P, H>
924where
925    I: Hash + Eq,
926    P: Ord,
927    H: BuildHasher,
928{
929    fn extend<T: IntoIterator<Item = (I, P)>>(&mut self, iter: T) {
930        let iter = iter.into_iter();
931        let (min, max) = iter.size_hint();
932        let rebuild = if let Some(max) = max {
933            self.reserve(max);
934            better_to_rebuild(self.len(), max)
935        } else if min != 0 {
936            self.reserve(min);
937            better_to_rebuild(self.len(), min)
938        } else {
939            false
940        };
941        if rebuild {
942            self.store.extend(iter);
943            self.heap_build();
944        } else {
945            for (item, priority) in iter {
946                self.push(item, priority);
947            }
948        }
949    }
950}
951
952use std::cmp::PartialEq;
953
954impl<I, P1, H1, P2, H2> PartialEq<PriorityQueue<I, P2, H2>> for PriorityQueue<I, P1, H1>
955where
956    I: Hash + Eq,
957    P1: Ord,
958    P1: PartialEq<P2>,
959    Option<P1>: PartialEq<Option<P2>>,
960    P2: Ord,
961    H1: BuildHasher,
962    H2: BuildHasher,
963{
964    fn eq(&self, other: &PriorityQueue<I, P2, H2>) -> bool {
965        self.store == other.store
966    }
967}
968
969/// Compute the index of the left child of an item from its index
970#[inline(always)]
971const fn left(i: Position) -> Position {
972    Position((i.0 * 2) + 1)
973}
974/// Compute the index of the right child of an item from its index
975#[inline(always)]
976const fn right(i: Position) -> Position {
977    Position((i.0 * 2) + 2)
978}
979/// Compute the index of the parent element in the heap from its index
980#[inline(always)]
981const fn parent(i: Position) -> Position {
982    Position((i.0 - 1) / 2)
983}
984
985#[inline(always)]
986const fn log2_fast(x: usize) -> usize {
987    (usize::BITS - x.leading_zeros() - 1) as usize
988}
989
990// `rebuild` takes O(len1 + len2) operations
991// and about 2 * (len1 + len2) comparisons in the worst case
992// while `extend` takes O(len2 * log_2(len1)) operations
993// and about 1 * len2 * log_2(len1) comparisons in the worst case,
994// assuming len1 >= len2.
995fn better_to_rebuild(len1: usize, len2: usize) -> bool {
996    // log(1) == 0, so the inequation always falsy
997    // log(0) is inapplicable and produces panic
998    if len1 <= 1 {
999        return false;
1000    }
1001
1002    2 * (len1 + len2) < len2 * log2_fast(len1)
1003}
1004
1005#[cfg(feature = "serde")]
1006#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
1007mod serde {
1008    use std::cmp::{Eq, Ord};
1009    use std::hash::{BuildHasher, Hash};
1010
1011    use serde::de::{Deserialize, Deserializer};
1012    use serde::ser::{Serialize, Serializer};
1013
1014    use super::PriorityQueue;
1015    use crate::store::Store;
1016
1017    impl<I, P, H> Serialize for PriorityQueue<I, P, H>
1018    where
1019        I: Hash + Eq + Serialize,
1020        P: Ord + Serialize,
1021        H: BuildHasher,
1022    {
1023        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1024        where
1025            S: Serializer,
1026        {
1027            self.store.serialize(serializer)
1028        }
1029    }
1030
1031    impl<'de, I, P, H> Deserialize<'de> for PriorityQueue<I, P, H>
1032    where
1033        I: Hash + Eq + Deserialize<'de>,
1034        P: Ord + Deserialize<'de>,
1035        H: BuildHasher + Default,
1036    {
1037        fn deserialize<D>(deserializer: D) -> Result<PriorityQueue<I, P, H>, D::Error>
1038        where
1039            D: Deserializer<'de>,
1040        {
1041            Store::deserialize(deserializer).map(|store| {
1042                let mut pq = PriorityQueue { store };
1043                pq.heap_build();
1044                pq
1045            })
1046        }
1047    }
1048}