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}