From 69406e6b3ab88c741a4af6127a539e1de12fe059 Mon Sep 17 00:00:00 2001 From: ripytide Date: Sun, 23 Apr 2023 15:02:09 +0100 Subject: [PATCH] undo allocations inside gaps --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + src/discrete_range_map.rs | 41 +++++++++++++++++++-------------------- src/discrete_range_set.rs | 5 +---- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecc78b4..cb64588 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,6 +40,7 @@ version = "0.4.0" dependencies = [ "btree_monstrousity", "either", + "itertools", "pretty_assertions", "serde", ] @@ -50,6 +51,15 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "output_vt100" version = "0.1.3" diff --git a/Cargo.toml b/Cargo.toml index 49f27c4..ca16440 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ categories = ["data-structures"] serde = {version = "1.0.148", features = ["derive"]} btree_monstrousity = {version ="0.0.4", features = ["btree_drain_filter", "btree_cursors"]} either = "1.8.1" +itertools = "0.10.5" [dev-dependencies] pretty_assertions = "1.3.0" diff --git a/src/discrete_range_map.rs b/src/discrete_range_map.rs index ec308f0..5509e98 100644 --- a/src/discrete_range_map.rs +++ b/src/discrete_range_map.rs @@ -27,6 +27,7 @@ use btree_monstrousity::btree_map::{ }; use btree_monstrousity::BTreeMap; use either::Either; +use itertools::Itertools; use serde::de::{MapAccess, Visitor}; use serde::ser::SerializeMap; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -643,7 +644,10 @@ where Some(before) => { let cut_result = cut_range(before, range); - (cut_result.before_cut.map(K::from), cut_result.inside_cut.map(K::from)) + ( + cut_result.before_cut.map(K::from), + cut_result.inside_cut.map(K::from), + ) } None => (None, None), }; @@ -651,7 +655,10 @@ where Some(after) => { let cut_result = cut_range(after, range); - (cut_result.after_cut.map(K::from), cut_result.inside_cut.map(K::from)) + ( + cut_result.after_cut.map(K::from), + cut_result.inside_cut.map(K::from), + ) } None => (None, None), }; @@ -719,17 +726,12 @@ where /// [ie(3, 5), ie(7, 9), iu(100)] /// ); /// ``` - pub fn gaps(&self, outer_range: Q) -> impl DoubleEndedIterator + pub fn gaps<'a, Q>(&'a self, outer_range: Q) -> impl Iterator + '_ where - Q: FiniteRange + Copy, + Q: FiniteRange + Copy + 'a, { invalid_range_panic(outer_range); - // I'm in love with how clean/mindblowing this entire function is - let overlapping = self - .overlapping(outer_range) - .map(|(key, _)| (key.start(), key.end())); - // If the start or end point of outer_range is not // contained within a range in the map then we need to // generate the gaps. @@ -768,22 +770,19 @@ where (None, None) => (None, None), }; + let overlapping = self + .overlapping(outer_range) + .map(|(key, _)| (key.start(), key.end())); + let inner_gaps = overlapping - //optimisation find an implementation of windows() - //somewhere that supports DoubleEndedIterator, I couldn't - //find one at the time of writing - .collect::>() - .windows(2) - .map(|windows| { + .tuple_windows() + .map(|(first, second)| { K::from(DiscreteFiniteBounds { - start: windows[0].1.up().unwrap(), - end: windows[1].0.down().unwrap(), + start: first.1.up().unwrap(), + end: second.0.down().unwrap(), }) }) - .filter(|range| is_valid_range(*range)) - //optimisation this would also then be unneccessary - .collect::>() - .into_iter(); + .filter(|range| is_valid_range(*range)); //possibly add the trimmed start and end gaps return trimmed_start_gap diff --git a/src/discrete_range_set.rs b/src/discrete_range_set.rs index 7057417..3992b4c 100644 --- a/src/discrete_range_set.rs +++ b/src/discrete_range_set.rs @@ -94,10 +94,7 @@ where self.inner.cut(range).map(first) } /// See [`DiscreteRangeMap::gaps()`] for more details. - pub fn gaps<'a, Q>( - &'a self, - range: Q, - ) -> impl DoubleEndedIterator + '_ + pub fn gaps<'a, Q>(&'a self, range: Q) -> impl Iterator + '_ where Q: FiniteRange + Copy + 'a, {