Skip to content

Commit

Permalink
checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
ripytide committed Jan 24, 2024
1 parent a31e865 commit 3003fae
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 56 deletions.
54 changes: 26 additions & 28 deletions src/nodit/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

use crate::utils::{
cut_interval, starts_comp, invalid_interval_panic, overlapping_comp,
overlaps, touching_end_comp, touching_start_comp,
cut_interval, invalid_interval_panic, overlapping_comp, overlaps,
starts_comp, touching_end_comp, touching_start_comp,
};
use crate::{DiscreteFinite, InclusiveInterval, Interval};

Expand Down Expand Up @@ -187,14 +187,12 @@ where
{
invalid_interval_panic(interval);

let start_comp = overlapping_comp(interval.start());
let end_comp = overlapping_comp(interval.end());

let start_bound = SearchBoundCustom::Included;
let end_bound = SearchBoundCustom::Included;

self.inner
.range(start_comp, start_bound, end_comp, end_bound)
self.inner.range(
overlapping_comp(interval.start()),
SearchBoundCustom::Included,
overlapping_comp(interval.end()),
SearchBoundCustom::Included,
)
}

/// Returns an mutable iterator over every entry in the map that
Expand Down Expand Up @@ -235,14 +233,12 @@ where
{
invalid_interval_panic(interval);

let start_comp = overlapping_comp(interval.start());
let end_comp = overlapping_comp(interval.end());

let start_bound = SearchBoundCustom::Included;
let end_bound = SearchBoundCustom::Included;

self.inner
.range_mut(start_comp, start_bound, end_comp, end_bound)
self.inner.range_mut(
overlapping_comp(interval.start()),
SearchBoundCustom::Included,
overlapping_comp(interval.end()),
SearchBoundCustom::Included,
)
}

/// Returns a reference to the value corresponding to the interval in
Expand All @@ -265,7 +261,9 @@ where
/// assert_eq!(map.get_at_point(101), None);
/// ```
pub fn get_at_point(&self, point: I) -> Option<&V> {
self.get_key_value_at_point(point).map(|(_, value)| value).ok()
self.get_key_value_at_point(point)
.map(|(_, value)| value)
.ok()
}

/// Returns a mutable reference to the value corresponding to the
Expand Down Expand Up @@ -329,7 +327,10 @@ where
/// ])
/// .unwrap();
///
/// assert_eq!(map.get_key_value_at_point(3), Ok((&ie(1, 4), &false)));
/// assert_eq!(
/// map.get_key_value_at_point(3),
/// Ok((&ie(1, 4), &false))
/// );
/// assert_eq!(map.get_key_value_at_point(5), Ok((&ie(4, 6), &true)));
/// assert_eq!(map.get_key_value_at_point(7), Err(ie(6, 8)));
/// assert_eq!(map.get_key_value_at_point(101), Err(iu(100)));
Expand Down Expand Up @@ -416,8 +417,8 @@ where
return result.into_iter();
}

/// Cuts a given interval out of the map and returns an iterator of the full or
/// partial intervals with their values that were cut in ascending order.
/// Cuts a given interval out of the map and returns an iterator of the full or
/// partial intervals with their values that were cut in ascending order.
///
/// `V` must implement `Clone` as if you try to cut out the center
/// of a interval in the map it will split into two different entries
Expand Down Expand Up @@ -461,17 +462,14 @@ where
{
invalid_interval_panic(interval);

let start_comp = overlapping_comp(interval.start());
let end_comp = overlapping_comp(interval.end());

let left_overlapping = self
.inner
.get_key_value(start_comp)
.get_key_value(overlapping_comp(interval.start()))
.map(|(key, _)| key)
.copied();
let right_overlapping = self
.inner
.get_key_value(end_comp)
.get_key_value(overlapping_comp(interval.end()))
.map(|(key, _)| key)
.copied();

Expand Down Expand Up @@ -1339,7 +1337,7 @@ where
pub fn from_slice_strict<const N: usize>(
slice: [(K, V); N],
) -> Result<NoditMap<I, K, V>, OverlapError<V>> {
NoditMap::from_iter_strict(slice.into_iter())
NoditMap::from_iter_strict(slice.into_iter())
}

/// Collects a `NoditMap` from an iterator of (interval,
Expand Down
103 changes: 75 additions & 28 deletions src/zosdit/map.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
//! A module containing [`ZosditMap`].
//todo remove the inner Nodit since I't/don use it
//todo make nodit use the more robust comparators in general and refactor them to remove all the
//temporary variables before the comp calls
//remove overlapping_mut and replace with overlapping_start_comp and overlapping_end_comp
use alloc::boxed::Box;
use core::cmp::Ordering;
use core::fmt;
use core::marker::PhantomData;

use btree_monstrousity::btree_map::SearchBoundCustom;
use btree_monstrousity::BTreeMap;
use serde::de::{SeqAccess, Visitor};
use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
Expand All @@ -14,11 +19,11 @@ use smallvec::SmallVec;
use crate::utils::{
exclusive_comp_generator, inclusive_comp_generator, invalid_interval_panic,
};
use crate::{IntervalType, NoditMap, PointType};
use crate::{IntervalType, PointType};

type ValueStore<V> = SmallVec<[V; 2]>;

/// A Zero Overlap Sequential Discrete Interval Tree Map Data-Structure based off [`NoditMap`] and
/// A Zero Overlap Sequential Discrete Interval Tree Map Data-Structure based off [`BTreeMap`] and
/// [`SmallVec`]
///
/// `I` is the generic type parameter for the [`Ord`] type the `K`
Expand Down Expand Up @@ -52,7 +57,11 @@ type ValueStore<V> = SmallVec<[V; 2]>;
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ZosditMap<I, K, V> {
nodit_map: NoditMap<I, K, ValueStore<V>>,
//we can't use the btreemaps's len
//since we can have multiples values per key
len: usize,
inner: BTreeMap<K, ValueStore<V>>,
phantom: PhantomData<I>,
}

/// The error returned when inserting a interval that non-zero-overlaps another interval when it
Expand All @@ -77,18 +86,16 @@ where
/// let map: ZosditMap<i8, Interval<i8>, bool> = ZosditMap::new();
/// ```
pub fn new() -> Self {
ZosditMap {
nodit_map: NoditMap::new(),
}
ZosditMap::default()
}

/// See [`NoditMap::len()`] for more details.
pub fn len(&self) -> usize {
self.nodit_map.len()
self.len
}
/// See [`NoditMap::is_empty()`] for more details.
pub fn is_empty(&self) -> bool {
self.nodit_map.is_empty()
self.len == 0
}

/// Returns the first key-value pair in the map.
Expand All @@ -110,7 +117,7 @@ where
/// Some((&ii(0, 4), &-2))
/// );
pub fn first_key_value(&self) -> Option<(&K, &V)> {
let (key, value_store) = self.nodit_map.first_key_value()?;
let (key, value_store) = self.inner.first_key_value()?;

let first_value = value_store.first()?;

Expand All @@ -136,7 +143,7 @@ where
/// Some((&ii(4, 4), &-8))
/// );
pub fn last_key_value(&self) -> Option<(&K, &V)> {
let (key, value_store) = self.nodit_map.last_key_value()?;
let (key, value_store) = self.inner.last_key_value()?;

let last_value = value_store.last()?;

Expand Down Expand Up @@ -164,8 +171,7 @@ where
/// assert_eq!(map.get_last_value_at_point(10), None);
/// ```
pub fn get_last_value_at_point(&self, point: I) -> Option<&V> {
self.nodit_map
.inner
self.inner
.lower_bound(
exclusive_comp_generator(point, Ordering::Greater),
SearchBoundCustom::Included,
Expand Down Expand Up @@ -215,8 +221,7 @@ where
if !self.is_zero_overlap(interval) {
Err(NonZeroOverlapError { value })
} else {
self.nodit_map
.inner
self.inner
.entry(interval, |inner_interval, new_interval| {
let start_result = exclusive_comp_generator(
new_interval.start(),
Expand Down Expand Up @@ -246,6 +251,8 @@ where
.or_default()
.push(value);

self.len += 1;

Ok(())
}
}
Expand Down Expand Up @@ -289,8 +296,7 @@ where
//this elegant solution, there are a surprising amount of different scenarios when you
//start considering zero-sized intervals and things

self.nodit_map
.inner
self.inner
.range(
exclusive_comp_generator(interval.start(), Ordering::Greater),
SearchBoundCustom::Included,
Expand Down Expand Up @@ -349,11 +355,9 @@ where
{
invalid_interval_panic(interval);

let cut = self.nodit_map.cut(interval);
todo!();

cut.flat_map(|(interval, value_store)| {
value_store.into_iter().map(move |value| (interval, value))
})
[].into_iter()
}

/// The same as [`NoditMap::overlapping()`] except it flattens the `SmallVec`s of values into
Expand Down Expand Up @@ -397,7 +401,7 @@ where
{
invalid_interval_panic(interval);

let overlapping = self.nodit_map.inner.range(
let overlapping = self.inner.range(
inclusive_comp_generator(interval.start(), Ordering::Less),
SearchBoundCustom::Included,
inclusive_comp_generator(interval.end(), Ordering::Greater),
Expand Down Expand Up @@ -432,7 +436,7 @@ where
/// assert_eq!(iter.next(), None);
/// ```
pub fn iter(&self) -> impl DoubleEndedIterator<Item = (&K, &V)> {
self.nodit_map.iter().flat_map(|(interval, value_store)| {
self.inner.iter().flat_map(|(interval, value_store)| {
value_store.iter().map(move |value| (interval, value))
})
}
Expand Down Expand Up @@ -507,7 +511,9 @@ where
impl<I, K, V> Default for ZosditMap<I, K, V> {
fn default() -> Self {
ZosditMap {
nodit_map: NoditMap::default(),
len: 0,
inner: BTreeMap::new(),
phantom: PhantomData,
}
}
}
Expand All @@ -522,11 +528,9 @@ where
type IntoIter = Box<dyn Iterator<Item = (K, V)>>;

fn into_iter(self) -> Self::IntoIter {
Box::new(self.nodit_map.into_iter().flat_map(
|(interval, value_store)| {
value_store.into_iter().map(move |value| (interval, value))
},
))
Box::new(self.inner.into_iter().flat_map(|(interval, value_store)| {
value_store.into_iter().map(move |value| (interval, value))
}))
}
}

Expand Down Expand Up @@ -600,6 +604,8 @@ where

#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;

use super::*;
use crate::interval::ii;

Expand Down Expand Up @@ -644,4 +650,45 @@ mod tests {
}
}
}

#[test]
fn insert_strict_back_tests() {
let mut map = ZosditMap::new();
assert_eq!(map.len(), 0);

map.insert_strict_back(ii(0_u8, 0), -8_i8).unwrap();
assert_eq!(map.len(), 1);

map.insert_strict_back(ii(0_u8, u8::MAX), -4_i8).unwrap();
assert_eq!(map.len(), 2);

let _ = map.insert_strict_back(ii(9_u8, 10), -4_i8);
assert_eq!(map.len(), 2);
}

#[test]
fn cut_tests() {
let mut map = ZosditMap::new();

map.insert_strict_back(ii(0_u8, 0), -8_i8).unwrap();
map.insert_strict_back(ii(0_u8, u8::MAX), -4_i8).unwrap();

assert_eq!(
map.iter().collect::<Vec<_>>(),
vec![(&ii(0, 0), &-8), (&ii(0, u8::MAX), &-4)]
);

let cut = map.cut(ii(0, u8::MAX));

assert_eq!(
map.iter().collect::<Vec<_>>(),
vec![],
"invalid map after cut"
);
assert_eq!(
cut.collect::<Vec<_>>(),
vec![(ii(0, 0), -8), (ii(0, u8::MAX), -4)],
"invalid cut"
);
}
}

0 comments on commit 3003fae

Please sign in to comment.