feat: SortedSet merge-based set algebra and Maxer/Minner fast paths #minor - #42
Merged
Conversation
…minor SortedSet now implements the optional Unioner, Intersectioner, Differencer, and SymmetricDifferencer interfaces: when both operands are SortedSets, the package-level set-algebra functions compute their result with a single O(N+M) linear merge of the two sorted backing slices, replacing fallbacks that were O(N*M) for Union and SymmetricDifference (each insert into the middle of the sorted slice shifts the tail) and O(N log M) for Intersection and Difference. Add Maxer and Minner, new optional interfaces following the same contract as the set-algebra ones: the package-level Max and Min check them and fall back to the generic O(N) iteration when the method reports false. SortedSet answers in O(1) from the ends of its slice; BitSet scans from its span edges for the outermost set bit. Tests mirror the existing BitSet patterns: a rapid differential test of the merge ops against Map-based generic results (including mixed-operand fallback and decline reporting), direct Max/Min tests covering empty sets, Removes that leave zero words at BitSet span edges, and the sign-bit mapping extremes, plus a third-party-style stub proving Max/Min honor external implementations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MVcvyLahh4ssVbaXJJA8dV
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds optional-interface fast paths for set algebra and extreme-element queries, improving performance for SortedSet/BitSet when using the package-level helpers while preserving the generic fallback algorithms in set.go.
Changes:
- Implemented merge-based
Union/Intersection/Difference/SymmetricDifferencefast paths forSortedSetvia optional set-algebra interfaces. - Added optional
Maxer/Minnerinterfaces and integrated them into package-levelMax/Min, withSortedSetandBitSetimplementations. - Added differential and direct tests covering merge operations and Max/Min fast paths, plus documentation updates.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| sorted.go | Adds Max/Min and merge-based set-algebra optional interface implementations for SortedSet. |
| sorted_test.go | Adds rapid differential tests for merge-based ops and direct tests for SortedSet Max/Min. |
| set.go | Introduces Maxer/Minner and uses them in package-level Max/Min. |
| README.MD | Documents SortedSet set-algebra optimization and new Max/Min optional interfaces. |
| coverage_test.go | Adds a third-party-style stub to verify Max/Min honor optional interfaces and fall back correctly. |
| CLAUDE.md | Updates repository documentation to reflect new SortedSet and BitSet optional-interface capabilities. |
| bitset.go | Implements Maxer/Minner for BitSet. |
| bitset_test.go | Adds tests for BitSet Max/Min behavior including edge cases and package-level fast-path usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
… mergeSorted prealloc - BitSet.Max/Min return early when the set is empty (card == 0), avoiding a scan of a retained-but-empty word span; also nil-receiver safe like Cardinality - mergeSorted only applies the intersection capacity bound when the flags are actually the intersection combination, so the all-false combination no longer over-allocates - drop unnecessary explicit type arguments in TestMinMaxOptionalInterfaces Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLrWSEKLMPuf1kq1KDCoxs
A typed-nil *SortedSet passed as Set[M] previously reached the nil-guarded Cardinality() in the package-level Max/Min and panicked with the intended "empty set" message; the new Maxer/Minner fast path dereferenced s.el first and crashed with a raw nil-pointer panic. Guard the receiver like BitSet does. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLrWSEKLMPuf1kq1KDCoxs
Regression test for the typed-nil SortedSet/BitSet Max/Min panics caught in review — a nil receiver must report ok=false, not dereference backing storage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLrWSEKLMPuf1kq1KDCoxs
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
This was referenced Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two additions from the optional-interface survey (the rest — Equaler/Disjointer/Subsetter, a bulk-AppendSeq hook, Locked delegation — are saved for follow-ups):
SortedSet implements the four set-algebra optimization interfaces
When both operands of the package-level
Union/Intersection/Difference/SymmetricDifferenceare*SortedSet[M], the result is now computed by a single O(N+M) two-pointer merge of the two sorted backing slices (one sharedmergeSortedhelper; each operation is a flag combination of keep-only-in-a / keep-only-in-b / keep-in-both). This replaces fallbacks that were:Non-SortedSet operands are declined (
false), keeping the generic algorithm in exactly one place, per theUnionercontract.New optional
Maxer/MinnerinterfacesSame pattern as the set-algebra interfaces: package-level
Max/Mincheck their argument and fall back to the generic O(N) iteration when the method reports false. Implemented by both always-sorted types:SortedSet: O(1) from the ends of the sorted sliceBitSet: outermost set bit scanning from the span edges — O(1) unless Removes have left zero edge words (Remove never trims)Testing
TestSortedSet_MergeOps: rapid differential test of all four ops against Map-based generic results — asserts the fast path returns a sorted*SortedSet[int], mixed operands fall back correctly, and non-SortedSet operands are declinedTestSortedSet_MaxMin/TestBitSet_MaxMin: direct method + package-level fast-path checks, covering empty sets, Removes leaving zero words at BitSet span edges, and sign-bit mapping extremes (MaxUint64,MinInt64)TestMinMaxOptionalInterfaces: third-party-style stub provingMax/Minhonor external implementations and fall back on declineNewEmpty(), so both sides are the same concrete type)go vet,staticcheck, andgo test -race ./...all clean🤖 Generated with Claude Code
https://claude.ai/code/session_01MVcvyLahh4ssVbaXJJA8dV