Skip to content

Commit

Permalink
[chore]: change some fn's and variable's name
Browse files Browse the repository at this point in the history
Signed-off-by: feathercyc <[email protected]>
  • Loading branch information
GG2002 committed Jul 26, 2024
1 parent 45232af commit f50f55d
Show file tree
Hide file tree
Showing 9 changed files with 473 additions and 518 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@ license = "Apache-2.0"
keywords = ["Interval Tree", "Augmented Tree", "Red-Black Tree"]

[dependencies]
serde = { version = "1.0", default-features = false, features = [
"derive",
"std",
], optional = true }

[dev-dependencies]
criterion = "0.5.1"
rand = "0.8.5"
serde_json = "1.0"

[features]
default = []
interval_tree_find_overlap_ordered = []
graphviz = []
serde = ["dep:serde"]

[[bench]]
name = "bench"
Expand Down
2 changes: 1 addition & 1 deletion benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn interval_map_insert_remove(count: usize, bench: &mut Bencher) {
black_box(map.insert(i, ()));
}
for i in &intervals {
black_box(map.remove(&i));
black_box(map.remove(i));
}
});
}
Expand Down
21 changes: 15 additions & 6 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use crate::node::Node;

/// A view into a single entry in a map, which may either be vacant or occupied.
#[derive(Debug)]
pub enum Entry<'a, T, V, Ix> {
pub enum Entry<'a, T, V, Ix>
where
T: Ord,
{
/// An occupied entry.
Occupied(OccupiedEntry<'a, T, V, Ix>),
/// A vacant entry.
Expand All @@ -15,17 +18,23 @@ pub enum Entry<'a, T, V, Ix> {
/// A view into an occupied entry in a `IntervalMap`.
/// It is part of the [`Entry`] enum.
#[derive(Debug)]
pub struct OccupiedEntry<'a, T, V, Ix> {
pub struct OccupiedEntry<'a, T, V, Ix>
where
T: Ord,
{
/// Reference to the map
pub map_ref: &'a mut IntervalMap<T, V, Ix>,
/// The entry node
pub node: NodeIndex<Ix>,
pub node_idx: NodeIndex<Ix>,
}

/// A view into a vacant entry in a `IntervalMap`.
/// It is part of the [`Entry`] enum.
#[derive(Debug)]
pub struct VacantEntry<'a, T, V, Ix> {
pub struct VacantEntry<'a, T, V, Ix>
where
T: Ord,
{
/// Mutable reference to the map
pub map_ref: &'a mut IntervalMap<T, V, Ix>,
/// The interval of this entry
Expand Down Expand Up @@ -53,7 +62,7 @@ where
#[inline]
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.map_ref.node_mut(entry.node, Node::value_mut),
Entry::Occupied(entry) => entry.map_ref.node_mut(entry.node_idx, Node::value_mut),
Entry::Vacant(entry) => {
let entry_idx = NodeIndex::new(entry.map_ref.nodes.len());
let _ignore = entry.map_ref.insert(entry.interval, default);
Expand Down Expand Up @@ -88,7 +97,7 @@ where
{
match self {
Entry::Occupied(entry) => {
f(entry.map_ref.node_mut(entry.node, Node::value_mut));
f(entry.map_ref.node_mut(entry.node_idx, Node::value_mut));
Self::Occupied(entry)
}
Entry::Vacant(entry) => Self::Vacant(entry),
Expand Down
65 changes: 45 additions & 20 deletions src/index.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,49 @@
use std::fmt;
use std::hash::Hash;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

pub type DefaultIx = u32;

pub unsafe trait IndexType: Copy + Default + Hash + Ord + fmt::Debug + 'static {
pub trait IndexType: Copy + Default + Hash + Ord + fmt::Debug + 'static {
const SENTINEL: Self;
fn new(x: usize) -> Self;
fn index(&self) -> usize;
fn max() -> Self;
fn is_sentinel(&self) -> bool {
*self == Self::SENTINEL
}
}

unsafe impl IndexType for u32 {
#[inline(always)]
fn new(x: usize) -> Self {
x as u32
}
#[inline(always)]
fn index(&self) -> usize {
*self as usize
}
#[inline(always)]
fn max() -> Self {
::std::u32::MAX
}
macro_rules! impl_index {
($type:ident) => {
impl IndexType for $type {
const SENTINEL: Self = 0;

#[inline(always)]
fn new(x: usize) -> Self {
x as $type
}
#[inline(always)]
fn index(&self) -> usize {
*self as usize
}
#[inline(always)]
fn max() -> Self {
$type::MAX
}
}
};
}

impl_index!(u8);
impl_index!(u16);
impl_index!(u32);
impl_index!(u64);

/// Node identifier.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct NodeIndex<Ix = DefaultIx>(Ix);

Expand All @@ -34,24 +53,30 @@ impl<Ix: IndexType> NodeIndex<Ix> {
NodeIndex(IndexType::new(x))
}

#[inline]
pub fn index(self) -> usize {
self.0.index()
}

#[inline]
pub fn end() -> Self {
NodeIndex(IndexType::max())
}

pub fn incre(&self) -> Self {
NodeIndex::new(self.index().wrapping_add(1))
}
}

unsafe impl<Ix: IndexType> IndexType for NodeIndex<Ix> {
impl<Ix: IndexType> IndexType for NodeIndex<Ix> {
const SENTINEL: Self = NodeIndex(Ix::SENTINEL);

#[inline]
fn index(&self) -> usize {
self.0.index()
}

#[inline]
fn new(x: usize) -> Self {
NodeIndex::new(x)
}

#[inline]
fn max() -> Self {
NodeIndex(<Ix as IndexType>::max())
}
Expand Down
80 changes: 78 additions & 2 deletions src/interval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@
//!
//! Currently, `interval_map` only supports half-open intervals, i.e., [...,...).
use std::fmt::{Display, Formatter};

#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};

/// The interval stored in `IntervalMap` represents [low, high)
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Interval<T> {
/// Low value
pub low: T,
Expand All @@ -32,9 +37,27 @@ impl<T: Ord> Interval<T> {

/// Checks if self overlaps with other interval
#[inline]
pub fn overlap(&self, other: &Self) -> bool {
pub fn overlaps(&self, other: &Self) -> bool {
self.high > other.low && other.high > self.low
}

/// Checks if self contains other interval
/// e.g. [1,10) contains [1,8)
#[inline]
pub fn contains(&self, other: &Self) -> bool {
self.low <= other.low && self.high > other.high
}

/// Checks if self contains a point
pub fn contains_point(&self, p: T) -> bool {
self.low <= p && self.high > p
}
}

impl<T: Display> Display for Interval<T> {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "[{},{})", self.low, self.high)
}
}

/// Reference type of `Interval`
Expand Down Expand Up @@ -64,6 +87,21 @@ impl<'a, T: Ord> IntervalRef<'a, T> {
}
}

#[cfg(feature = "serde")]
impl<T: Serialize + Ord> Serialize for Interval<T> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
(&self.low, &self.high).serialize(serializer)
}
}

#[cfg(feature = "serde")]
impl<'de, T: Deserialize<'de> + Ord> Deserialize<'de> for Interval<T> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let (low, high) = <(T, T)>::deserialize(deserializer)?;
Ok(Interval::new(low, high))
}
}

#[cfg(test)]
mod test {
use super::*;
Expand All @@ -73,4 +111,42 @@ mod test {
fn invalid_range_should_panic() {
let _interval = Interval::new(3, 1);
}

#[test]
fn test_interval_clone() {
let interval1 = Interval::new(1, 10);
let interval2 = interval1.clone();
assert_eq!(interval1, interval2);
}

#[test]
fn test_interval_compare() {
let interval1 = Interval::new(1, 10);
let interval2 = Interval::new(5, 15);
assert!(interval1 < interval2);
assert!(interval2 > interval1);
assert_eq!(interval1, Interval::new(1, 10));
assert_ne!(interval1, interval2);
}

#[test]
fn test_interval_hash() {
let interval1 = Interval::new(1, 10);
let interval2 = Interval::new(1, 10);
let interval3 = Interval::new(5, 15);
let mut hashset = std::collections::HashSet::new();
hashset.insert(interval1);
hashset.insert(interval2);
hashset.insert(interval3);
assert_eq!(hashset.len(), 2);
}

#[cfg(feature = "serde")]
#[test]
fn test_interval_serialize_deserialize() {
let interval = Interval::new(1, 10);
let serialized = serde_json::to_string(&interval).unwrap();
let deserialized: Interval<i32> = serde_json::from_str(&serialized).unwrap();
assert_eq!(interval, deserialized);
}
}
Loading

0 comments on commit f50f55d

Please sign in to comment.