Skip to content
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

compact: Introduce Range intersection and merge methods #13

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

pav-kv
Copy link
Contributor

@pav-kv pav-kv commented Mar 29, 2022

The unit test is an exhaustive test that intersects and merges all compact range
pairs within the tree of size 20.

@pav-kv pav-kv requested review from AlCutter and smeiklej March 29, 2022 14:16
Copy link

@smeiklej smeiklej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main concerns are around the side effects of Merge and Intersect, your thoughts on why those are necessary would be much appreciated!

// nodes, and reports them through the visitor function (if non-nil). The other
// range must begin between the current range's begin and end.
//
// Warning: This method modifies both this and the other Range.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: there is no reason for "range" to be capitalized here and throughout.

// nodes, and reports them through the visitor function (if non-nil). The other
// range must begin between the current range's begin and end.
//
// Warning: This method modifies both this and the other Range.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems unnecessary to modify the other range, no? Or at least this feels like it could easily have some awkward and unintended side effects. Why not implement it in a more "pure" way?

begin, end := other.begin, r.end
if begin > end { // The other range is disjoint.
return nil, fmt.Errorf("ranges are disjoint: other.begin=%d, want <= %d", begin, end)
} else if begin == end { // The ranges touch ends.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the distinction here, since the intersection of two disjoint ranges is the empty set regardless of whether or not they "almost" intersect.

//
// Warning: This method modifies both this and the other Range.
// Warning: This method is experimental.
func (r *Range) Intersect(other *Range) (*Range, error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The modification of both ranges feels especially confusing here. Really after you call this function you have three compact ranges:

  • r is now r without the intersecting parts.
  • the output is the intersection.
  • other is now other without the intersecting parts.
    This seems like it could lead to even more confusion than the behavior of Merge above. Surely what you'd want is just the intersection, like the function name suggests, without all of the side effects?

@pav-kv pav-kv force-pushed the compact_range_bool_ops branch from e88a44e to b368c6b Compare April 25, 2022 13:49
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.

2 participants