//Note: this could be the only place where we need `SmallVec`. //TODO: consider getting rid of it. use smallvec::SmallVec;
use std::{fmt::Debug, iter, ops::Range};
/// Structure that keeps track of a I -> T mapping, /// optimized for a case where keys of the same values /// are often grouped together linearly. #[derive(Clone, Debug, PartialEq)] pub(crate) struct RangedStates<I, T> { /// List of ranges, each associated with a singe value. /// Ranges of keys have to be non-intersecting and ordered.
ranges: SmallVec<[(Range<I>, T); 1]>,
}
/// Construct a new instance from a slice of ranges. #[cfg(test)] pubfn from_slice(values: &[(Range<I>, T)]) -> Self { Self {
ranges: values.iter().cloned().collect(),
}
}
/// Check that all the ranges are non-intersecting and ordered. /// Panics otherwise. #[cfg(test)] fn check_sanity(&self) { for a inself.ranges.iter() {
assert!(a.0.start < a.0.end);
} for (a, b) inself.ranges.iter().zip(self.ranges[1..].iter()) {
assert!(a.0.end <= b.0.start);
}
}
/// Merge the neighboring ranges together, where possible. pubfn coalesce(&mutself) { letmut num_removed = 0; letmut iter = self.ranges.iter_mut(); letmut cur = match iter.next() {
Some(elem) => elem,
None => return,
}; for next in iter { if cur.0.end == next.0.start && cur.1 == next.1 {
num_removed += 1;
cur.0.end = next.0.end;
next.0.end = next.0.start;
} else {
cur = next;
}
} if num_removed != 0 { self.ranges.retain(|pair| pair.0.start != pair.0.end);
}
}
/// Split the storage ranges in such a way that there is a linear subset of /// them occupying exactly `index` range, which is returned mutably. /// /// Gaps in the ranges are filled with `default` value. pubfn isolate(&mutself, index: &Range<I>, default: T) -> &mut [(Range<I>, T)] { //TODO: implement this in 2 passes: // 1. scan the ranges to figure out how many extra ones need to be inserted // 2. go through the ranges by moving them them to the right and inserting the missing ones
/// Helper method for isolation that checks the sanity of the results. #[cfg(test)] pubfn sanely_isolated(&self, index: Range<I>, default: T) -> Vec<(Range<I>, T)> { letmut clone = self.clone(); let result = clone.isolate(&index, default).to_vec();
clone.check_sanity();
result
}
}
#[cfg(test)] mod test { //TODO: randomized/fuzzy testing usesuper::RangedStates;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.