Skip to content

Commit

Permalink
WIP more sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
andyferris committed Mar 5, 2021
1 parent 018da9a commit 25d0105
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 32 deletions.
22 changes: 22 additions & 0 deletions src/ArrayDictionary.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,25 @@ end
function Base.empty(d::ArrayDictionary, ::Type{I}, ::Type{T}) where {I, T}
return ArrayDictionary(empty(keys(d), I), empty(parent(d), T))
end

function Base.sort!(d::ArrayDictionary; kwargs...)
p = sortperm(parent(d), kwargs...)
permute!(parent(keys(d)), p)
permute!(parent(d), p)
return d
end

function sortkeys!(d::ArrayDictionary; kwargs...)
p = sortperm(parent(keys(d)), kwargs...)
permute!(parent(keys(d)), p)
permute!(parent(d), p)
return d
end

function sortpairs!(d::ArrayDictionary; by = first, kwargs...)
inds = keys(d)
p = sortperm(Base.OneTo(length(d)); by = by(@inbounds(gettokenvalue(inds, t)) => @inbounds(gettokenvalue(d, t))), kwargs...)
permute!(parent(keys(d)), p)
permute!(parent(d), p)
return d
end
5 changes: 5 additions & 0 deletions src/ArrayIndices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,9 @@ end

function randtoken(rng::Random.AbstractRNG, inds::ArrayIndices)
return rand(rng, keys(parent(inds)))
end

function Base.sort!(inds::ArrayIndices; kwargs...)
sort!(parent(inds), kwargs...)
return inds
end
22 changes: 20 additions & 2 deletions src/Dictionary.jl
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,6 @@ isinsertable(::Dictionary) = true

function gettoken!(dict::Dictionary{I}, i::I) where {I}
return gettoken!(keys(dict), i, (_values(dict),))
#(hadtoken, (slot, index)) = gettoken!(keys(dict), i, (_values(dict),))
#return (hadtoken, (slot, index))
end

function deletetoken!(dict::Dictionary{I, T}, (slot, index)) where {I, T}
Expand Down Expand Up @@ -340,3 +338,23 @@ function Base.similar(indices::Indices{I}, ::Type{T}) where {I, T}
return Dictionary{I, T}(indices, Vector{T}(undef, length(_values(indices))), nothing)
end

function Base.sort!(d::Dictionary; by = identity, kwargs...)
inds = keys(d)
p = sortpermtokens!(inds, (_values(d),); by = t -> by(@inbounds gettokenvalue(d, t)), kwargs...)
permutetokens!(inds, p, (_values(d),))
return d
end

function sortkeys!(d::Dictionary; kwargs...)
inds = keys(d)
p = sortpermtokens!(inds, (_values(d),); kwargs...)
permutetokens!(inds, p, (_values(d),))
return d
end

function sortpairs!(d::Dictionary; by = first, kwargs...)
inds = keys(d)
p = sortpermtokens!(inds, (_values(d),); by = t -> by(@inbounds(gettokenvalue(inds, t)) => @inbounds(gettokenvalue(d, t))), kwargs...)
permutetokens!(inds, p, (_values(d),))
return d
end
34 changes: 32 additions & 2 deletions src/Indices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -527,16 +527,46 @@ function __distinct!(indices::AbstractIndices, itr, s, x_old)
end

function randtoken(rng::Random.AbstractRNG, inds::Indices)
if inds.holes === 0
if _holes(inds) === 0
return (0, rand(rng, Base.OneTo(length(inds))))
end

# Rejection sampling to handle deleted tokens (which are sparse)
range = Base.OneTo(length(_hashes(inds)))
while true
i = rand(rng, range)
if inds.hashes[i] !== deletion_mask
if _hashes(inds)[i] !== deletion_mask
return (0, i)
end
end
end

function Base.sort!(inds::Indices; kwargs...)
p = sortpermtokens!(inds; kwargs)
permutetokens!(inds, p)
return inds
end

function sortpermtokens!(inds::Indices, values = (); by = t -> @inbounds(gettokenvalue(inds, t)), kwargs...)
# Ideally we wouldn't do this... but `Base.permute!` doesn't like holes
if _holes(inds) > 0
rehash!(inds, Base._tablesz(3*length(inds) >> 0x01), values)
end
return sortperm(Base.OneTo(length(inds)); kwargs...)
end

function permutetokens!(inds::Indices, p, values = ())
ip = invperm(p)
permute!(_values(inds), p)
permute!(_hashes(inds), p)
slots = _slots(inds)
@inbounds for i in 1:length(slots)
if slots[i] > 0
slots[i] = ip[slots[i]] # Check if this is the right way around
end
end
foreach(values) do v
permute!(v, p)
end
return inds
end
10 changes: 5 additions & 5 deletions src/indexing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ end

## getproperty is equivalent to indexing with a `Symbol`

@propagate_inbounds Base.getproperty(d::AbstractDictionary, s::Symbol) = d[s]
@propagate_inbounds function Base.setproperty!(d::AbstractDictionary, s::Symbol, x)
d[s] = x
return x
end
# @propagate_inbounds Base.getproperty(d::AbstractDictionary, s::Symbol) = d[s]
# @propagate_inbounds function Base.setproperty!(d::AbstractDictionary, s::Symbol, x)
# d[s] = x
# return x
# end

## Non-scalar indexing

Expand Down
73 changes: 50 additions & 23 deletions src/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function Base.searchsortedlast(d::AbstractDictionary, x)
return nothing
else
return gettokenvalue(keys(d), t)
end
end
end

function searchsortedlasttoken(d::AbstractDictionary, x)
Expand Down Expand Up @@ -68,32 +68,59 @@ function searchsortedlasttoken(d::AbstractDictionary, x)
end
end

function Base.sort(dict::AbstractDictionary; by = identity, kwargs...)
x = collect(tokens(dict))
sort!(x; by = t -> by(@inbounds gettokenvalue(dict, t)), kwargs...)
return @inbounds permutetokens(dict, x)
function Base.sort(dict::AbstractDictionary; kwargs...)
out = copy(dict)
sort!(out; kwargs...)
return out
end

function Base.sortperm(dict::AbstractDictionary; by = identity, kwargs...)
x = collect(tokens(dict))
sort!(x; by = t -> by(@inbounds gettokenvalue(dict, t)), kwargs...)
return @inbounds permutetokens(keys(dict), x)
function sortkeys(dict::AbstractDictionary; kwargs...)
out = copy(dict)
return sortkeys!(out; kwargs...)
return out
end

function permutetokens(dict::AbstractDictionary, perm)
out = empty(dict)
p = pairs(dict)
for t in perm
(i, v) = @inbounds gettokenvalue(p, t)
insert!(out, i, v)
end
function sortpairs(dict::AbstractDictionary; kwargs...)
out = copy(dict)
return sortpairs!(out; kwargs...)
return out
end

function permutetokens(inds::AbstractIndices, perm)
out = empty(inds)
for t in perm
insert!(out, @inbounds gettokenvalue(inds, t))
end
return out
end
# function Base.sortperm(dict::AbstractDictionary; by = identity, kwargs...)
# token_perm = sortpermtokens(dict::AbstractDictionary; by = identity, kwargs...)
# return @inbounds permutetokens(keys(dict), token_perm)
# end

# function sortpermtokens(dict::AbstractDictionary; by = identity, kwargs...)
# x = collect(tokens(dict))
# sort!(x; by = t -> by(@inbounds gettokenvalue(dict, t)), kwargs...)
# out = similar(dict, eltype(x))
# i = 1
# for t in tokens(dict)
# @inbounds settokenvalue!(out, t, x[i])
# i += 1
# end
# return out
# end

# function permutetokens(dict::AbstractDictionary, perm)
# out = empty(dict)
# p = pairs(dict)
# for t in perm
# (i, v) = @inbounds gettokenvalue(p, t)
# insert!(out, i, v)
# end
# return out
# end

# function permutetokens(inds::AbstractIndices, perm)
# out = empty(inds)
# for t in perm
# insert!(out, @inbounds gettokenvalue(inds, t))
# end
# return out
# end

# function permutetokenvalues!(dict::AbstractDictionary, perm)

# end

0 comments on commit 25d0105

Please sign in to comment.