Skip to content

Commit

Permalink
Merge pull request #77 from JuliaLang/ordered_cleanup
Browse files Browse the repository at this point in the history
RFC: Update OrderedDict, OrderedSet constructors to take iterables (fixes #50, #64, #67)
  • Loading branch information
kmsquire committed Mar 5, 2015
2 parents 1d1afe5 + e51ccc6 commit fed1448
Show file tree
Hide file tree
Showing 8 changed files with 530 additions and 36 deletions.
15 changes: 13 additions & 2 deletions src/DataStructures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module DataStructures
import Base: length, isempty, start, next, done,
show, dump, empty!, getindex, setindex!, get, get!,
in, haskey, keys, merge, copy, cat,
push!, pop!, shift!, unshift!,
push!, pop!, shift!, unshift!, insert!,
union!, delete!, similar, sizehint,
isequal, hash,
map, reverse,
Expand Down Expand Up @@ -36,7 +36,7 @@ module DataStructures
export LinkedList, Nil, Cons, nil, cons, head, tail, list, filter, cat,
reverse
export SortedDict, SDToken, SDSemiToken
export insert!, startof
export startof
export pastendtoken, beforestarttoken
export searchsortedafter
export enumerate_ind, packcopy, packdeepcopy
Expand Down Expand Up @@ -67,10 +67,21 @@ module DataStructures
import .Tokens: Token, IntSemiToken, semi, container, assemble
import .Tokens: deref_key, deref_value, deref, status
import .Tokens: advance, regress

include("sortedDict.jl")
export semi, container, assemble, status
export deref_key, deref_value, deref, advance, regress

@deprecate stack Stack
@deprecate queue Queue
@deprecate add! push!

@deprecate HashDict{K,V}(ks::AbstractArray{K}, vs::AbstractArray{V}) HashDict{K,V,Unordered}(ks,vs)
@deprecate HashDict(ks, vs) HashDict{Any,Any,Unordered}(ks, vs)

@deprecate OrderedDict(ks, vs) OrderedDict(zip(ks,vs))
@deprecate OrderedDict{K,V}(ks::AbstractArray{K}, vs::AbstractArray{V}) OrderedDict{K,V}(zip(ks,vs))
@deprecate OrderedDict{K,V}(::Type{K},::Type{V}) OrderedDict{K,V}()

@deprecate OrderedSet(a, b...) OrderedSet({a, b...})
end
6 changes: 3 additions & 3 deletions src/defaultdict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ DefaultDictBase{F,D<:Associative}(default::F, d::D) = ((K,V)=eltype(d); DefaultD

# most functions are simply delegated to the wrapped dictionary
@delegate DefaultDictBase.d [ sizehint, empty!, setindex!, get, haskey,
getkey, pop!, delete!, start, done, next,
isempty, length ]
getkey, pop!, delete!, start, done, next,
isempty, length ]

similar{K,V,F}(d::DefaultDictBase{K,V,F}) = DefaultDictBase{K,V,F}(d.default)
in{T<:DefaultDictBase}(key, v::Base.KeyIterator{T}) = key in keys(v.dict.d)
Expand Down Expand Up @@ -132,7 +132,7 @@ for (DefaultDict,O) in [(:DefaultDict, :Unordered), (:DefaultOrderedDict, :Order
@delegate $DefaultDict.d [ sizehint, empty!, setindex!,
getindex, get, get!, haskey,
getkey, pop!, delete!, start, next,
done, next, isempty, length]
done, next, isempty, length ]

similar{K,V,F}(d::$DefaultDict{K,V,F}) = $DefaultDict{K,V,F}(d.d.default)
in{T<:$DefaultDict}(key, v::Base.KeyIterator{T}) = key in keys(v.dict.d.d)
Expand Down
2 changes: 1 addition & 1 deletion src/disjoint_set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ type DisjointSets{T}
function DisjointSets(xs) # xs must be iterable
imap = Dict{T,Int}()
n = length(xs)
sizehint!(imap, n)
sizehint(imap, n)
id = 0
for x in xs
imap[x] = (id += 1)
Expand Down
33 changes: 28 additions & 5 deletions src/hashdict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type HashDict{K,V,O<:Union(Ordered,Unordered)} <: Associative{K,V}
new(zeros(Uint8,n), Array(K,n), Array(V,n), Array(O,n), Array(O,0), 0, 0, identity)
end
if VERSION >= v"0.4.0-dev+980"
HashDict(p::Pair) = setindex!(HashDict{K,V,O}(), p.second, p.first)
function HashDict(ps::Pair{K,V}...)
h = HashDict{K,V,O}()
sizehint(h, length(ps))
Expand All @@ -31,10 +32,11 @@ type HashDict{K,V,O<:Union(Ordered,Unordered)} <: Associative{K,V}
end
return h
end
HashDict(p::Pair{K,V}) = invoke(HashDict, (Pair{K,V}...), p)
end
function HashDict(ks, vs)
if VERSION >= v"0.4.0-dev+980"
Base.warn_once("HashDict(kv,vs) is deprecated, use HashDict(collect(zip(ks,vs))) instead")
Base.warn_once("HashDict(kv,vs) is deprecated, use HashDict(zip(ks,vs)) instead")
end
n = length(ks)
h = HashDict{K,V,O}()
Expand All @@ -43,7 +45,7 @@ type HashDict{K,V,O<:Union(Ordered,Unordered)} <: Associative{K,V}
end
return h
end
function HashDict(kv::AbstractArray{(K,V)})
function HashDict(kv)
h = HashDict{K,V,O}()
sizehint(h, length(kv))
for (k,v) in kv
Expand All @@ -54,16 +56,27 @@ type HashDict{K,V,O<:Union(Ordered,Unordered)} <: Associative{K,V}
end

HashDict() = HashDict{Any,Any,Unordered}()
HashDict(kv::()) = HashDict()
HashDict(kv) = hash_dict_with_eltype(kv, eltype(kv))

hash_dict_with_eltype{K,V}(kv, ::Type{(K,V)}) = HashDict{K,V}(kv)
hash_dict_with_eltype(kv, t) = HashDict{Any,Any}(kv)

HashDict{K,V}(ks::AbstractArray{K}, vs::AbstractArray{V}) = HashDict{K,V,Unordered}(ks,vs)
HashDict(ks, vs) = HashDict{Any,Any,Unordered}(ks, vs)
HashDict{K,V}(kv::AbstractArray{(K,V)}) = HashDict{K,V,Unordered}(kv)
if VERSION >= v"0.4.0-dev+980"
HashDict{K,V}(ps::Pair{K,V}...) = HashDict{K,V,Unordered}(ps...)
HashDict{K,V}(kv::(Pair{K,V}...,)) = HashDict{K,V}(kv)
HashDict{K} (kv::(Pair{K}...,)) = HashDict{K,Any}(kv)
HashDict{V} (kv::(Pair{TypeVar(:K),V}...,)) = HashDict{Any,V}(kv)
HashDict (kv::(Pair...,)) = HashDict{Any,Any}(kv)

HashDict{K,V}(kv::AbstractArray{Pair{K,V}}) = HashDict{K,V}(kv)

hash_dict_with_eltype{K,V}(kv, ::Type{Pair{K,V}}) = HashDict{K,V}(kv)
end

# TODO: these could be more efficient
HashDict{K,V,O}(d::HashDict{K,V,O}) = HashDict{K,V,O}(collect(kv))
HashDict{K,V,O}(d::HashDict{K,V,O}) = HashDict{K,V,O}(collect(d))
HashDict{K,V}(d::Associative{K,V}) = HashDict{K,V,Unordered}(collect(d))

similar{K,V,O}(d::HashDict{K,V,O}) = HashDict{K,V,O}()
Expand Down Expand Up @@ -517,3 +530,13 @@ next(v::ValueIterator{HashDict}, i) = (v.dict.vals[i], skip_deleted(v.dict,i+1))

next{K,V}(v::KeyIterator{HashDict{K,V,Ordered}}, i) = (v.dict.keys[v.dict.order[i]], skip_deleted(v.dict,i+1))
next{K,V}(v::ValueIterator{HashDict{K,V,Ordered}}, i) = (v.dict.vals[v.dict.order[i]], skip_deleted(v.dict,i+1))

if VERSION >= v"0.4.0-dev+980"
push!(t::HashDict, p::Pair) = setindex!(t, p.second, p.first)
push!(t::HashDict, p::Pair, q::Pair) = push!(push!(t, p), q)
push!(t::HashDict, p::Pair, q::Pair, r::Pair...) = push!(push!(push!(t, p), q), r...)
end

push!(d::HashDict, p) = setindex!(d, p[2], p[1])
push!(d::HashDict, p, q) = push!(push!(d, p), q)
push!(d::HashDict, p, q, r...) = push!(push!(push!(d, p), q), r...)
44 changes: 33 additions & 11 deletions src/ordereddict.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ordered dict

import Base: haskey, get, get!, getkey, delete!, push!, pop!, empty!,
setindex!, getindex, sizehint, length, isempty, start,
setindex!, getindex, length, isempty, start,
next, done, keys, values, setdiff, setdiff!,
union, union!, intersect, isequal, filter, filter!,
hash, eltype
Expand All @@ -19,32 +19,54 @@ immutable OrderedDict{K,V} <: Associative{K,V}
d::HashDict{K,V,Ordered}

OrderedDict() = new(HashDict{K,V,Ordered}())
OrderedDict(kv::AbstractArray{(K,V)}) = new(HashDict{K,V,Ordered}(kv))
OrderedDict(kv) = new(HashDict{K,V,Ordered}(kv))
if VERSION >= v"0.4.0-dev+980"
OrderedDict(ps::Pair{K,V}...) = new(HashDict{K,V,Ordered}(ps...))
end
OrderedDict(ks,vs) = new(HashDict{K,V,Ordered}(ks,vs))
#OrderedDict(ks,vs) = new(HashDict{K,V,Ordered}(ks,vs))
end

OrderedDict() = OrderedDict{Any,Any}()
OrderedDict(kv::()) = OrderedDict()
OrderedDict(kv) = ordered_dict_with_eltype(kv, eltype(kv))

ordered_dict_with_eltype{K,V}(kv, ::Type{(K,V)}) = OrderedDict{K,V}(kv)
ordered_dict_with_eltype(kv, t) = OrderedDict{Any,Any}(kv)

OrderedDict{K,V}(ks::AbstractArray{K}, vs::AbstractArray{V}) = OrderedDict{K,V}(ks,vs)
OrderedDict{K,V}(::Type{K},::Type{V}) = OrderedDict{K,V}()
OrderedDict(ks,vs) = OrderedDict{eltype(ks),eltype(vs)}(ks, vs)
if VERSION >= v"0.4.0-dev+980"
OrderedDict{K,V}(ps::Pair{K,V}...) = OrderedDict{K,V}(ps...)
OrderedDict{K,V}(ps::Pair{K,V}...) = OrderedDict{K,V}(ps...)
OrderedDict{K,V}(kv::(Pair{K,V}...,)) = OrderedDict{K,V}(kv)
OrderedDict{K} (kv::(Pair{K}...,)) = OrderedDict{K,Any}(kv)
OrderedDict{V} (kv::(Pair{TypeVar(:K),V}...,)) = OrderedDict{Any,V}(kv)
OrderedDict (kv::(Pair...,)) = OrderedDict{Any,Any}(kv)

OrderedDict{K,V}(kv::AbstractArray{Pair{K,V}}) = OrderedDict{K,V}(kv)

ordered_dict_with_eltype{K,V}(kv, ::Type{Pair{K,V}}) = OrderedDict{K,V}(kv)
end

OrderedDict{K,V}(kv::AbstractArray{(K,V)}) = OrderedDict{K,V}(kv)
copy(d::OrderedDict) = OrderedDict(d)

## Functions

## Most functions are simply delegated to the wrapped HashDict

@delegate OrderedDict.d [ haskey, get, get!, getkey, delete!, pop!,
empty!, setindex!, getindex, sizehint,
length, isempty, start, next, done, keys,
values ]
empty!, setindex!, getindex,
length, isempty, start, next, done, keys,
values ]

sizehint(d::OrderedDict, sz::Integer) = (sizehint(d.d, sz); d)

if VERSION >= v"0.4.0-dev+980"
push!(d::OrderedDict, kv::Pair) = (push!(d.d, kv); d)
push!(d::OrderedDict, kv::Pair, kv2::Pair) = (push!(d.d, kv, kv2); d)
push!(d::OrderedDict, kv::Pair, kv2::Pair, kv3::Pair...) = (push!(d.d, kv, kv2, kv3...); d)
end

push!(d::OrderedDict, kv) = (push!(d.d, kv); d)
push!(d::OrderedDict, kv, kv2...) = (push!(d.d, kv, kv2...); d)


similar{K,V}(d::OrderedDict{K,V}) = OrderedDict{K,V}()
in{T<:OrderedDict}(key, v::Base.KeyIterator{T}) = key in keys(v.dict.d.d)
13 changes: 7 additions & 6 deletions src/orderedset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ immutable OrderedSet{T}
dict::HashDict{T,Nothing,Ordered}

OrderedSet() = new(HashDict{T,Nothing,Ordered}())
OrderedSet(x...) = union!(new(HashDict{T,Nothing,Ordered}()), x)
OrderedSet(xs) = union!(new(HashDict{T,Nothing,Ordered}()), xs)
end
OrderedSet() = OrderedSet{Any}()
OrderedSet(x...) = OrderedSet{Any}(x...)
OrderedSet{T}(x::T...) = OrderedSet{T}(x...)
OrderedSet(xs) = OrderedSet{eltype(xs)}(xs)

show(io::IO, s::OrderedSet) = (show(io, typeof(s)); Base.show_comma_array(io, s,'(',')'))

@delegate OrderedSet.dict [isempty, length, sizehint]
show(io::IO, s::OrderedSet) = (show(io, typeof(s)); print(io, "("); !isempty(s) && Base.show_comma_array(io, s,'[',']'); print(io, ")"))

@delegate OrderedSet.dict [isempty, length]

sizehint(s::OrderedSet, sz::Integer) = (sizehint(s.dict, sz); s)
eltype{T}(s::OrderedSet{T}) = T

in(x, s::OrderedSet) = haskey(s.dict, x)
Expand All @@ -43,7 +44,7 @@ done(s::OrderedSet, state) = done(s.dict, state)
next(s::OrderedSet, i) = (s.dict.keys[s.dict.order[i]], skip_deleted(s.dict,i+1))

# TODO: simplify me?
pop!(s::OrderedSet) = (val = s.dict.keys[start(s.dict)]; delete!(s.dict, val); val)
pop!(s::OrderedSet) = (val = s.dict.keys[s.dict.order[start(s.dict)]]; delete!(s.dict, val); val)

union(s::OrderedSet) = copy(s)
function union(s::OrderedSet, sets...)
Expand Down
Loading

0 comments on commit fed1448

Please sign in to comment.