From 7575db3b6b71c55368cbbc080daa86bf9e61835a Mon Sep 17 00:00:00 2001 From: Aurelien Jacobs Date: Fri, 14 Jun 2024 10:57:06 +0200 Subject: [PATCH] Much faster OverlapIterator --- CHANGELOG.md | 1 + src/iter.rs | 19 ++++++++----------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7824090..9225845 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased - Add `start()` and `end()` method to the `Region` trait. +- Much faster `OverlapIterator`. ## [0.3.1] - 2023-12-04 diff --git a/src/iter.rs b/src/iter.rs index 3b5c102..7878e6e 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -30,18 +30,15 @@ where type Item = (&'a [u8], R, u32); fn next(&mut self) -> Option { + let mem_start = self.base_address; + let mem_end = self.base_address + self.memory.len() as u32; while let Some(region) = self.regions.next() { - // TODO: This might be possible to do in a smarter way? - let mut block_range = (0..self.memory.len()) - .skip_while(|index| !region.contains(self.base_address + *index as u32)) - .take_while(|index| region.contains(self.base_address + *index as u32)); - if let Some(start) = block_range.next() { - let end = block_range.last().unwrap_or(start) + 1; - return Some(( - &self.memory[start..end], - region, - self.base_address + start as u32, - )); + if mem_start < region.end() && mem_end >= region.start() { + let addr_start = core::cmp::max(mem_start, region.start()); + let addr_end = core::cmp::min(mem_end, region.end()); + let start = (addr_start - self.base_address) as usize; + let end = (addr_end - self.base_address) as usize; + return Some((&self.memory[start..end], region, addr_start)); } } None