diff --git a/Cargo.toml b/Cargo.toml index c0a39af..0475d41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "iset" version = "0.1.1" authors = ["Timofey Prodanov "] -edition = "2018" +edition = "2021" description = "Map and set with interval keys (x..y)." repository = "https://github.com/tprodanov/iset" readme = "README.md" @@ -26,5 +26,5 @@ rand = "0.8" serde_json = "1.0" [features] -default = ["dot"] +default = ["dot", "serde"] dot = [] diff --git a/src/iter.rs b/src/iter.rs index 6e6c465..56e21b0 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -1,38 +1,44 @@ //! Module with various iterators over `IntervalMap` and `IntervalSet`. use alloc::vec::Vec; -use core::ops::{Range, RangeBounds, Bound}; use core::iter::FusedIterator; use core::mem; +use core::ops::{Bound, Range, RangeBounds}; -use super::{IntervalMap, Node, IndexType, check_ordered, BitVec}; +use super::{check_ordered, BitVec, IndexType, IntervalMap, Node}; fn should_go_left(nodes: &[Node], index: Ix, start_bound: Bound<&T>) -> bool -where T: PartialOrd + Copy, - Ix: IndexType, +where + T: PartialOrd + Copy, + Ix: IndexType, { - if !nodes[index.get()].left.defined() { - return false; - } - let left_end = nodes[nodes[index.get()].left.get()].subtree_interval.end; - match start_bound { - Bound::Included(&value) | Bound::Excluded(&value) => left_end >= value, - Bound::Unbounded => true, + match nodes[index.get()].left { + None => false, + Some(left) => { + let left_end = nodes[left.get()].subtree_interval.end; + match start_bound { + Bound::Included(&value) | Bound::Excluded(&value) => left_end >= value, + Bound::Unbounded => true, + } + } } } fn should_go_right(nodes: &[Node], index: Ix, end_bound: Bound<&T>) -> bool -where T: PartialOrd + Copy, - Ix: IndexType, +where + T: PartialOrd + Copy, + Ix: IndexType, { - if !nodes[index.get()].right.defined() { - return false; - } - let right_start = nodes[nodes[index.get()].right.get()].subtree_interval.start; - match end_bound { - Bound::Included(&value) => right_start <= value, - Bound::Excluded(&value) => right_start < value, - Bound::Unbounded => true, + match nodes[index.get()].right { + None => false, + Some(right) => { + let right_start = nodes[right.get()].subtree_interval.start; + match end_bound { + Bound::Included(&value) => right_start <= value, + Bound::Excluded(&value) => right_start < value, + Bound::Unbounded => true, + } + } } } @@ -45,7 +51,7 @@ impl ActionStack { } #[inline] - fn push(& mut self) { + fn push(&mut self) { self.0.push(false); self.0.push(false); } @@ -94,17 +100,23 @@ impl ActionStack { } } -fn move_to_next(nodes: &[Node], mut index: Ix, range: &R, stack: &mut ActionStack) -> Ix -where T: PartialOrd + Copy, - R: RangeBounds, - Ix: IndexType, +fn move_to_next( + nodes: &[Node], + mut index_opt: Option, + range: &R, + stack: &mut ActionStack, +) -> Option +where + T: PartialOrd + Copy, + R: RangeBounds, + Ix: IndexType, { - while index.defined() { + while let Some(mut index) = index_opt { if stack.can_go_left() { while should_go_left(nodes, index, range.start_bound()) { stack.go_left(); stack.push(); - index = nodes[index.get()].left; + index = nodes[index.get()].left.unwrap(); } stack.go_left(); } @@ -112,20 +124,20 @@ where T: PartialOrd + Copy, if stack.can_match() { stack.make_match(); if nodes[index.get()].interval.intersects_range(range) { - return index; + return Some(index); } } if stack.can_go_right() && should_go_right(nodes, index, range.end_bound()) { stack.go_right(); stack.push(); - index = nodes[index.get()].right; + index_opt = nodes[index.get()].right; } else { stack.pop(); - index = nodes[index.get()].parent; + index_opt = nodes[index.get()].parent; } } - index + None } /// Macro that generates Iterator over IntervalMap. @@ -141,7 +153,7 @@ macro_rules! iterator { R: RangeBounds, Ix: IndexType, { - pub(crate) index: Ix, + pub(crate) index: Option, range: R, nodes: &'a $( $mut_ )? [Node], stack: ActionStack, @@ -164,12 +176,10 @@ macro_rules! iterator { fn next(&mut self) -> Option { self.index = move_to_next(self.nodes, self.index, &self.range, &mut self.stack); - if !self.index.defined() { - None - } else { - let $node = & $( $mut_ )? self.nodes[self.index.get()]; - Some($out) - } + self.index.map(|index| { + let $node = & $( $mut_ )? self.nodes[index.get()]; + $out + }) } fn size_hint(& self) -> (usize, Option) { @@ -217,6 +227,110 @@ iterator! { node -> unsafe { &mut *(&mut node.value as *mut V) }, { mut } } +/* +#[doc = "Iterator over values equal to range."] +#[derive(Clone, Debug)] +pub struct EqualValues<'a, T, V, Ix> +where + T: PartialOrd + Copy, + Ix: IndexType, +{ + pub(crate) index: Ix, + interval: Interval, + nodes: &'a [Node], + stack: ActionStack, +} +impl<'a, T: PartialOrd + Copy, V, Ix: IndexType> EqualValues<'a, T, V, Ix> { + pub(crate) fn new(tree: &'a IntervalMap, interval: Interval) -> Self { + check_ordered(&interval); + Self { + index: tree.root, + interval, + nodes: &tree.nodes, + stack: ActionStack::new(), + } + } + fn should_go_left(nodes: &[Node], index: Ix, interval: &R) -> bool { + if !nodes[index.get()].left.defined() { + return false; + } + let node = &nodes[nodes[index.get()].left.get()]; + match interval.cmp(&node.interval) { + Ordering::Less => true, + Ordering::Greater => false, + Ordering::Equal => true, + } + let left_end = nodes[nodes[index.get()].left.get()].subtree_interval.end; + match start_bound { + Bound::Included(&value) | Bound::Excluded(&value) => left_end >= value, + Bound::Unbounded => true, + } + } + fn should_go_right(nodes: &[Node], index: Ix, interval: &R) -> bool { + if !nodes[index.get()].right.defined() { + return false; + } + nodes[nodes[index.get()].right.get()].interval <= interval + } + + fn move_to_next( + nodes: &[Node], + mut index: Ix, + interval: &R, + stack: &mut ActionStack, + ) -> Ix + where + T: PartialOrd + Copy, + R: RangeBounds, + Ix: IndexType, + { + while index.defined() { + if stack.can_go_left() { + while Self::should_go_left(nodes, index, interval) { + stack.go_left(); + stack.push(); + index = nodes[index.get()].left; + } + stack.go_left(); + } + + if stack.can_match() { + stack.make_match(); + if nodes[index.get()].interval == interval { + return index; + } + } + + if stack.can_go_right() && should_go_right(nodes, index, interval.end_bound()) { + stack.go_right(); + stack.push(); + index = nodes[index.get()].right; + } else { + stack.pop(); + index = nodes[index.get()].parent; + } + } + index + } +} +impl<'a, T: PartialOrd + Copy, V, Ix: IndexType> Iterator for EqualValues<'a, T, V, Ix> { + type Item = &'a V; + fn next(&mut self) -> Option { + self.index = Self::move_to_next(self.nodes, self.index, &self.interval, &mut self.stack); + if !self.index.defined() { + None + } else { + let node = &self.nodes[self.index.get()]; + Some(&node.value) + } + } + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.nodes.len())) + } +} +impl<'a, T: PartialOrd + Copy, V, Ix: IndexType> FusedIterator for EqualValues<'a, T, V, Ix> {} +*/ + /// Macro that generates IntoIterator over IntervalMap. macro_rules! into_iterator { ( @@ -230,7 +344,7 @@ macro_rules! into_iterator { R: RangeBounds, Ix: IndexType, { - index: Ix, + index: Option, range: R, nodes: Vec>, stack: ActionStack, @@ -253,12 +367,10 @@ macro_rules! into_iterator { fn next(&mut self) -> Option { self.index = move_to_next(&self.nodes, self.index, &self.range, &mut self.stack); - if !self.index.defined() { - None - } else { - let $node = &mut self.nodes[self.index.get()]; - Some($out) - } + self.index.map(|index| { + let $node = &mut self.nodes[index.get()]; + $out + }) } fn size_hint(& self) -> (usize, Option) { diff --git a/src/ix.rs b/src/ix.rs index eddd0e5..cc2784c 100644 --- a/src/ix.rs +++ b/src/ix.rs @@ -1,5 +1,6 @@ //! Wrapper around integer types, used as indices within `IntervalMap` and `IntervalSet`. +use core::convert::TryInto; use core::fmt::Display; /// Trait for index types: used in the inner representation of [IntervalMap](../struct.IntervalMap.html) and @@ -13,60 +14,46 @@ use core::fmt::Display; /// /// Using smaller index types saves memory and slightly reduces running time. pub trait IndexType: Copy + Display + Sized + Eq + Ord { - /// Undefined index. There can be no indices higher than MAX. - const MAX: Self; - /// Converts index into `usize`. fn get(self) -> usize; /// Creates a new index. Returns error if the `elemen_num` is too big. fn new(element_num: usize) -> Result; - - /// Returns `true` if the index is defined. - #[inline(always)] - fn defined(self) -> bool { - self != Self::MAX - } -} - -macro_rules! index_error { - (u64) => { - "Failed to insert a new element into IntervalMap/Set: number of elements is too large for u64." - }; - ($name:ident) => { - concat!( - "Failed to insert a new element into IntervalMap/Set: number of elements is too large for ", - stringify!($name), - ", try using u64.") - }; } macro_rules! impl_index { ($type:ident) => { - impl IndexType for $type { - const MAX: Self = core::$type::MAX; - + impl IndexType for core::num::$type { #[inline(always)] fn get(self) -> usize { - self as usize + (self.get() - 1) as usize } #[inline] fn new(element_num: usize) -> Result { - let element_num = element_num as $type; - if element_num == core::$type::MAX { - Err(index_error!($type)) - } else { - Ok(element_num as $type) - } + const ERROR_STR :&'static str= + concat!( + "Failed to insert a new element into IntervalMap/Set: number of elements is too large for ", + stringify!($type), + ", try using NonZeroU64."); + let nonzero = core::num::$type::new( + element_num + .checked_add(1) + .ok_or(ERROR_STR)? + .try_into() + .map_err(|_| ERROR_STR)?, + ) + .ok_or(ERROR_STR)?; + Ok(nonzero) } } }; } -impl_index!(u8); -impl_index!(u16); -impl_index!(u32); -impl_index!(u64); +impl_index!(NonZeroU8); +impl_index!(NonZeroU16); +impl_index!(NonZeroU32); +impl_index!(NonZeroU64); +impl_index!(NonZeroUsize); /// Default index type. -pub type DefaultIx = u32; +pub type DefaultIx = core::num::NonZeroU32; diff --git a/src/lib.rs b/src/lib.rs index bdef7e8..4e1b810 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,35 +25,35 @@ extern crate std; extern crate alloc; -pub mod ix; +mod bitvec; pub mod iter; +pub mod ix; pub mod set; mod tree_rm; -mod bitvec; #[cfg(test)] mod tests; use alloc::vec::Vec; -use core::ops::{Range, RangeFull, RangeInclusive, RangeBounds, Bound, AddAssign, Sub, Index}; +use core::cmp::Ordering; use core::fmt::{self, Debug, Display, Formatter}; use core::iter::{FromIterator, IntoIterator}; -use core::cmp::Ordering; +use core::ops::{AddAssign, Bound, Index, Range, RangeBounds, RangeFull, RangeInclusive, Sub}; #[cfg(feature = "dot")] use std::io::{self, Write}; #[cfg(feature = "serde")] use { core::marker::PhantomData, - serde::{Serialize, Serializer, Deserialize, Deserializer}, - serde::ser::{SerializeTuple, SerializeSeq}, - serde::de::{Visitor, SeqAccess}, + serde::de::{SeqAccess, Visitor}, + serde::ser::{SerializeSeq, SerializeTuple}, + serde::{Deserialize, Deserializer, Serialize, Serializer}, }; -use ix::IndexType; -pub use ix::DefaultIx; +use bitvec::BitVec; use iter::*; +pub use ix::DefaultIx; +use ix::IndexType; pub use set::IntervalSet; -use bitvec::BitVec; #[derive(Clone, Debug, PartialEq, PartialOrd)] struct Interval { @@ -87,9 +87,7 @@ impl Interval { Bound::Included(&value) => self.start <= value, Bound::Excluded(&value) => self.start < value, Bound::Unbounded => true, - }) - && - (match range.start_bound() { + }) && (match range.start_bound() { Bound::Included(&value) | Bound::Excluded(&value) => self.end > value, Bound::Unbounded => true, }) @@ -105,26 +103,18 @@ impl Interval { } } +#[allow(clippy::derive_ord_xor_partial_ord)] impl Ord for Interval { fn cmp(&self, other: &Self) -> Ordering { - // Implement cmp by ourselves because T can be PartialOrd. - if self.start < other.start { - Ordering::Less - } else if self.start == other.start { - if self.end < other.end { - Ordering::Less - } else if self.end == other.end { - Ordering::Equal - } else { - Ordering::Greater - } - } else { - Ordering::Greater + // We allow using PartialOrd keys, but any values must actually be comparable (e.g. not NAN) + match self.partial_cmp(other) { + Some(ordering) => ordering, + None => panic!("Interval keys must be comparable"), } } } -impl Eq for Interval { } +impl Eq for Interval {} #[cfg(feature = "serde")] impl Serialize for Interval { @@ -147,9 +137,9 @@ struct Node { interval: Interval, subtree_interval: Interval, value: V, - left: Ix, - right: Ix, - parent: Ix, + left: Option, + right: Option, + parent: Option, } impl Node { @@ -158,30 +148,31 @@ impl Node { interval: interval.clone(), subtree_interval: interval, value, - left: Ix::MAX, - right: Ix::MAX, - parent: Ix::MAX, + left: None, + right: None, + parent: None, } } - - /// Swaps values and intervals between two mutable nodes. - fn swap_with(&mut self, other: &mut Self) { - core::mem::swap(&mut self.value, &mut other.value); - core::mem::swap(&mut self.interval, &mut other.interval); - core::mem::swap(&mut self.subtree_interval, &mut other.subtree_interval); - } } #[cfg(feature = "dot")] impl Node { fn write_dot(&self, index: usize, is_red: bool, mut writer: W) -> io::Result<()> { - writeln!(writer, " {} [label=\"i={}\\n{}: {}\\nsubtree: {}\", fillcolor={}, style=filled]", - index, index, self.interval, self.value, self.subtree_interval, if is_red { "salmon" } else { "grey65" })?; - if self.left.defined() { - writeln!(writer, " {} -> {} [label=\"L\"]", index, self.left)?; + writeln!( + writer, + " {} [label=\"i={}\\n{}: {}\\nsubtree: {}\", fillcolor={}, style=filled]", + index, + index, + self.interval, + self.value, + self.subtree_interval, + if is_red { "salmon" } else { "grey65" } + )?; + if let Some(left) = self.left { + writeln!(writer, " {index} -> {} [label=\"L\"]", left.get())?; } - if self.right.defined() { - writeln!(writer, " {} -> {} [label=\"R\"]", index, self.right)?; + if let Some(right) = self.right { + writeln!(writer, " {index} -> {right} [label=\"R\"]")?; } Ok(()) } @@ -189,14 +180,24 @@ impl Node { #[cfg(feature = "dot")] impl Node { - fn write_dot_without_values(&self, index: usize, is_red: bool, mut writer: W) -> io::Result<()> { - writeln!(writer, " {} [label=\"i={}: {}\\nsubtree: {}\", fillcolor={}, style=filled]", - index, index, self.interval, self.subtree_interval, if is_red { "salmon" } else { "grey65" })?; - if self.left.defined() { - writeln!(writer, " {} -> {} [label=\"L\"]", index, self.left)?; + fn write_dot_without_values( + &self, + index: usize, + is_red: bool, + mut writer: W, + ) -> io::Result<()> { + writeln!( + writer, + " {index} [label=\"i={index}: {}\\nsubtree: {}\", fillcolor={}, style=filled]", + self.interval, + self.subtree_interval, + if is_red { "salmon" } else { "grey65" } + )?; + if let Some(left) = self.left { + writeln!(writer, " {index} -> {left} [label=\"L\"]")?; } - if self.right.defined() { - writeln!(writer, " {} -> {} [label=\"R\"]", index, self.right)?; + if let Some(right) = self.right { + writeln!(writer, " {index} -> {right} [label=\"R\"]")?; } Ok(()) } @@ -204,7 +205,10 @@ impl Node { fn check_interval(start: T, end: T) { if start < end { - assert!(end > start, "Interval cannot be ordered (`start < end` but not `end > start`)"); + assert!( + end > start, + "Interval cannot be ordered (`start < end` but not `end > start`)" + ); } else if end <= start { panic!("Interval is empty (`start >= end`)"); } else { @@ -214,7 +218,10 @@ fn check_interval(start: T, end: T) { fn check_interval_incl(start: T, end: T) { if start <= end { - assert!(end >= start, "Interval cannot be ordered (`start < end` but not `end > start`)"); + assert!( + end >= start, + "Interval cannot be ordered (`start < end` but not `end > start`)" + ); } else if end < start { panic!("Interval is empty (`start > end`)"); } else { @@ -224,7 +231,7 @@ fn check_interval_incl(start: T, end: T) { fn check_ordered>(range: &R) { match (range.start_bound(), range.end_bound()) { - (_, Bound::Unbounded) | (Bound::Unbounded, _) => {}, + (_, Bound::Unbounded) | (Bound::Unbounded, _) => {} (Bound::Included(a), Bound::Included(b)) => check_interval_incl(a, b), (Bound::Included(a), Bound::Excluded(b)) | (Bound::Excluded(a), Bound::Included(b)) @@ -334,16 +341,17 @@ fn check_ordered>(range: &R) { /// ```rust /// #[macro_use] extern crate iset; /// use iset::IntervalMap; +/// use core::num::*; /// /// // Creates an empty interval map with the default index type (u32): /// let mut map = IntervalMap::new(); /// map.insert(10..20, 'a'); /// /// // Creates an empty interval map and specifies index type (u16 here): -/// let mut map = IntervalMap::<_, _, u16>::default(); +/// let mut map = IntervalMap::<_, _, NonZeroU16>::default(); /// map.insert(10..20, 'a'); /// -/// let mut map = IntervalMap::<_, _, u16>::with_capacity(10); +/// let mut map = IntervalMap::<_, _, NonZeroU16>::with_capacity(10); /// map.insert(10..20, 'a'); /// /// // Creates an interval map with the default index type: @@ -354,7 +362,7 @@ fn check_ordered>(range: &R) { /// /// // Creates an interval map from a sorted iterator, takes O(N): /// let vec = vec![(0..10, 'b'), (5..15, 'a')]; -/// let map = IntervalMap::<_, _, u32>::from_sorted(vec.into_iter()); +/// let map = IntervalMap::<_, _, NonZeroU32>::from_sorted(vec.into_iter()); /// /// // Alternatively, you can use `.collect()` method that creates an interval map /// // with the default index size. `Collect` does not require sorted intervals, @@ -380,13 +388,14 @@ fn check_ordered>(range: &R) { /// and [Iterator::partition](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.partition) in linear time. #[derive(Clone)] pub struct IntervalMap -where T: PartialOrd + Copy, - Ix: IndexType, +where + T: PartialOrd + Copy, + Ix: IndexType, { nodes: Vec>, // true if the node is red, false if black. colors: BitVec, - root: Ix, + root: Option, } impl IntervalMap { @@ -402,7 +411,7 @@ impl Default for IntervalMap { Self { nodes: Vec::new(), colors: BitVec::new(), - root: Ix::MAX, + root: None, } } } @@ -429,7 +438,7 @@ impl IntervalMap { Self { nodes: Vec::with_capacity(capacity), colors: BitVec::with_capacity(capacity), - root: Ix::MAX, + root: None, } } @@ -449,13 +458,13 @@ impl IntervalMap { let center_ix = Ix::new(center).unwrap_or_else(|error| panic!("{}", error)); if start < center { let left_ix = self.init_from_sorted(start, center, rev_depth - 1); - self.nodes[center].left = left_ix; - self.nodes[left_ix.get()].parent = center_ix; + self.nodes[center].left = Some(left_ix); + self.nodes[left_ix.get()].parent = Some(center_ix); } if center + 1 < end { let right_ix = self.init_from_sorted(center + 1, end, rev_depth - 1); - self.nodes[center].right = right_ix; - self.nodes[right_ix.get()].parent = center_ix; + self.nodes[center].right = Some(right_ix); + self.nodes[right_ix.get()].parent = Some(center_ix); } self.update_subtree_interval(center_ix); center_ix @@ -465,14 +474,17 @@ impl IntervalMap { /// /// Panics if the intervals are not sorted or if there are equal intervals. pub fn from_sorted(iter: I) -> Self - where I: Iterator, V)>, + where + I: Iterator, V)>, { - let nodes: Vec<_> = iter.map(|(range, value)| Node::new(Interval::new(&range), value)).collect(); + let nodes: Vec<_> = iter + .map(|(range, value)| Node::new(Interval::new(&range), value)) + .collect(); let n = nodes.len(); let mut map = Self { nodes, colors: BitVec::from_elem(n, false), // Start with all black nodes. - root: Ix::MAX, + root: None, }; for i in 1..n { assert!(map.nodes[i - 1].interval < map.nodes[i].interval, @@ -481,7 +493,7 @@ impl IntervalMap { } if n > 0 { let max_depth = calculate_max_depth(n); - map.root = map.init_from_sorted(0, n, max_depth); + map.root = Some(map.init_from_sorted(0, n, max_depth)); } map } @@ -502,7 +514,7 @@ impl IntervalMap { pub fn clear(&mut self) { self.nodes.clear(); self.colors.clear(); - self.root = Ix::MAX; + self.root = None; } /// Shrinks inner contents. @@ -511,6 +523,14 @@ impl IntervalMap { self.colors.shrink_to_fit(); } + fn node(&self, ix: Ix) -> &Node { + &self.nodes[ix.get()] + } + + fn node_mut(&mut self, ix: Ix) -> &mut Node { + &mut self.nodes[ix.get()] + } + #[inline] fn is_red(&self, ix: Ix) -> bool { self.colors.get(ix.get()) @@ -522,8 +542,11 @@ impl IntervalMap { } #[inline] - fn is_black_or_nil(&self, ix: Ix) -> bool { - !ix.defined() || !self.colors.get(ix.get()) + fn is_black_or_nil(&self, ix: Option) -> bool { + match ix { + Some(ix) => self.is_black(ix), + None => true, + } } #[inline] @@ -537,126 +560,138 @@ impl IntervalMap { } fn update_subtree_interval(&mut self, index: Ix) { - let node = &self.nodes[index.get()]; + let node = self.node(index); let mut subtree_interval = node.interval.clone(); - if node.left.defined() { - subtree_interval.extend(&self.nodes[node.left.get()].subtree_interval); + if let Some(left) = node.left { + subtree_interval.extend(&self.node(left).subtree_interval); } - if node.right.defined() { - subtree_interval.extend(&self.nodes[node.right.get()].subtree_interval); + if let Some(right) = node.right { + subtree_interval.extend(&self.node(right).subtree_interval); } - self.nodes[index.get()].subtree_interval = subtree_interval; - } - - fn sibling(&self, index: Ix) -> Ix { - let parent = self.nodes[index.get()].parent; - if !parent.defined() { - Ix::MAX - } else if self.nodes[parent.get()].left == index { - self.nodes[parent.get()].right - } else { - self.nodes[parent.get()].left + self.node_mut(index).subtree_interval = subtree_interval; + } + + fn sibling(&self, index: Ix) -> Option { + match self.node(index).parent { + None => None, + Some(parent) => { + let parent = self.node(parent); + if parent.left == Some(index) { + parent.right + } else { + parent.left + } + } } } fn rotate_left(&mut self, index: Ix) { - let prev_parent = self.nodes[index.get()].parent; - let prev_right = self.nodes[index.get()].right; - debug_assert!(prev_right.defined()); + let prev_parent = self.node(index).parent; + let prev_right = self.node(index).right.unwrap(); - let new_right = self.nodes[prev_right.get()].left; - self.nodes[index.get()].right = new_right; - if new_right.defined() { - self.nodes[new_right.get()].parent = index; + let new_right = self.node(prev_right).left; + self.node_mut(index).right = new_right; + if let Some(new_right) = new_right { + self.node_mut(new_right).parent = Some(index); } self.update_subtree_interval(index); - self.nodes[prev_right.get()].left = index; - self.nodes[index.get()].parent = prev_right; + self.node_mut(prev_right).left = Some(index); + self.node_mut(index).parent = Some(prev_right); self.update_subtree_interval(prev_right); - if prev_parent.defined() { - if self.nodes[prev_parent.get()].left == index { - self.nodes[prev_parent.get()].left = prev_right; - } else { - self.nodes[prev_parent.get()].right = prev_right; + match prev_parent { + Some(prev_parent) => { + let prev_parent_node = self.node_mut(prev_parent); + if prev_parent_node.left == Some(index) { + prev_parent_node.left = Some(prev_right); + } else { + prev_parent_node.right = Some(prev_right); + } + self.node_mut(prev_right).parent = Some(prev_parent); + self.update_subtree_interval(prev_parent); + } + None => { + self.root = Some(prev_right); + self.node_mut(prev_right).parent = None; } - self.nodes[prev_right.get()].parent = prev_parent; - self.update_subtree_interval(prev_parent); - } else { - self.root = prev_right; - self.nodes[prev_right.get()].parent = Ix::MAX; } } fn rotate_right(&mut self, index: Ix) { + // XXX switch to using node() and node_mut() let prev_parent = self.nodes[index.get()].parent; - let prev_left = self.nodes[index.get()].left; - debug_assert!(prev_left.defined()); + let prev_left = self.nodes[index.get()].left.unwrap(); let new_left = self.nodes[prev_left.get()].right; self.nodes[index.get()].left = new_left; - if new_left.defined() { - self.nodes[new_left.get()].parent = index; + if let Some(new_left) = new_left { + self.nodes[new_left.get()].parent = Some(index); } self.update_subtree_interval(index); - self.nodes[prev_left.get()].right = index; - self.nodes[index.get()].parent = prev_left; + self.nodes[prev_left.get()].right = Some(index); + self.nodes[index.get()].parent = Some(prev_left); self.update_subtree_interval(prev_left); - if prev_parent.defined() { - if self.nodes[prev_parent.get()].right == index { - self.nodes[prev_parent.get()].right = prev_left; - } else { - self.nodes[prev_parent.get()].left = prev_left; + match prev_parent { + Some(prev_parent) => { + if self.nodes[prev_parent.get()].right == Some(index) { + self.nodes[prev_parent.get()].right = Some(prev_left); + } else { + self.nodes[prev_parent.get()].left = Some(prev_left); + } + self.nodes[prev_left.get()].parent = Some(prev_parent); + self.update_subtree_interval(prev_parent); + } + None => { + self.root = Some(prev_left); + self.nodes[prev_left.get()].parent = None; } - self.nodes[prev_left.get()].parent = prev_parent; - self.update_subtree_interval(prev_parent); - } else { - self.root = prev_left; - self.nodes[prev_left.get()].parent = Ix::MAX; } } fn insert_repair(&mut self, mut index: Ix) { loop { debug_assert!(self.is_red(index)); - if index == self.root { + if Some(index) == self.root { self.set_black(index); return; } // parent should be defined - let parent = self.nodes[index.get()].parent; + let parent = self.node(index).parent.unwrap(); if self.is_black(parent) { return; } // parent is red // grandparent should be defined - let grandparent = self.nodes[parent.get()].parent; - let uncle = self.sibling(parent); - - if uncle.defined() && self.is_red(uncle) { - self.set_black(parent); - self.set_black(uncle); - self.set_red(grandparent); - index = grandparent; - continue; + let grandparent = self.node(parent).parent.unwrap(); + if let Some(uncle) = self.sibling(parent) { + if self.is_red(uncle) { + self.set_black(parent); + self.set_black(uncle); + self.set_red(grandparent); + index = grandparent; + continue; + } } - if index == self.nodes[parent.get()].right && parent == self.nodes[grandparent.get()].left { + if Some(index) == self.node(parent).right && Some(parent) == self.node(grandparent).left + { self.rotate_left(parent); - index = self.nodes[index.get()].left; - } else if index == self.nodes[parent.get()].left && parent == self.nodes[grandparent.get()].right { + index = self.node(index).left.unwrap(); + } else if Some(index) == self.node(parent).left + && Some(parent) == self.node(grandparent).right + { self.rotate_right(parent); - index = self.nodes[index.get()].right; + index = self.node(index).right.unwrap(); } - let parent = self.nodes[index.get()].parent; - let grandparent = self.nodes[parent.get()].parent; - if index == self.nodes[parent.get()].left { + let parent = self.node(index).parent.unwrap(); + let grandparent = self.node(parent).parent.unwrap(); + if Some(index) == self.node(parent).left { self.rotate_right(grandparent); } else { self.rotate_left(grandparent); @@ -667,10 +702,10 @@ impl IntervalMap { } } - fn fix_intervals_up(&mut self, mut ix: Ix) { - while ix.defined() { + fn fix_intervals_up(&mut self, mut ix_opt: Option) { + while let Some(ix) = ix_opt { self.update_subtree_interval(ix); - ix = self.nodes[ix.get()].parent; + ix_opt = self.node(ix).parent; } } @@ -679,40 +714,43 @@ impl IntervalMap { /// Otherwise, inserts a new node and returns None. fn insert_inner(&mut self, interval: Range, value: V, replace: bool) -> Option { let interval = Interval::new(&interval); - let mut current = self.root; let new_index = Ix::new(self.nodes.len()).unwrap_or_else(|error| panic!("{}", error)); - if !current.defined() { - self.root = new_index; - self.nodes.push(Node::new(interval, value)); - // New node should be black. - self.colors.push(false); - return None; - } + let mut current = match self.root { + Some(root) => root, + None => { + self.root = Some(new_index); + self.nodes.push(Node::new(interval, value)); + // New node should be black. + self.colors.push(false); + return None; + } + }; loop { - let node = &mut self.nodes[current.get()]; + let node = self.node_mut(current); let child = match interval.cmp(&node.interval) { Ordering::Less => &mut node.left, Ordering::Equal if replace => { let old_val = core::mem::replace(&mut node.value, value); - self.fix_intervals_up(current); + self.fix_intervals_up(Some(current)); return Some(old_val); } // If Ordering::Greater or if Equal and there is no replacing. _ => &mut node.right, }; - if child.defined() { - current = *child; - } else { - let mut new_node = Node::new(interval, value); - *child = new_index; - new_node.parent = current; - self.nodes.push(new_node); - self.colors.push(true); - self.fix_intervals_up(current); - self.insert_repair(new_index); - return None; + match child { + Some(child) => current = *child, + None => { + let mut new_node = Node::new(interval, value); + *child = Some(new_index); + new_node.parent = Some(current); + self.nodes.push(new_node); + self.colors.push(true); + self.fix_intervals_up(Some(current)); + self.insert_repair(new_index); + return None; + } } } } @@ -760,28 +798,31 @@ impl IntervalMap { /// ``` #[inline] pub fn force_insert(&mut self, interval: Range, value: V) { - assert!(self.insert_inner(interval, value, false).is_none(), "Force insert should always return None"); + assert!( + self.insert_inner(interval, value, false).is_none(), + "Force insert should always return None" + ); } - fn find_index(&self, interval: &Range) -> Ix { + fn find_index(&self, interval: &Range) -> Option { let interval = Interval::new(interval); - let mut index = self.root; - while index.defined() { + let mut index_opt = self.root; + while let Some(index) = index_opt { let node = &self.nodes[index.get()]; match interval.cmp(&node.interval) { - Ordering::Less => index = node.left, - Ordering::Greater => index = node.right, - Ordering::Equal => return index, + Ordering::Less => index_opt = node.left, + Ordering::Greater => index_opt = node.right, + Ordering::Equal => return Some(index), } } - index + None } /// Check if the interval map contains `interval` (exact match). /// /// Panics if `interval` is empty (`start >= end`) or contains a value that cannot be compared (such as `NAN`). pub fn contains(&self, interval: Range) -> bool { - self.find_index(&interval).defined() + self.find_index(&interval).is_some() } /// Returns value associated with `interval` (exact match). @@ -789,12 +830,8 @@ impl IntervalMap { /// /// Panics if `interval` is empty (`start >= end`) or contains a value that cannot be compared (such as `NAN`). pub fn get(&self, interval: Range) -> Option<&V> { - let index = self.find_index(&interval); - if index.defined() { - Some(&self.nodes[index.get()].value) - } else { - None - } + self.find_index(&interval) + .map(|index| &self.node(index).value) } /// Returns mutable value associated with `interval` (exact match). @@ -802,11 +839,9 @@ impl IntervalMap { /// /// Panics if `interval` is empty (`start >= end`) or contains a value that cannot be compared (such as `NAN`). pub fn get_mut(&mut self, interval: Range) -> Option<&mut V> { - let index = self.find_index(&interval); - if index.defined() { - Some(&mut self.nodes[index.get()].value) - } else { - None + match self.find_index(&interval) { + Some(index) => Some(&mut self.node_mut(index).value), + None => None, } } @@ -818,101 +853,141 @@ impl IntervalMap { self.remove_at(self.find_index(&interval)) } + /// Call f() on all indices of nodes whose interval is equal to `interval`. If f() returns + /// Some(x), stop traversal and return Some(x). + fn find_equal_indices( + &self, + index: Option, + interval: &Interval, + f: &mut impl FnMut(Ix) -> Option, + ) -> Option { + let index = match index { + Some(index) => index, + None => return None, + }; + let node = self.node(index); + match interval.cmp(&node.interval) { + Ordering::Less => self.find_equal_indices(node.left, interval, f), + Ordering::Greater => self.find_equal_indices(node.right, interval, f), + Ordering::Equal => match f(index) { + Some(result) => Some(result), + None => { + if let Some(result) = self.find_equal_indices(node.left, interval, f) { + return Some(result); + } + self.find_equal_indices(node.right, interval, f) + } + }, + } + } + + /// Removes an entry, associated with `interval` (exact match is required) and for which + /// `select` returns `true`. Takes *O(M + log N)*, where M is the number of entries with the + /// same interval. Returns value if the interval was present in the map and `select` + /// returned `true`, and None otherwise. + /// + /// Panics if `interval` is empty (`start >= end`) or contains a value that cannot be + /// compared (such as `NAN`). + pub fn remove_select(&mut self, interval: Range, select: impl Fn(&V) -> bool) -> Option { + self.find_equal_indices( + self.root, + &Interval::new(&interval), + &mut |index| match select(&self.node(index).value) { + true => Some(index), + false => None, + }, + ) + .and_then(|index| self.remove_at(Some(index))) + } + /// Returns a range of interval keys in the map, takes *O(1)*. Returns `None` if the map is empty. /// `out.start` is the minimal start of all intervals in the map, /// and `out.end` is the maximal end of all intervals in the map. pub fn range(&self) -> Option> { - if self.root.defined() { - Some(self.nodes[self.root.get()].subtree_interval.to_range()) - } else { - None - } + self.root + .map(|root| self.node(root).subtree_interval.to_range()) } - fn smallest_index(&self) -> Ix { - let mut index = self.root; - while self.nodes[index.get()].left.defined() { - index = self.nodes[index.get()].left; + fn smallest_index(&self) -> Option { + let mut index_opt = self.root; + while let Some(index) = index_opt { + match self.node(index).left { + Some(left) => index_opt = Some(left), + None => return Some(index), + } } - index + None } - fn largest_index(&self) -> Ix { - let mut index = self.root; - while self.nodes[index.get()].right.defined() { - index = self.nodes[index.get()].right; + fn largest_index(&self) -> Option { + let mut index_opt = self.root; + while let Some(index) = index_opt { + match self.node(index).right { + Some(right) => index_opt = Some(right), + None => return Some(index), + } } - index + None } /// Returns the pair `(x..y, &value)` with the smallest interval `x..y` (in lexicographical order). /// Takes *O(log N)*. Returns `None` if the map is empty. pub fn smallest(&self) -> Option<(Range, &V)> { - if !self.root.defined() { - None - } else { - let node = &self.nodes[self.smallest_index().get()]; - Some((node.interval.to_range(), &node.value)) - } + self.smallest_index().map(|index| { + let node = self.node(index); + (node.interval.to_range(), &node.value) + }) } /// Returns the pair `(x..y, &mut value)` with the smallest interval `x..y` (in lexicographical order). /// Takes *O(log N)*. Returns `None` if the map is empty. pub fn smallest_mut(&mut self) -> Option<(Range, &mut V)> { - if !self.root.defined() { - None - } else { - let index = self.smallest_index(); - let node = &mut self.nodes[index.get()]; - Some((node.interval.to_range(), &mut node.value)) + match self.smallest_index() { + Some(index) => { + let node = self.node_mut(index); + Some((node.interval.to_range(), &mut node.value)) + } + None => None, } } /// Removes the smallest interval `x..y` (in lexicographical order) from the map and returns pair `(x..y, value)`. /// Takes *O(log N)*. Returns `None` if the map is empty. pub fn remove_smallest(&mut self) -> Option<(Range, V)> { - if !self.root.defined() { - None - } else { - let index = self.smallest_index(); - let range = self.nodes[index.get()].interval.to_range(); - Some((range, self.remove_at(index).unwrap())) - } + self.smallest_index().map(|index| { + let range = self.node(index).interval.to_range(); + (range, self.remove_at(Some(index)).unwrap()) + }) } /// Returns the pair `(x..y, &value)` with the largest interval `x..y` (in lexicographical order). /// Takes *O(log N)*. Returns `None` if the map is empty. pub fn largest(&self) -> Option<(Range, &V)> { - if !self.root.defined() { - None - } else { - let node = &self.nodes[self.largest_index().get()]; - Some((node.interval.to_range(), &node.value)) - } + self.largest_index().map(|index| { + let node = self.node(index); + (node.interval.to_range(), &node.value) + }) } /// Returns the pair `(x..y, &mut value)` with the largest interval `x..y` (in lexicographical order). /// Takes *O(log N)*. Returns `None` if the map is empty. pub fn largest_mut(&mut self) -> Option<(Range, &mut V)> { - if !self.root.defined() { - None - } else { - let index = self.largest_index(); - let node = &mut self.nodes[index.get()]; - Some((node.interval.to_range(), &mut node.value)) + match self.largest_index() { + Some(index) => { + let node = self.node_mut(index); + Some((node.interval.to_range(), &mut node.value)) + } + None => None, } } /// Removes the largest interval `x..y` (in lexicographical order) from the map and returns pair `(x..y, value)`. /// Takes *O(log N)*. Returns `None` if the map is empty. pub fn remove_largest(&mut self) -> Option<(Range, V)> { - if !self.root.defined() { - None - } else { - let index = self.largest_index(); - let range = self.nodes[index.get()].interval.to_range(); - Some((range, self.remove_at(index).unwrap())) - } + self.largest_index().map(|index| { + let range = self.node(index).interval.to_range(); + (range, self.remove_at(Some(index)).unwrap()) + }) } /// Checks, if the query overlaps any intervals in the interval map. @@ -924,17 +999,17 @@ impl IntervalMap { /// assert!(map.has_overlap(8..=10)); /// ``` pub fn has_overlap(&self, query: R) -> bool - where R: RangeBounds, + where + R: RangeBounds, { check_ordered(&query); - if !self.root.defined() { - return false; - } let mut queue = Vec::new(); - queue.push(self.root); + if let Some(root) = self.root { + queue.push(root); + } while let Some(index) = queue.pop() { - let node = &self.nodes[index.get()]; + let node = self.node(index); let subtree_start = node.subtree_interval.start; let subtree_end = node.subtree_interval.end; @@ -953,7 +1028,7 @@ impl IntervalMap { // The whole subtree lies to the left of the query. continue; } - }, + } Bound::Excluded(&q_start) => { if q_start <= subtree_start { true @@ -963,7 +1038,7 @@ impl IntervalMap { // The whole subtree lies to the left of the query. continue; } - }, + } }; // Query end is greater than the subtree interval end. @@ -978,23 +1053,23 @@ impl IntervalMap { } else { q_end > subtree_end } - }, + } Bound::Excluded(&q_end) => { if q_end <= subtree_start { continue; } else { q_end > subtree_end } - }, + } }; if q_start_lt_start || q_end_gt_end || node.interval.intersects_range(&query) { return true; } - if node.left.defined() { - queue.push(node.left); + if let Some(left) = node.left { + queue.push(left); } - if node.right.defined() { - queue.push(node.right); + if let Some(right) = node.right { + queue.push(right); } } false @@ -1005,40 +1080,45 @@ impl IntervalMap { /// Output is sorted by intervals, but not by values. /// /// Panics if `interval` is empty or contains a value that cannot be compared (such as `NAN`). - pub fn iter<'a, R>(&'a self, query: R) -> Iter<'a, T, V, R, Ix> - where R: RangeBounds, + pub fn iter(&self, query: R) -> Iter<'_, T, V, R, Ix> + where + R: RangeBounds, { Iter::new(self, query) } /// Iterates over intervals `x..y` that overlap the `query`. /// See [iter](#method.iter) for more details. - pub fn intervals<'a, R>(&'a self, query: R) -> Intervals<'a, T, V, R, Ix> - where R: RangeBounds, + pub fn intervals(&self, query: R) -> Intervals<'_, T, V, R, Ix> + where + R: RangeBounds, { Intervals::new(self, query) } /// Iterates over values that overlap the `query`. /// See [iter](#method.iter) for more details. - pub fn values<'a, R>(&'a self, query: R) -> Values<'a, T, V, R, Ix> - where R: RangeBounds, + pub fn values(&self, query: R) -> Values<'_, T, V, R, Ix> + where + R: RangeBounds, { Values::new(self, query) } /// Iterator over pairs `(x..y, &mut value)` that overlap the `query`. /// See [iter](#method.iter) for more details. - pub fn iter_mut<'a, R>(&'a mut self, query: R) -> IterMut<'a, T, V, R, Ix> - where R: RangeBounds, + pub fn iter_mut(&mut self, query: R) -> IterMut<'_, T, V, R, Ix> + where + R: RangeBounds, { IterMut::new(self, query) } /// Iterator over *mutable* values that overlap the `query`. /// See [iter](#method.iter) for more details. - pub fn values_mut<'a, R>(&'a mut self, query: R) -> ValuesMut<'a, T, V, R, Ix> - where R: RangeBounds, + pub fn values_mut(&mut self, query: R) -> ValuesMut<'_, T, V, R, Ix> + where + R: RangeBounds, { ValuesMut::new(self, query) } @@ -1047,7 +1127,8 @@ impl IntervalMap { /// iterates over pairs `(x..y, value)` that overlap the `query`. /// See [iter](#method.iter) for more details. pub fn into_iter(self, query: R) -> IntoIter - where R: RangeBounds, + where + R: RangeBounds, { IntoIter::new(self, query) } @@ -1056,7 +1137,8 @@ impl IntervalMap { /// iterates over pairs `(x..y, value)` that overlap the `query`. /// See [iter](#method.iter) for more details. pub fn into_intervals(self, query: R) -> IntoIntervals - where R: RangeBounds, + where + R: RangeBounds, { IntoIntervals::new(self, query) } @@ -1065,7 +1147,8 @@ impl IntervalMap { /// iterates over values, for which intervals that overlap the `query`. /// See [iter](#method.iter) for more details. pub fn into_values(self, query: R) -> IntoValues - where R: RangeBounds, + where + R: RangeBounds, { IntoValues::new(self, query) } @@ -1073,61 +1156,61 @@ impl IntervalMap { /// Iterates over pairs `(x..y, &value)` that overlap the `point`. /// See [iter](#method.iter) for more details. #[inline] - pub fn overlap<'a>(&'a self, point: T) -> Iter<'a, T, V, RangeInclusive, Ix> { + pub fn overlap(&self, point: T) -> Iter<'_, T, V, RangeInclusive, Ix> { Iter::new(self, point..=point) } /// Iterates over intervals `x..y` that overlap the `point`. /// See [iter](#method.iter) for more details. #[inline] - pub fn intervals_overlap<'a>(&'a self, point: T) -> Intervals<'a, T, V, RangeInclusive, Ix> { + pub fn intervals_overlap(&self, point: T) -> Intervals<'_, T, V, RangeInclusive, Ix> { Intervals::new(self, point..=point) } /// Iterates over values that overlap the `point`. /// See [iter](#method.iter) for more details. #[inline] - pub fn values_overlap<'a>(&'a self, point: T) -> Values<'a, T, V, RangeInclusive, Ix> { + pub fn values_overlap(&self, point: T) -> Values<'_, T, V, RangeInclusive, Ix> { Values::new(self, point..=point) } /// Iterator over pairs `(x..y, &mut value)` that overlap the `point`. /// See [iter](#method.iter) for more details. #[inline] - pub fn overlap_mut<'a>(&'a mut self, point: T) -> IterMut<'a, T, V, RangeInclusive, Ix> { + pub fn overlap_mut(&mut self, point: T) -> IterMut<'_, T, V, RangeInclusive, Ix> { IterMut::new(self, point..=point) } /// Iterates over *mutable* values that overlap the `point`. /// See [iter](#method.iter) for more details. #[inline] - pub fn values_overlap_mut<'a>(&'a mut self, point: T) -> ValuesMut<'a, T, V, RangeInclusive, Ix> { + pub fn values_overlap_mut(&mut self, point: T) -> ValuesMut<'_, T, V, RangeInclusive, Ix> { ValuesMut::new(self, point..=point) } /// Creates an unsorted iterator over all pairs `(x..y, &value)`. /// Slightly faster than the sorted iterator, although both take *O(N)*. - pub fn unsorted_iter<'a>(&'a self) -> UnsIter<'a, T, V, Ix> { + pub fn unsorted_iter(&self) -> UnsIter<'_, T, V, Ix> { UnsIter::new(self) } /// Creates an unsorted iterator over all intervals `x..y`. - pub fn unsorted_intervals<'a>(&'a self) -> UnsIntervals<'a, T, V, Ix> { + pub fn unsorted_intervals(&self) -> UnsIntervals<'_, T, V, Ix> { UnsIntervals::new(self) } /// Creates an unsorted iterator over all values `&value`. - pub fn unsorted_values<'a>(&'a self) -> UnsValues<'a, T, V, Ix> { + pub fn unsorted_values(&self) -> UnsValues<'_, T, V, Ix> { UnsValues::new(self) } /// Creates an unsorted iterator over all pairs `(x..y, &mut value)`. - pub fn unsorted_iter_mut<'a>(&'a mut self) -> UnsIterMut<'a, T, V, Ix> { + pub fn unsorted_iter_mut(&mut self) -> UnsIterMut<'_, T, V, Ix> { UnsIterMut::new(self) } /// Creates an unsorted iterator over all mutable values `&mut value`. - pub fn unsorted_values_mut<'a>(&'a mut self) -> UnsValuesMut<'a, T, V, Ix> { + pub fn unsorted_values_mut(&mut self) -> UnsValuesMut<'_, T, V, Ix> { UnsValuesMut::new(self) } @@ -1161,11 +1244,15 @@ impl IntoIterator for IntervalMap FromIterator<(Range, V)> for IntervalMap { fn from_iter(iter: I) -> Self - where I: IntoIterator, V)> + where + I: IntoIterator, V)>, { let mut map = IntervalMap::new(); for (range, value) in iter { - assert!(map.insert(range, value).is_none(), "Cannot collect IntervalMap with duplicate intervals!"); + assert!( + map.insert(range, value).is_none(), + "Cannot collect IntervalMap with duplicate intervals!" + ); } map } @@ -1180,8 +1267,9 @@ impl Index> for IntervalMap IntervalMap -where T: PartialOrd + Copy + Default + AddAssign + Sub, - Ix: IndexType, +where + T: PartialOrd + Copy + Default + AddAssign + Sub, + Ix: IndexType, { /// Calculates the total length of the `query` that is covered by intervals in the map. /// Takes *O(log N + K)* where *K* is the number of intervals that overlap `query`. @@ -1197,7 +1285,8 @@ where T: PartialOrd + Copy + Default + AddAssign + Sub, /// assert_eq!(map.covered_len(..), 13); /// ``` pub fn covered_len(&self, query: R) -> T - where R: RangeBounds, + where + R: RangeBounds, { let mut res = T::default(); let start_bound = query.start_bound().cloned(); @@ -1272,7 +1361,7 @@ impl Debug for IntervalMa } else { need_comma = true; } - write!(f, "{:?} => {:?}", interval, value)?; + write!(f, "{interval:?} => {value:?}")?; } write!(f, "}}") } @@ -1280,24 +1369,24 @@ impl Debug for IntervalMa #[cfg(feature = "serde")] impl Serialize for IntervalMap - where - T: PartialOrd + Copy + Serialize, - V: Serialize, - Ix: IndexType + Serialize, +where + T: PartialOrd + Copy + Serialize, + V: Serialize, + Ix: IndexType + Serialize, { fn serialize(&self, serializer: S) -> Result { // For some reason, Vec does not support serialization. Because of that we create a newtype. struct NodeVecSer<'a, T, V, Ix>(&'a Vec>) - where - T: PartialOrd + Copy + Serialize, - V: Serialize, - Ix: IndexType + Serialize; + where + T: PartialOrd + Copy + Serialize, + V: Serialize, + Ix: IndexType + Serialize; impl<'a, T, V, Ix> Serialize for NodeVecSer<'a, T, V, Ix> - where - T: PartialOrd + Copy + Serialize, - V: Serialize, - Ix: IndexType + Serialize, + where + T: PartialOrd + Copy + Serialize, + V: Serialize, + Ix: IndexType + Serialize, { fn serialize(&self, serializer: S) -> Result { let mut seq = serializer.serialize_seq(Some(self.0.len()))?; @@ -1322,10 +1411,10 @@ struct NodeVecDe(Vec>); #[cfg(feature = "serde")] impl<'de, T, V, Ix> Deserialize<'de> for NodeVecDe - where - T: PartialOrd + Copy + Deserialize<'de>, - V: Deserialize<'de>, - Ix: IndexType + Deserialize<'de>, +where + T: PartialOrd + Copy + Deserialize<'de>, + V: Deserialize<'de>, + Ix: IndexType + Deserialize<'de>, { fn deserialize>(deserializer: D) -> Result { struct NodeVecVisitor { @@ -1368,7 +1457,10 @@ where Ix: IndexType + Deserialize<'de>, { fn deserialize>(deserializer: D) -> Result { - let (node_vec, colors, root) = <(NodeVecDe, BitVec, Ix)>::deserialize(deserializer)?; + // XXX changing to Option may have changed the serialization format. Need to + // implement serialize/deserialize for Option to match old format? + let (node_vec, colors, root) = + <(NodeVecDe, BitVec, Option)>::deserialize(deserializer)?; Ok(IntervalMap { nodes: node_vec.0, colors, @@ -1377,6 +1469,28 @@ where } } +#[macro_export] +macro_rules! nonzero { + ( u8 ) => { + core::num::NonZeroU8 + }; + ( u16 ) => { + core::num::NonZeroU16 + }; + ( u32 ) => { + core::num::NonZeroU32 + }; + ( u64 ) => { + core::num::NonZeroU64 + }; + ( u128 ) => { + core::num::NonZeroU128 + }; + ( usize ) => { + core::num::NonZeroUsize + }; +} + /// Macros for [IntervalMap](struct.IntervalMap.html) creation. /// ```rust /// #[macro_use] extern crate iset; @@ -1393,17 +1507,19 @@ where #[macro_export] macro_rules! interval_map { // Create an empty interval map given the index type. - ( [$ix:ty] $(,)? ) => ( $crate::IntervalMap::<_, _, $ix>::default() ); + ( [$ix:ident] $(,)? ) => {{ + $crate::IntervalMap::<_, _, $crate::nonzero!($ix)>::default() + }}; // Create an empty interval map given the default index type. ( () ) => ( $crate::IntervalMap::new() ); // Create a filled interval map given the index type. - ( [$ix:ty] $(,)? $( $k:expr => $v:expr ),* $(,)? ) => { + ( [$ix:ident] $(,)? $( $k:expr => $v:expr ),* $(,)? ) => { { - let mut _temp_map = $crate::IntervalMap::<_, _, $ix>::default(); + let mut _temp_map = $crate::IntervalMap::<_, _, $crate::nonzero!($ix)>::default(); $( - assert!(_temp_map.insert($k, $v).is_none(), "Cannot use interval_map!{ ... } with duplicate intervals"); + assert!(_temp_map.insert($k, $v).is_none(), "Cannot use interval_map!{{ ... }} with duplicate intervals"); )* _temp_map } @@ -1414,7 +1530,7 @@ macro_rules! interval_map { { let mut _temp_map = $crate::IntervalMap::new(); $( - assert!(_temp_map.insert($k, $v).is_none(), "Cannot use interval_map!{ ... } with duplicate intervals"); + assert!(_temp_map.insert($k, $v).is_none(), "Cannot use interval_map!{{ ... }} with duplicate intervals"); )* _temp_map } @@ -1435,15 +1551,17 @@ macro_rules! interval_map { #[macro_export] macro_rules! interval_set { // Create an empty interval set given the index type. - ( [$ix:ty] $(,)? ) => ( $crate::IntervalSet::<_, $ix>::default() ); + ( [$ix:ident] $(,)? ) => {{ + $crate::IntervalSet::<_, _, $crate::nonzero!($ix)>::default() + }}; // Create an empty interval set given with the default index type. ( () ) => ( $crate::IntervalSet::new() ); // Create a filled interval set given the index type. - ( [$ix:ty] $(,)? $( $k:expr ),* $(,)? ) => { + ( [$ix:ident] $(,)? $( $k:expr ),* $(,)? ) => { { - let mut _temp_set = $crate::IntervalSet::<_, $ix>::default(); + let mut _temp_set = $crate::IntervalSet::<_, $crate::nonzero!($ix)>::default(); $( _temp_set.insert($k); )* diff --git a/src/set.rs b/src/set.rs index a5e2825..6c8ff68 100644 --- a/src/set.rs +++ b/src/set.rs @@ -1,18 +1,18 @@ //! `IntervalSet` implementation. -use core::ops::{Range, RangeInclusive, RangeBounds, RangeFull, AddAssign, Sub}; -use core::fmt::{self, Debug, Formatter}; -use core::iter::{FromIterator, IntoIterator}; #[cfg(feature = "dot")] use core::fmt::Display; +use core::fmt::{self, Debug, Formatter}; +use core::iter::{FromIterator, IntoIterator}; +use core::ops::{AddAssign, Range, RangeBounds, RangeFull, RangeInclusive, Sub}; +#[cfg(feature = "serde")] +use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "dot")] use std::io::{self, Write}; -#[cfg(feature = "serde")] -use serde::{Serialize, Serializer, Deserialize, Deserializer}; -use super::IntervalMap; -use super::ix::{IndexType, DefaultIx}; use super::iter::*; +use super::ix::{DefaultIx, IndexType}; +use super::IntervalMap; /// Set with interval keys (ranges `x..y`). Newtype over `IntervalMap`. /// See [IntervalMap](../struct.IntervalMap.html) for more information. @@ -59,8 +59,9 @@ use super::iter::*; /// [force_insert](../struct.IntervalMap.html#method.force_insert), and completely forbids duplicate intervals. #[derive(Clone)] pub struct IntervalSet -where T: PartialOrd + Copy, - Ix: IndexType, +where + T: PartialOrd + Copy, + Ix: IndexType, { inner: IntervalMap, } @@ -93,7 +94,8 @@ impl IntervalSet { /// /// Panics if the intervals are not sorted or if there are equal intervals. pub fn from_sorted(iter: I) -> Self - where I: Iterator>, + where + I: Iterator>, { Self { inner: IntervalMap::from_sorted(iter.map(|range| (range, ()))), @@ -182,7 +184,9 @@ impl IntervalSet { /// Equivalent to `set.iter(query).next().is_some()`, but much faster. #[inline] pub fn has_overlap(&self, query: R) -> bool - where R: RangeBounds, { + where + R: RangeBounds, + { self.inner.has_overlap(query) } @@ -191,29 +195,31 @@ impl IntervalSet { /// Output is sorted by intervals. /// /// Panics if `interval` is empty or contains a value that cannot be compared (such as `NAN`). - pub fn iter<'a, R>(&'a self, query: R) -> Intervals<'a, T, (), R, Ix> - where R: RangeBounds, + pub fn iter(&self, query: R) -> Intervals<'_, T, (), R, Ix> + where + R: RangeBounds, { self.inner.intervals(query) } /// Iterates over intervals `x..y` that overlap the `point`. Same as `iter(point..=point)`. /// See [iter](#method.iter) for more details. - pub fn overlap<'a>(&'a self, point: T) -> Intervals<'a, T, (), RangeInclusive, Ix> { + pub fn overlap(&self, point: T) -> Intervals<'_, T, (), RangeInclusive, Ix> { self.inner.intervals(point..=point) } /// Consumes [IntervalSet](struct.IntervalSet.html) and iterates over intervals `x..y` that overlap the `query`. /// See [iter](#method.iter) for more details. pub fn into_iter(self, query: R) -> IntoIntervals - where R: RangeBounds, + where + R: RangeBounds, { IntoIntervals::new(self.inner, query) } /// Creates an unsorted iterator over all intervals `x..y`. /// Slightly faster than the sorted iterator, although both take *O(N)*. - pub fn unsorted_iter<'a>(&'a self) -> UnsIntervals<'a, T, (), Ix> { + pub fn unsorted_iter(&self) -> UnsIntervals<'_, T, (), Ix> { UnsIntervals::new(&self.inner) } @@ -244,8 +250,9 @@ impl FromIterator> for IntervalSet { } impl IntervalSet -where T: PartialOrd + Copy + Default + AddAssign + Sub, - Ix: IndexType, +where + T: PartialOrd + Copy + Default + AddAssign + Sub, + Ix: IndexType, { /// Calculates the total length of the `query` that is covered by intervals in the map. /// Takes *O(log N + K)* where *K* is the number of intervals that overlap `query`. @@ -253,7 +260,8 @@ where T: PartialOrd + Copy + Default + AddAssign + Sub, /// See [IntervalMap::covered_len](../struct.IntervalMap.html#method.covered_len) for more details. #[inline] pub fn covered_len(&self, query: R) -> T - where R: RangeBounds + where + R: RangeBounds, { self.inner.covered_len(query) } @@ -277,7 +285,7 @@ impl Debug for IntervalSet { } else { need_comma = true; } - write!(f, "{:?}", interval)?; + write!(f, "{interval:?}")?; } write!(f, "}}") } @@ -304,4 +312,4 @@ where let inner = >::deserialize(deserializer)?; Ok(IntervalSet { inner }) } -} \ No newline at end of file +} diff --git a/src/tests.rs b/src/tests.rs index 9e626e9..cd3b8bf 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -2,22 +2,32 @@ extern crate rand; #[cfg(feature = "serde")] extern crate serde_json; -use std::string::String; -use std::ops::{self, Range, RangeBounds, Bound}; +use core::num::NonZeroU32; +use rand::prelude::*; use std::fmt::{Debug, Write}; use std::fs::File; +use std::ops::{self, Bound, Range, RangeBounds}; use std::path::Path; -use rand::prelude::*; +use std::string::String; use super::*; /// Returns distance to leaves (only black nodes). -fn validate_tree_recursive(tree: &IntervalMap, index: Ix, upper_interval: &mut Interval, - visited: &mut BitVec) -> u32 -where T: PartialOrd + Copy, - Ix: IndexType, +fn validate_tree_recursive( + tree: &IntervalMap, + index: Ix, + upper_interval: &mut Interval, + visited: &mut BitVec, +) -> u32 +where + T: PartialOrd + Copy, + Ix: IndexType, { - assert!(!visited.get(index.get()), "The tree contains a cycle: node {} was visited twice", index); + assert!( + !visited.get(index.get()), + "The tree contains a cycle: node {} was visited twice", + index + ); visited.set(index.get(), true); let node = &tree.nodes[index.get()]; @@ -25,28 +35,58 @@ where T: PartialOrd + Copy, let left = node.left; let right = node.right; - let left_depth = if left.defined() { + let left_depth = if let Some(left) = left { if tree.is_red(index) { - assert!(tree.is_black(left), "Red node {} has a red child {}", index, left); + assert!( + tree.is_black(left), + "Red node {} has a red child {}", + index, + left + ); } - Some(validate_tree_recursive(tree, left, &mut down_interval, visited)) + Some(validate_tree_recursive( + tree, + left, + &mut down_interval, + visited, + )) } else { None }; - let right_depth = if right.defined() { + let right_depth = if let Some(right) = right { if tree.is_red(index) { - assert!(tree.is_black(right), "Red node {} has a red child {}", index, right); + assert!( + tree.is_black(right), + "Red node {} has a red child {}", + index, + right + ); } - Some(validate_tree_recursive(tree, right, &mut down_interval, visited)) + Some(validate_tree_recursive( + tree, + right, + &mut down_interval, + visited, + )) } else { None }; - assert!(down_interval == node.subtree_interval, "Interval != subtree interval for node {}", index); + assert!( + down_interval == node.subtree_interval, + "Interval != subtree interval for node {}", + index + ); upper_interval.extend(&down_interval); match (left_depth, right_depth) { - (Some(x), Some(y)) => assert!(x == y, "Node {} has different depths to leaves: {} != {}", index, x, y), - _ => {}, + (Some(x), Some(y)) => assert!( + x == y, + "Node {} has different depths to leaves: {} != {}", + index, + x, + y + ), + _ => {} } let depth = left_depth.or(right_depth).unwrap_or(0); if tree.is_black(index) { @@ -58,29 +98,54 @@ where T: PartialOrd + Copy, fn validate(tree: &IntervalMap, size: usize) { assert_eq!(size, tree.len(), "Tree sizes do not match"); - assert_eq!(size > 0, tree.root.defined(), "Tree root != size"); - assert_eq!(tree.len(), tree.colors.len(), "Number of nodes != number of colors"); - - if !tree.root.defined() { - assert!(tree.nodes.is_empty(), "Non empty nodes with an empty root"); - return; - } + assert_eq!(size > 0, tree.root.is_some(), "Tree root != size"); + assert_eq!( + tree.len(), + tree.colors.len(), + "Number of nodes != number of colors" + ); + + let root = match tree.root { + Some(root) => root, + None => { + assert!(tree.nodes.is_empty(), "Non empty nodes with an empty root"); + return; + } + }; for i in 0..tree.nodes.len() { - if i == tree.root.get() { - assert!(!tree.nodes[i].parent.defined(), "Root {} has a parent {}", i, tree.nodes[i].parent); + if i == root.get() { + assert!( + !tree.nodes[i].parent.is_some(), + "Root {} has a parent {}", + i, + tree.nodes[i].parent.unwrap() + ); } else { - assert!(tree.nodes[i].parent.defined(), "Non-root {} has an empty parent (root is {})", i, tree.root); + assert!( + tree.nodes[i].parent.is_some(), + "Non-root {} has an empty parent (root is {})", + i, + root + ); } } - let node = &tree.nodes[tree.root.get()]; + let node = tree.node(root); let mut interval = node.interval.clone(); let mut visited = BitVec::from_elem(tree.nodes.len(), false); - validate_tree_recursive(tree, tree.root, &mut interval, &mut visited); - assert!(interval == node.subtree_interval, "Interval != subtree interval for node {}", tree.root); + validate_tree_recursive(tree, root, &mut interval, &mut visited); + assert!( + interval == node.subtree_interval, + "Interval != subtree interval for node {}", + root + ); for i in 0..tree.len() { - assert!(visited.get(i), "The tree is disjoint: node {} has no connection to the root", i); + assert!( + visited.get(i), + "The tree is disjoint: node {} has no connection to the root", + i + ); } } @@ -89,9 +154,7 @@ fn intersects>(range: &Range, query: &R) -> Bound::Included(value) => value >= &range.start, Bound::Excluded(value) => value > &range.start, Bound::Unbounded => true, - }) - && - (match query.start_bound() { + }) && (match query.start_bound() { Bound::Included(value) | Bound::Excluded(value) => value < &range.end, Bound::Unbounded => true, }) @@ -107,9 +170,7 @@ struct NaiveIntervalMap { impl NaiveIntervalMap { fn new() -> Self { - Self { - nodes: Vec::new(), - } + Self { nodes: Vec::new() } } fn len(&self) -> usize { @@ -120,13 +181,21 @@ impl NaiveIntervalMap { self.nodes.push((range, value)); } - fn iter<'a, R: 'a + RangeBounds>(&'a self, query: R) -> impl Iterator, &V)> + 'a { - self.nodes.iter().filter(move |(range, _value)| intersects(range, &query)) + fn iter<'a, R: 'a + RangeBounds>( + &'a self, + query: R, + ) -> impl Iterator, &V)> + 'a { + self.nodes + .iter() + .filter(move |(range, _value)| intersects(range, &query)) .map(|(range, value)| (range.clone(), value)) } - fn all_matching<'a>(&'a self, query: Range) -> impl Iterator + 'a { - self.nodes.iter().filter(move |(range, _value)| range_eq(&range, &query)).map(|(_range, value)| value) + fn all_matching(&self, query: Range) -> impl Iterator + '_ { + self.nodes + .iter() + .filter(move |(range, _value)| range_eq(range, &query)) + .map(|(_range, value)| value) } fn remove_random(&mut self, rng: &mut impl Rng) -> (Range, V) { @@ -175,7 +244,10 @@ impl NaiveIntervalMap { } } -fn generate_ordered_pair T>(generator: &mut F, forbid_eq: bool) -> (T, T) { +fn generate_ordered_pair T>( + generator: &mut F, + forbid_eq: bool, +) -> (T, T) { let a = generator(); let mut b = generator(); while forbid_eq && a == b { @@ -188,10 +260,15 @@ fn generate_ordered_pair T>(generator: &mut } } -fn modify_maps(naive: &mut NaiveIntervalMap, tree: &mut IntervalMap, n_inserts: u32, - mut generator: F) -> String -where T: PartialOrd + Copy + Debug, - F: FnMut() -> Range, +fn modify_maps( + naive: &mut NaiveIntervalMap, + tree: &mut IntervalMap, + n_inserts: u32, + mut generator: F, +) -> String +where + T: PartialOrd + Copy + Debug, + F: FnMut() -> Range, { let mut history = String::new(); for i in 0..n_inserts { @@ -199,7 +276,11 @@ where T: PartialOrd + Copy + Debug, writeln!(history, "insert({:?})", range).unwrap(); naive.insert(range.clone(), i); if let Some(value) = tree.insert(range.clone(), i) { - let i = naive.nodes.iter().position(|(range2, _value2)| range == *range2).unwrap(); + let i = naive + .nodes + .iter() + .position(|(range2, _value2)| range == *range2) + .unwrap(); assert_eq!(naive.nodes[i].1, value); naive.nodes.swap_remove(i); } @@ -208,11 +289,16 @@ where T: PartialOrd + Copy + Debug, } fn save_iter<'a, T, I>(iter: I) -> Vec<(Range, u32)> -where T: PartialOrd + Copy, - I: Iterator, &'a u32)>, +where + T: PartialOrd + Copy, + I: Iterator, &'a u32)>, { let mut res: Vec<_> = iter.map(|(range, value)| (range, *value)).collect(); - res.sort_by(|a, b| (a.0.start, a.0.end, a.1).partial_cmp(&(b.0.start, b.0.end, b.1)).unwrap()); + res.sort_by(|a, b| { + (a.0.start, a.0.end, a.1) + .partial_cmp(&(b.0.start, b.0.end, b.1)) + .unwrap() + }); res } @@ -232,16 +318,18 @@ fn generate_float_rounding() -> impl (FnMut() -> f64) { move || (rng.gen::() * MULT).round() / MULT } -fn generate_range T>(mut generator: F) - -> impl (FnMut() -> Range) { +fn generate_range T>( + mut generator: F, +) -> impl (FnMut() -> Range) { move || { let (a, b) = generate_ordered_pair(&mut generator, true); a..b } } -fn generate_range_from T>(mut generator: F) - -> impl (FnMut() -> ops::RangeFrom) { +fn generate_range_from T>( + mut generator: F, +) -> impl (FnMut() -> ops::RangeFrom) { move || generator().. } @@ -249,29 +337,37 @@ fn generate_range_full() -> ops::RangeFull { .. } -fn generate_range_incl T>(mut generator: F) - -> impl (FnMut() -> ops::RangeInclusive) { +fn generate_range_incl T>( + mut generator: F, +) -> impl (FnMut() -> ops::RangeInclusive) { move || { let (a, b) = generate_ordered_pair(&mut generator, false); a..=b } } -fn generate_range_to T>(mut generator: F) - -> impl (FnMut() -> ops::RangeTo) { +fn generate_range_to T>( + mut generator: F, +) -> impl (FnMut() -> ops::RangeTo) { move || ..generator() } -fn generate_range_to_incl T>(mut generator: F) - -> impl (FnMut() -> ops::RangeToInclusive) { +fn generate_range_to_incl T>( + mut generator: F, +) -> impl (FnMut() -> ops::RangeToInclusive) { move || ..=generator() } -fn search_rand(naive: &mut NaiveIntervalMap, tree: &mut IntervalMap, n_searches: u32, - mut range_generator: F, history: &str) -where T: PartialOrd + Copy + Debug, - R: RangeBounds + Debug + Clone, - F: FnMut() -> R, +fn search_rand( + naive: &mut NaiveIntervalMap, + tree: &mut IntervalMap, + n_searches: u32, + mut range_generator: F, + history: &str, +) where + T: PartialOrd + Copy + Debug, + R: RangeBounds + Debug + Clone, + F: FnMut() -> R, { for _ in 0..n_searches { let range = range_generator(); @@ -293,10 +389,17 @@ where T: PartialOrd + Copy + Debug, } fn compare_extremums(naive: &NaiveIntervalMap, tree: &IntervalMap, history: &str) -where T: PartialOrd + Copy + Debug +where + T: PartialOrd + Copy + Debug, { - let smallest_a = naive.nodes.iter() - .min_by(|a, b| (a.0.start, a.0.end, a.1).partial_cmp(&(b.0.start, b.0.end, b.1)).unwrap()) + let smallest_a = naive + .nodes + .iter() + .min_by(|a, b| { + (a.0.start, a.0.end, a.1) + .partial_cmp(&(b.0.start, b.0.end, b.1)) + .unwrap() + }) .map(|(interval, _)| interval.clone()); let smallest_b = tree.smallest().map(|(interval, _)| interval); if smallest_a != smallest_b { @@ -305,8 +408,14 @@ where T: PartialOrd + Copy + Debug assert_eq!(smallest_a, smallest_b); } - let largest_a = naive.nodes.iter() - .max_by(|a, b| (a.0.start, a.0.end, a.1).partial_cmp(&(b.0.start, b.0.end, b.1)).unwrap()) + let largest_a = naive + .nodes + .iter() + .max_by(|a, b| { + (a.0.start, a.0.end, a.1) + .partial_cmp(&(b.0.start, b.0.end, b.1)) + .unwrap() + }) .map(|(interval, _)| interval.clone()); let largest_b = tree.largest().map(|(interval, _)| interval); if largest_a != largest_b { @@ -316,8 +425,13 @@ where T: PartialOrd + Copy + Debug } } -fn compare_match_results(naive: &NaiveIntervalMap, tree: &IntervalMap, history: &str, range: Range) -where T: PartialOrd + Copy + Clone + Debug +fn compare_match_results( + naive: &NaiveIntervalMap, + tree: &IntervalMap, + history: &str, + range: Range, +) where + T: PartialOrd + Copy + Clone + Debug, { let values: Vec = naive.all_matching(range.clone()).map(|v| *v).collect(); let mut correct = true; @@ -327,17 +441,26 @@ where T: PartialOrd + Copy + Clone + Debug None => values.is_empty(), }; if !correct { - println!("Range: {:?}, values: {:?}, tree.get: {:?}", range, values, tree.get(range.clone())); + println!( + "Range: {:?}, values: {:?}, tree.get: {:?}", + range, + values, + tree.get(range.clone()) + ); println!("{}", history); println!(); panic!(); } } -fn compare_exact_matching(naive: &NaiveIntervalMap, tree: &IntervalMap, history: &str, - mut generator: F) -where T: PartialOrd + Copy + Debug, - F: FnMut() -> Range, +fn compare_exact_matching( + naive: &NaiveIntervalMap, + tree: &IntervalMap, + history: &str, + mut generator: F, +) where + T: PartialOrd + Copy + Debug, + F: FnMut() -> Range, { for (range, _value) in &naive.nodes { compare_match_results(naive, tree, history, range.clone()); @@ -348,10 +471,15 @@ where T: PartialOrd + Copy + Debug, } } -fn check_covered_len(naive: &NaiveIntervalMap, tree: &IntervalMap, - count: u32, mut generator: F, history: &str) -where R: RangeBounds + Clone + Debug, - F: FnMut() -> R, +fn check_covered_len( + naive: &NaiveIntervalMap, + tree: &IntervalMap, + count: u32, + mut generator: F, + history: &str, +) where + R: RangeBounds + Clone + Debug, + F: FnMut() -> R, { for _ in 0..count { let query = generator(); @@ -360,7 +488,10 @@ where R: RangeBounds + Clone + Debug, if len1 != len2 { println!("{}", history); println!(); - println!("Query = {:?}, naive len = {}, map len = {}", query, len1, len2); + println!( + "Query = {:?}, naive len = {}, map len = {}", + query, len1, len2 + ); panic!(); } assert_eq!(len1, len2); @@ -377,11 +508,13 @@ where loop { match (iter1.next(), iter2.next()) { (None, None) => break, - (x, y) => if x != y { - println!("{}", history); - println!(); - assert_eq!(x, y); - }, + (x, y) => { + if x != y { + println!("{}", history); + println!(); + assert_eq!(x, y); + } + } } } } @@ -391,7 +524,12 @@ fn test_int_inserts() { const COUNT: u32 = 1000; let mut naive = NaiveIntervalMap::new(); let mut tree = IntervalMap::new(); - let history = modify_maps(&mut naive, &mut tree, COUNT, generate_range(generate_int(20, 120))); + let history = modify_maps( + &mut naive, + &mut tree, + COUNT, + generate_range(generate_int(20, 120)), + ); let output_path = Path::new("tests/data/int.dot"); let folders = output_path.parent().unwrap(); @@ -403,12 +541,42 @@ fn test_int_inserts() { let mut generator = generate_int(0, 140); compare_exact_matching(&naive, &tree, &history, generate_range(&mut generator)); - search_rand(&mut naive, &mut tree, COUNT, generate_range(&mut generator), &history); - search_rand(&mut naive, &mut tree, COUNT, generate_range_from(&mut generator), &history); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range(&mut generator), + &history, + ); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range_from(&mut generator), + &history, + ); search_rand(&mut naive, &mut tree, 1, generate_range_full, &history); - search_rand(&mut naive, &mut tree, COUNT, generate_range_incl(&mut generator), &history); - search_rand(&mut naive, &mut tree, COUNT, generate_range_to(&mut generator), &history); - search_rand(&mut naive, &mut tree, COUNT, generate_range_to_incl(&mut generator), &history); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range_incl(&mut generator), + &history, + ); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range_to(&mut generator), + &history, + ); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range_to_incl(&mut generator), + &history, + ); } #[test] @@ -416,16 +584,51 @@ fn test_covered_len() { const COUNT: u32 = 1000; let mut naive = NaiveIntervalMap::new(); let mut tree = IntervalMap::new(); - let history = modify_maps(&mut naive, &mut tree, COUNT, generate_range(generate_int(-500, 500))); + let history = modify_maps( + &mut naive, + &mut tree, + COUNT, + generate_range(generate_int(-500, 500)), + ); validate(&tree, naive.len()); let mut generator = generate_int(-510, 510); - check_covered_len(&mut naive, &mut tree, COUNT, generate_range(&mut generator), &history); - check_covered_len(&mut naive, &mut tree, COUNT, generate_range_from(&mut generator), &history); + check_covered_len( + &mut naive, + &mut tree, + COUNT, + generate_range(&mut generator), + &history, + ); + check_covered_len( + &mut naive, + &mut tree, + COUNT, + generate_range_from(&mut generator), + &history, + ); check_covered_len(&mut naive, &mut tree, 1, generate_range_full, &history); - check_covered_len(&mut naive, &mut tree, COUNT, generate_range_incl(&mut generator), &history); - check_covered_len(&mut naive, &mut tree, COUNT, generate_range_to(&mut generator), &history); - check_covered_len(&mut naive, &mut tree, COUNT, generate_range_to_incl(&mut generator), &history); + check_covered_len( + &mut naive, + &mut tree, + COUNT, + generate_range_incl(&mut generator), + &history, + ); + check_covered_len( + &mut naive, + &mut tree, + COUNT, + generate_range_to(&mut generator), + &history, + ); + check_covered_len( + &mut naive, + &mut tree, + COUNT, + generate_range_to_incl(&mut generator), + &history, + ); } #[test] @@ -433,7 +636,12 @@ fn test_float_inserts() { const COUNT: u32 = 1000; let mut naive = NaiveIntervalMap::new(); let mut tree = IntervalMap::new(); - let history = modify_maps(&mut naive, &mut tree, COUNT, generate_range(generate_float(0.0, 1000.0))); + let history = modify_maps( + &mut naive, + &mut tree, + COUNT, + generate_range(generate_float(0.0, 1000.0)), + ); let output_path = Path::new("tests/data/float.dot"); let folders = output_path.parent().unwrap(); @@ -444,23 +652,53 @@ fn test_float_inserts() { compare_extremums(&naive, &tree, &history); let mut generator = generate_float(-50.0, 1050.0); - search_rand(&mut naive, &mut tree, COUNT, generate_range(&mut generator), &history); - search_rand(&mut naive, &mut tree, COUNT, generate_range_from(&mut generator), &history); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range(&mut generator), + &history, + ); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range_from(&mut generator), + &history, + ); search_rand(&mut naive, &mut tree, 1, generate_range_full, &history); - search_rand(&mut naive, &mut tree, COUNT, generate_range_incl(&mut generator), &history); - search_rand(&mut naive, &mut tree, COUNT, generate_range_to(&mut generator), &history); - search_rand(&mut naive, &mut tree, COUNT, generate_range_to_incl(&mut generator), &history); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range_incl(&mut generator), + &history, + ); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range_to(&mut generator), + &history, + ); + search_rand( + &mut naive, + &mut tree, + COUNT, + generate_range_to_incl(&mut generator), + &history, + ); } #[test] fn test_from_sorted() { const COUNT: u32 = 1000; let mut vec = Vec::new(); - let mut map: IntervalMap<_, _, u32> = IntervalMap::from_sorted(vec.clone().into_iter()); + let mut map: IntervalMap<_, _, NonZeroU32> = IntervalMap::from_sorted(vec.clone().into_iter()); validate(&map, 0); for i in 0..COUNT { - vec.push((i..i+1, i)); + vec.push((i..i + 1, i)); map = IntervalMap::from_sorted(vec.clone().into_iter()); assert_eq!(map.len(), vec.len()); validate(&map, vec.len()); @@ -477,7 +715,12 @@ fn test_serde() { const COUNT: u32 = 1000; let mut naive = NaiveIntervalMap::new(); let mut tree: IntervalMap = IntervalMap::new(); - let history = modify_maps(&mut naive, &mut tree, COUNT, generate_range(generate_int(0, 10000))); + let history = modify_maps( + &mut naive, + &mut tree, + COUNT, + generate_range(generate_int(0, 10000)), + ); let json_path = Path::new("tests/data/serde.json"); let folders = json_path.parent().unwrap(); diff --git a/src/tree_rm.rs b/src/tree_rm.rs index 66d8b92..56b779a 100644 --- a/src/tree_rm.rs +++ b/src/tree_rm.rs @@ -1,13 +1,21 @@ - use super::*; impl IntervalMap { /// Swap values and intervals for `i`-th and `j`-th nodes. - unsafe fn swap_nodes(&mut self, i: Ix, j: Ix) { - let ptr = self.nodes.as_mut_ptr(); - let ptr_i = ptr.add(i.get()); - let ptr_j = ptr.add(j.get()); - (*ptr_i).swap_with(&mut *ptr_j); + fn swap_nodes(&mut self, i: Ix, j: Ix) { + let ptr_i = core::ptr::addr_of_mut!(self.nodes[i.get()].value); + let ptr_j = core::ptr::addr_of_mut!(self.nodes[j.get()].value); + unsafe { + core::ptr::swap(ptr_i, ptr_j); + } + + let tmp = self.node(i).interval.clone(); + self.node_mut(i).interval = self.node(j).interval.clone(); + self.node_mut(j).interval = tmp; + + let tmp = self.node(i).subtree_interval.clone(); + self.node_mut(i).subtree_interval = self.node(j).subtree_interval.clone(); + self.node_mut(j).subtree_interval = tmp; } /// Removes node at index i by swapping it with the last node. @@ -22,67 +30,66 @@ impl IntervalMap { } let ix = Ix::new(i).unwrap(); - let left = self.nodes[i].left; - if left.defined() { - self.nodes[left.get()].parent = ix; + if let Some(left) = self.node(ix).left { + self.node_mut(left).parent = Some(ix); } - - let right = self.nodes[i].right; - if right.defined() { - self.nodes[right.get()].parent = ix; + if let Some(right) = self.node(ix).right { + self.node_mut(right).parent = Some(ix); } - let parent = self.nodes[i].parent; let old_ix = Ix::new(self.nodes.len()).unwrap(); - if parent.defined() { - let parent_node = &mut self.nodes[parent.get()]; - if parent_node.left == old_ix { - parent_node.left = ix; + if let Some(parent) = self.node(ix).parent { + let parent_node = self.node_mut(parent); + if parent_node.left == Some(old_ix) { + parent_node.left = Some(ix); } else { - debug_assert!(parent_node.right == old_ix); - parent_node.right = ix; + debug_assert!(parent_node.right == Some(old_ix)); + parent_node.right = Some(ix); } } - if self.root == old_ix { - self.root = ix; + if self.root == Some(old_ix) { + self.root = Some(ix); } removed_val } fn remove_child(&mut self, parent: Ix, child: Ix) { - let parent_node = &mut self.nodes[parent.get()]; - if parent_node.left == child { - parent_node.left = Ix::MAX; + let parent_node = self.node_mut(parent); + if parent_node.left == Some(child) { + parent_node.left = None; } else { - debug_assert!(parent_node.right == child); - parent_node.right = Ix::MAX; + debug_assert!(parent_node.right == Some(child)); + parent_node.right = None; } } - fn set_child(&mut self, parent: Ix, child: Ix, left_side: bool) { - if child.defined() { - self.nodes[child.get()].parent = parent; + fn set_child(&mut self, parent: Ix, child: Option, left_side: bool) { + if let Some(child) = child { + self.node_mut(child).parent = Some(parent); } if left_side { - self.nodes[parent.get()].left = child; + self.node_mut(parent).left = child; } else { - self.nodes[parent.get()].right = child; + self.node_mut(parent).right = child; } } fn replace_children(&mut self, prev_child: Ix, new_child: Ix) { - let parent = self.nodes[prev_child.get()].parent; - if parent.defined() { - if self.nodes[parent.get()].left == prev_child { - self.nodes[parent.get()].left = new_child; - } else { - self.nodes[parent.get()].right = new_child; + match self.node(prev_child).parent { + Some(parent) => { + let parent_node = self.node_mut(parent); + if parent_node.left == Some(prev_child) { + parent_node.left = Some(new_child); + } else { + parent_node.right = Some(new_child); + } + self.node_mut(new_child).parent = Some(parent); + } + None => { + self.node_mut(new_child).parent = None; + self.root = Some(new_child); } - self.nodes[new_child.get()].parent = parent; - } else { - self.nodes[new_child.get()].parent = Ix::MAX; - self.root = new_child; } } @@ -91,30 +98,42 @@ impl IntervalMap { fn restructure_rm_complex_cases(&mut self, mut ix: Ix) { loop { debug_assert!(self.is_black(ix)); - let node = &self.nodes[ix.get()]; - let parent_ix = node.parent; - - // Case (terminal): Node is the root of the tree. - if !parent_ix.defined() { - debug_assert!(self.root == ix); - return; - } + let node = self.node(ix); + let parent_ix = match node.parent { + Some(parent) => parent, + None => { + // Case (terminal): Node is the root of the tree. + debug_assert!(self.root == Some(ix)); + return; + } + }; - let parent = &self.nodes[parent_ix.get()]; + let parent = self.node(parent_ix); let parent_black = self.is_black(parent_ix); - let node_is_left = parent.left == ix; - let sibling_ix = if node_is_left { parent.right } else { parent.left }; - let (close_nephew_ix, distant_nephew_ix) = if sibling_ix.defined() { - let sibling = &self.nodes[sibling_ix.get()]; - if node_is_left { (sibling.left, sibling.right) } else { (sibling.right, sibling.left) } + let node_is_left = parent.left == Some(ix); + let sibling_ix = if node_is_left { + parent.right } else { - (Ix::MAX, Ix::MAX) + parent.left + }; + let (close_nephew_ix, distant_nephew_ix) = if let Some(sibling_ix) = sibling_ix { + let sibling = self.node(sibling_ix); + if node_is_left { + (sibling.left, sibling.right) + } else { + (sibling.right, sibling.left) + } + } else { + (None, None) }; let sibling_black = self.is_black_or_nil(sibling_ix); let close_nephew_black = self.is_black_or_nil(close_nephew_ix); let distant_nephew_black = self.is_black_or_nil(distant_nephew_ix); + // XXX not clear why this is OK, we just handled it being None above + let sibling_ix = sibling_ix.unwrap(); + if parent_black && close_nephew_black && distant_nephew_black { if sibling_black { // Case: Node has black parent and black sibling, both nephews are black. @@ -125,7 +144,7 @@ impl IntervalMap { self.set_red(parent_ix); self.set_black(sibling_ix); self.replace_children(parent_ix, sibling_ix); - self.set_child(sibling_ix, parent_ix, node_is_left); + self.set_child(sibling_ix, Some(parent_ix), node_is_left); self.set_child(parent_ix, close_nephew_ix, !node_is_left); } } @@ -137,93 +156,102 @@ impl IntervalMap { } // Case: Node has any parent, sibling and distant nephew, but close nephew is red. else if sibling_black && distant_nephew_black && !close_nephew_black { + let close_nephew_ix = close_nephew_ix.unwrap(); // !black_or_nil self.set_black(close_nephew_ix); self.set_red(sibling_ix); let close_newphew_child2 = if node_is_left { - self.nodes[close_nephew_ix.get()].right + self.node(close_nephew_ix).right } else { - self.nodes[close_nephew_ix.get()].left + self.node(close_nephew_ix).left }; self.set_child(sibling_ix, close_newphew_child2, node_is_left); - self.set_child(close_nephew_ix, sibling_ix, !node_is_left); - self.set_child(parent_ix, close_nephew_ix, !node_is_left); + self.set_child(close_nephew_ix, Some(sibling_ix), !node_is_left); + self.set_child(parent_ix, Some(close_nephew_ix), !node_is_left); self.update_subtree_interval(sibling_ix); self.update_subtree_interval(close_nephew_ix); } // Case (terminal): any parent, black sibling, any close sibling and any red distant nephew. else { debug_assert!(sibling_black && !distant_nephew_black); - // parent's color -> sibling's color. - self.colors.set(sibling_ix.get(), self.colors.get(parent_ix.get())); + let distant_nephew_ix = distant_nephew_ix.unwrap(); // !black_or_nil + // parent's color -> sibling's color. + self.colors + .set(sibling_ix.get(), self.colors.get(parent_ix.get())); self.set_black(parent_ix); self.set_black(distant_nephew_ix); self.replace_children(parent_ix, sibling_ix); self.set_child(parent_ix, close_nephew_ix, !node_is_left); - self.set_child(sibling_ix, parent_ix, node_is_left); + self.set_child(sibling_ix, Some(parent_ix), node_is_left); return; } } } /// Restructure the tree before removing `ix`. - fn restructure_rm(&mut self, ix: Ix, child_ix: Ix) { + fn restructure_rm(&mut self, ix: Ix, child_ix: Option) { if self.is_red(ix) { // Both of the children must be NIL. - debug_assert!(!child_ix.defined()); + debug_assert!(child_ix.is_none()); // Do nothing. } else if !self.is_black_or_nil(child_ix) { - self.set_red(child_ix); - // Child will be removed later. + self.set_red(child_ix.unwrap()); // unwrap: !black_or_nil + // Child will be removed later. } else { self.restructure_rm_complex_cases(ix); } } - pub(super) fn remove_at(&mut self, ix: Ix) -> Option { - if !ix.defined() { - return None; - } + pub(super) fn remove_at(&mut self, ix: Option) -> Option { + let ix = match ix { + Some(ix) => ix, + None => return None, + }; - let node = &self.nodes[ix.get()]; - let rm_ix = if !node.right.defined() || !node.right.defined() { - ix - } else { - // Searching for a minimal node in the right subtree. - let mut curr = node.right; - loop { - let left = self.nodes[curr.get()].left; - if !left.defined() { - break curr; + let node = self.node(ix); + let rm_ix = match node.right { + None => ix, + Some(right) => { + // Searching for a minimal node in the right subtree. + let mut curr = right; + loop { + match self.node(curr).left { + Some(left) => curr = left, + None => break curr, + } } - curr = left; } }; if rm_ix != ix { - unsafe { self.swap_nodes(ix, rm_ix); } + self.swap_nodes(ix, rm_ix); } - let rm_node = &self.nodes[rm_ix.get()]; - let child_ix = core::cmp::min(rm_node.left, rm_node.right); + let rm_node = self.node(rm_ix); + let child_ix = rm_node.left.or(rm_node.right); self.restructure_rm(rm_ix, child_ix); - if child_ix.defined() { - // Removed node has a child, replace the node with the child and remove the child. - unsafe { self.swap_nodes(rm_ix, child_ix); } - self.remove_child(rm_ix, child_ix); - self.fix_intervals_up(rm_ix); - Some(self.swap_remove(child_ix)) - } else { - // Removed node has no child, just remove the node. - let parent_ix = self.nodes[rm_ix.get()].parent; - if parent_ix.defined() { - self.remove_child(parent_ix, rm_ix); - self.fix_intervals_up(parent_ix); - } else { - debug_assert!(self.len() == 1 && self.root == rm_ix); - self.root = Ix::MAX; + match child_ix { + Some(child_ix) => { + // Removed node has a child, replace the node with the child and remove the child. + self.swap_nodes(rm_ix, child_ix); + self.remove_child(rm_ix, child_ix); + self.fix_intervals_up(Some(rm_ix)); + Some(self.swap_remove(child_ix)) + } + None => { + // Removed node has no child, just remove the node. + match self.node(rm_ix).parent { + Some(parent_ix) => { + self.remove_child(parent_ix, rm_ix); + self.fix_intervals_up(Some(parent_ix)); + } + None => { + debug_assert!(self.len() == 1 && self.root == Some(rm_ix)); + self.root = None; + } + } + Some(self.swap_remove(rm_ix)) } - Some(self.swap_remove(rm_ix)) } } }