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

rename QuickerSort to ScratchQuickSort #48160

Merged
merged 3 commits into from
Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ issorted(itr;
issorted(itr, ord(lt,by,rev,order))

function partialsort!(v::AbstractVector, k::Union{Integer,OrdinalRange}, o::Ordering)
_sort!(v, InitialOptimizations(QuickerSort(k)), o, (;))
_sort!(v, InitialOptimizations(QuickBufferSort(k)), o, (;))
maybeview(v, k)
end

Expand Down Expand Up @@ -953,12 +953,12 @@ end


"""
QuickerSort(next::Algorithm=SMALL_ALGORITHM) <: Algorithm
QuickerSort(lo::Union{Integer, Missing}, hi::Union{Integer, Missing}=lo, next::Algorithm=SMALL_ALGORITHM) <: Algorithm
QuickBufferSort(next::Algorithm=SMALL_ALGORITHM) <: Algorithm
QuickBufferSort(lo::Union{Integer, Missing}, hi::Union{Integer, Missing}=lo, next::Algorithm=SMALL_ALGORITHM) <: Algorithm

Use the `QuickerSort` algorithm with the `next` algorithm as a base case.
Use the `QuickBufferSort` algorithm with the `next` algorithm as a base case.

`QuickerSort` is like `QuickSort`, but utilizes scratch space to operate faster and allow
`QuickBufferSort` is like `QuickSort`, but utilizes scratch space to operate faster and allow
for the possibility of maintaining stability.

If `lo` and `hi` are provided, finds and sorts the elements in the range `lo:hi`, reordering
Expand All @@ -976,17 +976,17 @@ Characteristics:
* *quadratic worst case runtime* in pathological cases
(vanishingly rare for non-malicious input)
"""
struct QuickerSort{L<:Union{Integer,Missing}, H<:Union{Integer,Missing}, T<:Algorithm} <: Algorithm
struct QuickBufferSort{L<:Union{Integer,Missing}, H<:Union{Integer,Missing}, T<:Algorithm} <: Algorithm
lo::L
hi::H
next::T
end
QuickerSort(next::Algorithm=SMALL_ALGORITHM) = QuickerSort(missing, missing, next)
QuickerSort(lo::Union{Integer, Missing}, hi::Union{Integer, Missing}) = QuickerSort(lo, hi, SMALL_ALGORITHM)
QuickerSort(lo::Union{Integer, Missing}, next::Algorithm=SMALL_ALGORITHM) = QuickerSort(lo, lo, next)
QuickerSort(r::OrdinalRange, next::Algorithm=SMALL_ALGORITHM) = QuickerSort(first(r), last(r), next)
QuickBufferSort(next::Algorithm=SMALL_ALGORITHM) = QuickBufferSort(missing, missing, next)
QuickBufferSort(lo::Union{Integer, Missing}, hi::Union{Integer, Missing}) = QuickBufferSort(lo, hi, SMALL_ALGORITHM)
QuickBufferSort(lo::Union{Integer, Missing}, next::Algorithm=SMALL_ALGORITHM) = QuickBufferSort(lo, lo, next)
QuickBufferSort(r::OrdinalRange, next::Algorithm=SMALL_ALGORITHM) = QuickBufferSort(first(r), last(r), next)

# select a pivot for QuickerSort
# select a pivot for QuickBufferSort
#
# This method is redefined to rand(lo:hi) in Random.jl
# We can't use rand here because it is not available in Core.Compiler and
Expand Down Expand Up @@ -1029,7 +1029,7 @@ function partition!(t::AbstractVector, lo::Integer, hi::Integer, offset::Integer
pivot_index
end

function _sort!(v::AbstractVector, a::QuickerSort, o::Ordering, kw;
function _sort!(v::AbstractVector, a::QuickBufferSort, o::Ordering, kw;
t=nothing, offset=nothing, swap=false, rev=false)
@getkw lo hi scratch

Expand All @@ -1047,7 +1047,7 @@ function _sort!(v::AbstractVector, a::QuickerSort, o::Ordering, kw;
end
swap = !swap

# For QuickerSort(), a.lo === a.hi === missing, so the first two branches get skipped
# For QuickBufferSort(), a.lo === a.hi === missing, so the first two branches get skipped
if !ismissing(a.lo) && j <= a.lo # Skip sorting the lower part
swap && copyto!(v, lo, t, lo+offset, j-lo)
rev && reverse!(v, lo, j-1)
Expand Down Expand Up @@ -1245,7 +1245,7 @@ the initial optimizations because they can change the input vector's type and or
make them `UIntMappable`.

If the input is not [`UIntMappable`](@ref), then we perform a presorted check and dispatch
to [`QuickerSort`](@ref).
to [`QuickBufferSort`](@ref).

Otherwise, we dispatch to [`InsertionSort`](@ref) for inputs with `length <= 40` and then
perform a presorted check ([`CheckSorted`](@ref)).
Expand Down Expand Up @@ -1277,7 +1277,7 @@ Consequently, we apply [`RadixSort`](@ref) for any reasonably long inputs that r
stage.

Finally, if the input has length less than 80, we dispatch to [`InsertionSort`](@ref) and
otherwise we dispatch to [`QuickerSort`](@ref).
otherwise we dispatch to [`QuickBufferSort`](@ref).
"""
const DEFAULT_STABLE = InitialOptimizations(
IsUIntMappable(
Expand All @@ -1287,9 +1287,9 @@ const DEFAULT_STABLE = InitialOptimizations(
ConsiderCountingSort(
ConsiderRadixSort(
Small{80}(
QuickerSort())))))),
QuickBufferSort())))))),
StableCheckSorted(
QuickerSort())))
QuickBufferSort())))
"""
DEFAULT_UNSTABLE

Expand Down Expand Up @@ -1494,7 +1494,7 @@ function partialsortperm!(ix::AbstractVector{<:Integer}, v::AbstractVector,
end

# do partial quicksort
_sort!(ix, InitialOptimizations(QuickerSort(k)), Perm(ord(lt, by, rev, order), v), (;))
_sort!(ix, InitialOptimizations(QuickBufferSort(k)), Perm(ord(lt, by, rev, order), v), (;))

maybeview(ix, k)
end
Expand Down
20 changes: 10 additions & 10 deletions test/sorting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ end
end

@testset "stability" begin
for Alg in [InsertionSort, MergeSort, Base.Sort.QuickerSort(), Base.DEFAULT_STABLE,
Base.Sort.QuickerSort(missing, 1729), Base.Sort.QuickerSort(1729, missing)]
for Alg in [InsertionSort, MergeSort, Base.Sort.QuickBufferSort(), Base.DEFAULT_STABLE,
Base.Sort.QuickBufferSort(missing, 1729), Base.Sort.QuickBufferSort(1729, missing)]
@test issorted(sort(1:2000, alg=Alg, by=x->0))
@test issorted(sort(1:2000, alg=Alg, by=x->x÷100))
end
Expand Down Expand Up @@ -333,7 +333,7 @@ end
@test c == v

# stable algorithms
for alg in [MergeSort, Base.Sort.QuickerSort(), Base.Sort.QuickerSort(1:n), Base.DEFAULT_STABLE]
for alg in [MergeSort, Base.Sort.QuickBufferSort(), Base.Sort.QuickBufferSort(1:n), Base.DEFAULT_STABLE]
p = sortperm(v, alg=alg, rev=rev)
p2 = sortperm(float(v), alg=alg, rev=rev)
@test p == p2
Expand Down Expand Up @@ -381,7 +381,7 @@ end
end

v = randn_with_nans(n,0.1)
for alg in [InsertionSort, MergeSort, Base.Sort.QuickerSort(), Base.Sort.QuickerSort(1, n), Base.DEFAULT_UNSTABLE, Base.DEFAULT_STABLE],
for alg in [InsertionSort, MergeSort, Base.Sort.QuickBufferSort(), Base.Sort.QuickBufferSort(1, n), Base.DEFAULT_UNSTABLE, Base.DEFAULT_STABLE],
rev in [false,true]
alg === InsertionSort && n >= 3000 && continue
# test float sorting with NaNs
Expand Down Expand Up @@ -588,7 +588,7 @@ end

@testset "fallback" begin
@test adaptive_sort_test(rand(1:typemax(Int32), len), by=x->x^2)# fallback
@test adaptive_sort_test(rand(Int, len), by=x->0, trusted=Base.Sort.QuickerSort())
@test adaptive_sort_test(rand(Int, len), by=x->0, trusted=Base.Sort.QuickBufferSort())
end

@test adaptive_sort_test(rand(Int, 20)) # InsertionSort
Expand Down Expand Up @@ -692,7 +692,7 @@ end
# not allowed. Consequently, none of the behavior tested in this
# testset is guaranteed to work in future minor versions of Julia.

safe_algs = [InsertionSort, MergeSort, Base.Sort.QuickerSort(), Base.DEFAULT_STABLE, Base.DEFAULT_UNSTABLE]
safe_algs = [InsertionSort, MergeSort, Base.Sort.QuickBufferSort(), Base.DEFAULT_STABLE, Base.DEFAULT_UNSTABLE]

n = 1000
v = rand(1:5, n);
Expand Down Expand Up @@ -899,8 +899,8 @@ end
@test issorted(sort(rand(Int8, 600)))
end

@testset "QuickerSort API" begin
bsqs = Base.Sort.QuickerSort
@testset "QuickBufferSort API" begin
bsqs = Base.Sort.QuickBufferSort
@test bsqs(1, 2, MergeSort) === bsqs(1, 2, MergeSort)
@test bsqs(missing, 2, MergeSort) === bsqs(missing, 2, MergeSort)
@test bsqs(1, missing, MergeSort) === bsqs(1, missing, MergeSort)
Expand All @@ -918,10 +918,10 @@ end
@test bsqs() === bsqs(missing, missing, InsertionSort)
end

@testset "QuickerSort allocations on non-concrete eltype" begin
@testset "QuickBufferSort allocations on non-concrete eltype" begin
v = Vector{Union{Nothing, Bool}}(rand(Bool, 10000))
@test 4 == @allocations sort(v)
@test 4 == @allocations sort(v; alg=Base.Sort.QuickerSort())
@test 4 == @allocations sort(v; alg=Base.Sort.QuickBufferSort())
# it would be nice if these numbers were lower (1 or 2), but these
# test that we don't have O(n) allocations due to type instability
end
Expand Down