-
Notifications
You must be signed in to change notification settings - Fork 2
disjoint intervals #193
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
disjoint intervals #193
Conversation
2f54902 to
c8ce624
Compare
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.
Pull request overview
This PR introduces a new Rust library for managing disjoint (non-overlapping) intervals with support for insertion, removal, and querying operations. The library uses a BTreeMap internally to maintain intervals in sorted order and provides a fold-based API for tracking changes during operations.
Key changes:
- Implements
DisjointIntervals<T>struct with insert/remove operations that automatically merge overlapping intervals - Provides query methods (
ge,le) to find intervals relative to a given point - Includes comprehensive test coverage for insert and remove operations with fold tracking
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| libs/disjoint_intervals/Cargo.toml | Package manifest defining library metadata and configuration |
| libs/disjoint_intervals/src/lib.rs | Core implementation of disjoint interval data structure with insert, remove, and query operations plus test suite |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| pub fn len(&self) -> usize { | ||
| self.intervals.len() | ||
| } |
Copilot
AI
Dec 20, 2025
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.
The len method lacks unit test coverage. While the method is simple, adding a test would help ensure it behaves correctly, especially after insert and remove operations. Consider adding tests that verify len() returns the correct number of disjoint intervals after various operations.
| pub fn is_empty(&self) -> bool { | ||
| self.intervals.is_empty() | ||
| } |
Copilot
AI
Dec 20, 2025
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.
The is_empty method lacks unit test coverage. While the method is simple, adding a test would help ensure it behaves correctly. Consider adding tests that verify is_empty() returns true for a new instance and false after inserting intervals.
| pub fn ge(&self, x: T) -> Option<Range<T>> { | ||
| self.intervals | ||
| .range(x..) | ||
| .next() | ||
| .map(|(&start, &end)| start..end) | ||
| } |
Copilot
AI
Dec 20, 2025
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.
The ge method lacks unit test coverage beyond its documentation example. Since other methods in this module have dedicated unit tests, consider adding tests that cover various edge cases such as searching in empty intervals, searching for values before/after all intervals, and searching for values that fall within existing intervals.
| pub fn le(&self, x: T) -> Option<Range<T>> { | ||
| self.intervals | ||
| .range(..=x) | ||
| .last() | ||
| .map(|(&start, &end)| start..end) | ||
| } |
Copilot
AI
Dec 20, 2025
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.
The le method lacks unit test coverage beyond its documentation example. Since other methods in this module have dedicated unit tests, consider adding tests that cover various edge cases such as searching in empty intervals, searching for values before/after all intervals, and searching for values that fall within existing intervals.
libs/disjoint_intervals/src/lib.rs
Outdated
|
|
||
| /// 区間を追加する | ||
| /// | ||
| /// 初期値 `init,` 関数 `f` による畳み込み結果を返す |
Copilot
AI
Dec 20, 2025
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.
The documentation comment has a trailing comma after "init" which appears to be a typo. It should read "初期値 init 関数 f による畳み込み結果を返す" (without the comma after init).
| /// 初期値 `init,` 関数 `f` による畳み込み結果を返す | |
| /// 初期値 `init` 関数 `f` による畳み込み結果を返す |
libs/disjoint_intervals/src/lib.rs
Outdated
|
|
||
| /// 区間を削除する | ||
| /// | ||
| /// 初期値 `init,` 関数 `f` による畳み込み結果を返す |
Copilot
AI
Dec 20, 2025
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.
The documentation comment has a trailing comma after "init" which appears to be a typo. It should read "初期値 init 関数 f による畳み込み結果を返す" (without the comma after init).
libs/disjoint_intervals/src/lib.rs
Outdated
| match self.intervals.range(..=interval.start).last() { | ||
| Some((&prev_start, &prev_end)) if interval.start <= prev_end => { | ||
| if interval.start < prev_end { | ||
| acc = f(acc, InsertItem::Overlap(interval.start..prev_end)); |
Copilot
AI
Dec 20, 2025
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.
There's a logical issue in the overlap calculation. When interval.start < prev_end, the overlap range is reported as interval.start..prev_end, but this doesn't account for when interval.end might be less than prev_end. In that case, the actual overlap should be interval.start..interval.end, not interval.start..prev_end. This could lead to incorrect overlap reporting when inserting an interval that is completely contained within an existing interval.
| acc = f(acc, InsertItem::Overlap(interval.start..prev_end)); | |
| let overlap_end = if prev_end < interval.end { prev_end } else { interval.end }; | |
| acc = f(acc, InsertItem::Overlap(interval.start..overlap_end)); |
No description provided.