refactor: give sortEndpointStats a strict comparator - #322
Open
FrameAutomata wants to merge 1 commit into
Open
Conversation
`sortEndpointStats` produced its descending order by negating the ascending comparison. For two rows that tie on the sort key that returns true for both (i, j) and (j, i), which is not the strict weak ordering sort.Slice documents a requirement for, so the result is formally unspecified. Descending is now the same comparison with the operands swapped. This is hygiene, not a bug fix. I could not make the old comparator misbehave: 2400 trials over slices of 8 to 20000 elements, 1 to 100 distinct values and three input patterns produced zero misordered results and zero lost elements, so Go's pdqsort tolerates the `>=` comparator in practice today. What the change buys is not depending on that tolerance. No test, because none can distinguish the two versions -- any behaviour a test could asserts holds for the old comparator too, which is what the probe above measured. The sibling sort in task.repository.go already used the strict form; this brings the two endpoint repositories in line with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Small hygiene change found while reviewing the percentile work in #319. Not a bug fix — see the measurement below before spending review time on it.
What
sortEndpointStatsbuilt its descending order by negating the ascending comparison:For two rows that tie on the sort key,
lessis false in both directions, so!lessreturns true for both(i, j)and(j, i). That is not the strict weak orderingsort.Slicedocuments a requirement for, and the results are then formally unspecified.Descending is now the same comparison with the operands swapped, which is strict in both directions:
Identical change in
sqlite/andduckdb/— the two copies of this function were byte-identical before and after. ClickHouse sorts in SQL and is unaffected.Why this is hygiene and not a fix
I tried to make the old comparator actually misbehave and could not:
Go's pdqsort tolerates the
>=comparator in practice today. So nothing is broken, and no user-visible symptom is being fixed. What the change buys is not depending on tolerance thatsort.Sliceexplicitly does not promise — a future Go release is free to change it.I had initially described this as tied rows reordering between page loads. That was wrong, and the probe above is what corrected it.
No test
None can distinguish the two versions: any behaviour a test could assert holds for the old comparator too, which is exactly what the probe measured. Adding one would be coverage-shaped code that pins nothing.
Precedent
sqlite/task.repository.goalready uses the strict form (>for desc,<for asc) in all four of its sort sites. This brings the two endpoint repositories in line with the pattern already in the package.Verification
go test -race -count=1 ./app/..., the DuckDB-tagged repository suite,go vet ./app/...,gofmt— all clean.Reasonable to close this if you'd rather not carry the churn. It is 6 lines of behaviour-preserving change against a risk that is currently theoretical.
🤖 Generated with Claude Code