Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 2 additions & 42 deletions src/double_priority_queue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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 {
Expand Down
16 changes: 16 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -161,3 +162,18 @@ impl From<IndexMapTryReserveError> 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)
}
47 changes: 3 additions & 44 deletions src/priority_queue/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -730,13 +732,6 @@ where
}
}

impl<I, P, H> PriorityQueue<I, P, H>
where
P: Ord,
I: Hash + Eq,
{
}

impl<I, P, H> PriorityQueue<I, P, H>
where
P: Ord,
Expand Down Expand Up @@ -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) };
Expand Down Expand Up @@ -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 {
Expand Down
37 changes: 28 additions & 9 deletions src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand All @@ -71,15 +99,6 @@ pub(crate) struct Store<I, P, H> {
pub size: usize, // The size of the heap
}

// do not [derive(Eq)] to loosen up trait requirements for other types and impls
impl<I, P, H> Eq for Store<I, P, H>
where
I: Hash + Eq,
P: Ord,
H: BuildHasher,
{
}

impl<I, P, H> Default for Store<I, P, H>
where
I: Hash + Eq,
Expand Down