-
Notifications
You must be signed in to change notification settings - Fork 1
Refactorfor for less allocation. #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There may be some redundant if branches. I'm considering whether the first item special case could be dropped. |
I don't think I can do the same for sub_interval_unchecked as the interval to subtract may span across all elements in self.intervals |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me ✨ mostly nits and stylistic comments below. I think the logic is sane (one way to double-check that would be to have fun with a small fuzzer for this function :D). It might be nice to add a doc comment for this function expliciting the invariant that the new interval won't overlap with any existing interval.
src/lib.rs
Outdated
if idx == self.intervals.len() { | ||
// previously treated | ||
unreachable!() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unnecessary because the .get().unwrap()
next line will panic the same way
src/lib.rs
Outdated
unreachable!() | ||
} | ||
// we can unwrap as the case interval is after the last element is treated before | ||
let next = self.intervals.get(idx).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: could be simplified as &mut self.intervals[idx]
@@ -82,26 +82,93 @@ impl Gtid { | |||
|
|||
/// Add an interval but does not check assume interval is correctly formed | |||
fn add_interval_unchecked(&mut self, interval: &(u64, u64)) { | |||
let mut interval = *interval; | |||
let interval = *interval; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a debug_assert!
that no intervals in self.intervals
overlap with the one to add, since it's an undocumented invariant?
// it may merge with next | ||
|
||
let before = self.intervals[idx]; | ||
let after = self.intervals[idx + 1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe comment that there is a next interval all the time (otherwise we would have fallen under another branch under the if let Some() = last
part above)
src/lib.rs
Outdated
self.intervals.push(interval); | ||
return; | ||
} | ||
if let Some(&first) = self.intervals.first() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: you can use first_mut
here (and remove the &
in front of &first
)...
src/lib.rs
Outdated
// unwrapping is ok as intervals is not empty | ||
|
||
let last = self.intervals.last_mut().unwrap(); | ||
*last = (last.0, interval.1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto, only updating the right bound
src/lib.rs
Outdated
new.push(interval); | ||
new.sort(); | ||
self.intervals = new; | ||
if let Some(&last) = self.intervals.last() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto, last_mut()
can be used here
src/lib.rs
Outdated
let next = self.intervals.get(idx).unwrap(); | ||
// interval merges with next | ||
if next.0 == interval.1 { | ||
*self.intervals.get_mut(idx).unwrap() = (interval.0, next.1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(and no need to take get_mut
here with the above suggestion, and we're only modifying the left bound here)
src/lib.rs
Outdated
|
||
// interval merges with before and after | ||
if interval.0 == before.1 && interval.1 == after.0 { | ||
*self.intervals.get_mut(idx).unwrap() = (before.0, after.1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth trying to use &mut self.intervals[idx]
for definition of before
above, and modify it in place here.
src/lib.rs
Outdated
} else if | ||
// interval merges with after | ||
interval.1 == after.0 { | ||
unreachable!("should have been treated in the error branch before"); | ||
// *self.intervals.get_mut(idx + 1).unwrap() = (interval.0, after.1); | ||
} else { | ||
// interval does not merge | ||
unreachable!("should have been treated in the error branch before"); | ||
// self.intervals.insert(idx + 1, interval) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: please remove commented code + maybe merge those two else
s, since they share the same panic message?
e0cec53
to
5ded370
Compare
Fix #7