Skip to content

Commit 95861f8

Browse files
authored
Merge pull request #53 from aurelj/iter_optimize
Optimize OverlapIterator
2 parents 4618091 + 7575db3 commit 95861f8

File tree

5 files changed

+31
-29
lines changed

5 files changed

+31
-29
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88
## Unreleased
99

10-
No unreleased changes yet
10+
- Add `start()` and `end()` method to the `Region` trait.
11+
- Much faster `OverlapIterator`.
1112

1213
## [0.3.1] - 2023-12-04
1314

embedded-storage-async/src/nor_flash.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,15 @@ impl Page {
102102
size,
103103
}
104104
}
105-
106-
/// The end address of the page
107-
const fn end(&self) -> u32 {
108-
self.start + self.size as u32
109-
}
110105
}
111106

112107
impl Region for Page {
113-
/// Checks if an address offset is contained within the page
114-
fn contains(&self, address: u32) -> bool {
115-
(self.start <= address) && (self.end() > address)
108+
fn start(&self) -> u32 {
109+
self.start
110+
}
111+
112+
fn end(&self) -> u32 {
113+
self.start + self.size as u32
116114
}
117115
}
118116

src/iter.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,15 @@ where
3030
type Item = (&'a [u8], R, u32);
3131

3232
fn next(&mut self) -> Option<Self::Item> {
33+
let mem_start = self.base_address;
34+
let mem_end = self.base_address + self.memory.len() as u32;
3335
while let Some(region) = self.regions.next() {
34-
// TODO: This might be possible to do in a smarter way?
35-
let mut block_range = (0..self.memory.len())
36-
.skip_while(|index| !region.contains(self.base_address + *index as u32))
37-
.take_while(|index| region.contains(self.base_address + *index as u32));
38-
if let Some(start) = block_range.next() {
39-
let end = block_range.last().unwrap_or(start) + 1;
40-
return Some((
41-
&self.memory[start..end],
42-
region,
43-
self.base_address + start as u32,
44-
));
36+
if mem_start < region.end() && mem_end >= region.start() {
37+
let addr_start = core::cmp::max(mem_start, region.start());
38+
let addr_end = core::cmp::min(mem_end, region.end());
39+
let start = (addr_start - self.base_address) as usize;
40+
let end = (addr_end - self.base_address) as usize;
41+
return Some((&self.memory[start..end], region, addr_start));
4542
}
4643
}
4744
None

src/lib.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,16 @@ pub mod nor_flash;
1515

1616
/// A region denotes a contiguous piece of memory between two addresses.
1717
pub trait Region {
18+
/// Start address of the region of `Self`
19+
fn start(&self) -> u32;
20+
21+
/// End address of the region of `Self`
22+
fn end(&self) -> u32;
23+
1824
/// Check if `address` is contained in the region of `Self`
19-
fn contains(&self, address: u32) -> bool;
25+
fn contains(&self, address: u32) -> bool {
26+
(address >= self.start()) && (address < self.end())
27+
}
2028
}
2129

2230
/// Transparent read only storage trait

src/nor_flash.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -202,17 +202,15 @@ impl Page {
202202
size,
203203
}
204204
}
205-
206-
/// The end address of the page
207-
const fn end(&self) -> u32 {
208-
self.start + self.size as u32
209-
}
210205
}
211206

212207
impl Region for Page {
213-
/// Checks if an address offset is contained within the page
214-
fn contains(&self, address: u32) -> bool {
215-
(self.start <= address) && (self.end() > address)
208+
fn start(&self) -> u32 {
209+
self.start
210+
}
211+
212+
fn end(&self) -> u32 {
213+
self.start + self.size as u32
216214
}
217215
}
218216

0 commit comments

Comments
 (0)