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}