From d9abe357c76df026fddc6eeb200f8d98a5b71c1a Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Fri, 21 Nov 2025 11:16:53 -0600 Subject: [PATCH 1/2] Make radix sort slightly more hackable --- base/sort.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/sort.jl b/base/sort.jl index 685caa25a33f6..82ac1eda6cd1a 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -982,7 +982,7 @@ struct ConsiderRadixSort{T <: Algorithm, U <: Algorithm} <: Algorithm next::U end ConsiderRadixSort(next) = ConsiderRadixSort(RadixSort(), next) -function _sort!(v::AbstractVector, a::ConsiderRadixSort, o::DirectOrdering, kw) +function _sort!(v::AbstractVector, a::ConsiderRadixSort, o::Ordering, kw) @getkw lo hi mn mx urange = uint_map(mx, o)-uint_map(mn, o) bits = unsigned(top_set_bit(urange)) @@ -1016,7 +1016,7 @@ Each pass divides the input into `2^chunk_size == mask+1` buckets. To do this, i `chunk_size` is larger for larger inputs and determined by an empirical heuristic. """ struct RadixSort <: Algorithm end -function _sort!(v::AbstractVector, a::RadixSort, o::DirectOrdering, kw) +function _sort!(v::AbstractVector, a::RadixSort, o::Ordering, kw) @getkw lo hi mn mx scratch umn = uint_map(mn, o) urange = uint_map(mx, o)-umn From 24330c7fe88f7ca7f64654101922d83c1e0ac0aa Mon Sep 17 00:00:00 2001 From: Lilith Orion Hafner Date: Fri, 21 Nov 2025 11:33:59 -0600 Subject: [PATCH 2/2] Add tests --- test/sorting.jl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/sorting.jl b/test/sorting.jl index 15794abcbec25..94fda6ae045f4 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -1145,6 +1145,25 @@ end @test partialsort!(view(copy(a), :, 6), 500:501) == [500, 501] end +@testset "radix sort extensibility (#60184)" begin + # Note: these are internal behaviors and could break. + # These tests ensure that they don't break unintentionally. + struct A60184 u::UInt end + + uint_order = Order.ord(isless, a -> a.u, false) + + Sort.uint_map(a::A60184, ::typeof(uint_order)) = a.u + Sort.uint_unmap(::Type{A60184}, u::UInt, ::typeof(uint_order)) = A60184(u) + Sort.UIntMappable(::Type{A60184}, ::typeof(uint_order)) = UInt + + v = map(A60184, rand(UInt, 3)); + @test sort(v; order = uint_order) == A60184.(sort([a.u for a in v])) + v = map(A60184, rand(UInt, 41)); + @test sort(v; order = uint_order) == A60184.(sort([a.u for a in v])) + v = map(A60184, rand(UInt, 401)); + @test sort(v; order = uint_order) == A60184.(sort([a.u for a in v])) +end + # This testset is at the end of the file because it is slow. @testset "searchsorted" begin numTypes = [ Int8, Int16, Int32, Int64, Int128,