diff --git a/src/double_priority_queue/mod.rs b/src/double_priority_queue/mod.rs index 566d5f2..8725f25 100644 --- a/src/double_priority_queue/mod.rs +++ b/src/double_priority_queue/mod.rs @@ -34,7 +34,9 @@ pub mod iterators; #[cfg(not(feature = "std"))] use std::vec::Vec; +use crate::better_to_rebuild; use crate::core_iterators::*; +use crate::store::{left, level, parent, right}; use crate::store::{Index, Position, Store}; use crate::TryReserveError; use iterators::*; @@ -1218,48 +1220,6 @@ where } } -/// Compute the index of the left child of an item from its index -#[inline(always)] -const fn left(i: Position) -> Position { - Position((i.0 * 2) + 1) -} -/// Compute the index of the right child of an item from its index -#[inline(always)] -const fn right(i: Position) -> Position { - Position((i.0 * 2) + 2) -} -/// Compute the index of the parent element in the heap from its index -#[inline(always)] -const fn parent(i: Position) -> Position { - Position((i.0 - 1) / 2) -} - -// Compute the level of a node from its index -#[inline(always)] -const fn level(i: Position) -> usize { - log2_fast(i.0 + 1) -} - -#[inline(always)] -const fn log2_fast(x: usize) -> usize { - (usize::BITS - x.leading_zeros() - 1) as usize -} - -// `rebuild` takes O(len1 + len2) operations -// and about 2 * (len1 + len2) comparisons in the worst case -// while `extend` takes O(len2 * log_2(len1)) operations -// and about 1 * len2 * log_2(len1) comparisons in the worst case, -// assuming len1 >= len2. -fn better_to_rebuild(len1: usize, len2: usize) -> bool { - // log(1) == 0, so the inequation always falsy - // log(0) is inapplicable and produces panic - if len1 <= 1 { - return false; - } - - 2 * (len1 + len2) < len2 * log2_fast(len1) -} - #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] mod serde { diff --git a/src/lib.rs b/src/lib.rs index 6bd2c5d..34ae10d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -119,6 +119,7 @@ mod store; pub use crate::double_priority_queue::DoublePriorityQueue; pub use crate::priority_queue::PriorityQueue; +use crate::store::log2_fast; use indexmap::TryReserveError as IndexMapTryReserveError; use std::collections::TryReserveError as StdTryReserveError; @@ -161,3 +162,18 @@ impl From for TryReserveError { } } } + +// `rebuild` takes O(len1 + len2) operations +// and about 2 * (len1 + len2) comparisons in the worst case +// while `extend` takes O(len2 * log_2(len1)) operations +// and about 1 * len2 * log_2(len1) comparisons in the worst case, +// assuming len1 >= len2. +fn better_to_rebuild(len1: usize, len2: usize) -> bool { + // log(1) == 0, so the inequation always falsy + // log(0) is inapplicable and produces panic + if len1 <= 1 { + return false; + } + + 2 * (len1 + len2) < len2 * log2_fast(len1) +} diff --git a/src/priority_queue/mod.rs b/src/priority_queue/mod.rs index 76f02a2..1981562 100644 --- a/src/priority_queue/mod.rs +++ b/src/priority_queue/mod.rs @@ -35,7 +35,9 @@ pub mod iterators; #[cfg(not(feature = "std"))] use std::vec::Vec; +use crate::better_to_rebuild; use crate::core_iterators::*; +use crate::store::{left, parent, right}; use crate::store::{Index, Position, Store}; use crate::TryReserveError; use iterators::*; @@ -730,13 +732,6 @@ where } } -impl PriorityQueue -where - P: Ord, - I: Hash + Eq, -{ -} - impl PriorityQueue where P: Ord, @@ -772,7 +767,7 @@ where self.store.swap(i, largest); i = largest; - let mut largestp = unsafe { self.store.get_priority_from_position(i) }; + largestp = unsafe { self.store.get_priority_from_position(i) }; l = left(i); if l.0 < self.len() { let childp = unsafe { self.store.get_priority_from_position(l) }; @@ -977,42 +972,6 @@ where } } -/// Compute the index of the left child of an item from its index -#[inline(always)] -const fn left(i: Position) -> Position { - Position((i.0 * 2) + 1) -} -/// Compute the index of the right child of an item from its index -#[inline(always)] -const fn right(i: Position) -> Position { - Position((i.0 * 2) + 2) -} -/// Compute the index of the parent element in the heap from its index -#[inline(always)] -const fn parent(i: Position) -> Position { - Position((i.0 - 1) / 2) -} - -#[inline(always)] -const fn log2_fast(x: usize) -> usize { - (usize::BITS - x.leading_zeros() - 1) as usize -} - -// `rebuild` takes O(len1 + len2) operations -// and about 2 * (len1 + len2) comparisons in the worst case -// while `extend` takes O(len2 * log_2(len1)) operations -// and about 1 * len2 * log_2(len1) comparisons in the worst case, -// assuming len1 >= len2. -fn better_to_rebuild(len1: usize, len2: usize) -> bool { - // log(1) == 0, so the inequation always falsy - // log(0) is inapplicable and produces panic - if len1 <= 1 { - return false; - } - - 2 * (len1 + len2) < len2 * log2_fast(len1) -} - #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] mod serde { diff --git a/src/store.rs b/src/store.rs index a4c0147..b1e6887 100644 --- a/src/store.rs +++ b/src/store.rs @@ -46,10 +46,38 @@ use indexmap::map::{IndexMap, MutableKeys}; /// The Index of the element in the Map #[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] pub(crate) struct Index(pub usize); + /// The Position of the element in the Heap #[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] pub(crate) struct Position(pub usize); +/// Compute the index of the left child of an item from its index +#[inline(always)] +pub(crate) const fn left(i: Position) -> Position { + Position((i.0 * 2) + 1) +} +/// Compute the index of the right child of an item from its index +#[inline(always)] +pub(crate) const fn right(i: Position) -> Position { + Position((i.0 * 2) + 2) +} +/// Compute the index of the parent element in the heap from its index +#[inline(always)] +pub(crate) const fn parent(i: Position) -> Position { + Position((i.0 - 1) / 2) +} + +// Compute the level of a node from its index +#[inline(always)] +pub(crate) const fn level(i: Position) -> usize { + log2_fast(i.0 + 1) +} + +#[inline(always)] +pub(crate) const fn log2_fast(x: usize) -> usize { + (usize::BITS - x.leading_zeros() - 1) as usize +} + /// Internal storage of PriorityQueue and DoublePriorityQueue #[derive(Clone)] #[cfg(feature = "std")] @@ -71,15 +99,6 @@ pub(crate) struct Store { pub size: usize, // The size of the heap } -// do not [derive(Eq)] to loosen up trait requirements for other types and impls -impl Eq for Store -where - I: Hash + Eq, - P: Ord, - H: BuildHasher, -{ -} - impl Default for Store where I: Hash + Eq,