Skip to content

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

AureliaDolo
Copy link

@AureliaDolo AureliaDolo commented Aug 2, 2023

Fix #7

@AureliaDolo
Copy link
Author

There may be some redundant if branches.

I'm considering whether the first item special case could be dropped.

@AureliaDolo AureliaDolo changed the title Refactorfor less allocation. Refactorfor for less allocation. Aug 2, 2023
@AureliaDolo
Copy link
Author

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

Copy link

@bnjbvr bnjbvr left a 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
Comment on lines 131 to 134
if idx == self.intervals.len() {
// previously treated
unreachable!()
}
Copy link

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();
Copy link

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;
Copy link

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];
Copy link

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() {
Copy link

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);
Copy link

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() {
Copy link

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);
Copy link

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);
Copy link

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
Comment on lines 160 to 169
} 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)
}
Copy link

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 elses, since they share the same panic message?

@AureliaDolo AureliaDolo force-pushed the no_alloc branch 3 times, most recently from e0cec53 to 5ded370 Compare January 22, 2024 14:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Investigate better algorithms for inserting interval and removing
2 participants