Skip to content

Commit

Permalink
Merge branch 'master' into fix346_documenter
Browse files Browse the repository at this point in the history
  • Loading branch information
s-celles committed Nov 20, 2017
2 parents 9865bb4 + 71e6001 commit ceb450a
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 61 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ DataStructures.jl

This package implements a variety of data structures, including

* Deque (based on block-list)
* Deque (implemented with an `unrolled linked list <https://en.wikipedia.org/wiki/Unrolled_linked_list>`_)
* CircularBuffer
* CircularDeque
* Stack
Expand Down
2 changes: 1 addition & 1 deletion docs/src/sorted_containers.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ SortedMultiDict{K,D}(o::Ord, kv) where {K,D,Ord<:Ordering}

### `SortedSets` constructors
```@docs
SortedSet{K,Ord}(o::Ord=Forward, iter=[]) where {K,Ord<:Ordering}
SortedSet{K, Ord <: Ordering}
```

```@docs
Expand Down
6 changes: 3 additions & 3 deletions src/DataStructures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ __precompile__()

module DataStructures

import Base: <, <=, ==, length, isempty, start, next, done,
import Base: <, <=, ==, length, isempty, start, next, done, delete!,
show, dump, empty!, getindex, setindex!, get, get!,
in, haskey, keys, merge, copy, cat,
push!, pop!, shift!, unshift!, insert!,
Expand All @@ -20,12 +20,12 @@ module DataStructures
export deque, enqueue!, dequeue!, dequeue_pair!, update!, reverse_iter
export capacity, num_blocks, front, back, top, top_with_handle, sizehint!

export Accumulator, counter
export Accumulator, counter, reset!, inc!, dec!

export ClassifiedCollections
export classified_lists, classified_sets, classified_counters

export IntDisjointSets, DisjointSets, num_groups, find_root, in_same_set, root_union!
export push!

export AbstractHeap, compare, extract_all!
export BinaryHeap, binary_minheap, binary_maxheap, nlargest, nsmallest
Expand Down
100 changes: 77 additions & 23 deletions src/accumulator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,33 @@ end
Accumulator(::Type{T}, ::Type{V}) where {T,V<:Number} = Accumulator{T,V}(Dict{T,V}())
counter(T::Type) = Accumulator(T,Int)

counter(dct::Dict{T,Int}) where {T} = Accumulator{T,Int}(copy(dct))
counter(dct::Dict{T,V}) where {T,V<:Integer} = Accumulator{T,V}(copy(dct))

"""
counter{T}(seq::AbstractArray)
counter(seq)
Returns an `Accumulator` object containing the elements from `seq`.
"""
function counter(seq::AbstractArray{T}) where T
ct = counter(T)
function counter(seq)
ct = counter(eltype_for_accumulator(seq))
for x in seq
push!(ct, x)
inc!(ct, x)
end
return ct
end

function counter(gen::T) where {T<:Base.Generator}
ct = counter(Base._default_eltype(T))
for x in gen
push!(ct, x)
eltype_for_accumulator(seq::T) where T = eltype(T)
function eltype_for_accumulator(seq::T) where {T<:Base.Generator}
@static if VERSION < v"0.7.0-DEV.2104"
Base._default_eltype(T)
else
Base.@default_eltype(T)
end
return ct
end

copy(ct::Accumulator{T,V}) where {T,V<:Number} = Accumulator{T,V}(copy(ct.map))


copy(ct::Accumulator) = Accumulator(copy(ct.map))

length(a::Accumulator) = length(a.map)

Expand All @@ -44,6 +47,9 @@ get(ct::Accumulator, x, default) = get(ct.map, x, default)

getindex(ct::Accumulator{T,V}, x) where {T,V} = get(ct.map, x, zero(V))

setindex!(ct::Accumulator, x, v) = setindex!(ct.map, x, v)


haskey(ct::Accumulator, x) = haskey(ct.map, x)

keys(ct::Accumulator) = keys(ct.map)
Expand All @@ -61,32 +67,80 @@ done(ct::Accumulator, state) = done(ct.map, state)

# manipulation

push!(ct::Accumulator, x, a::Number) = (ct.map[x] = ct[x] + a)
push!(ct::Accumulator{T,V}, x) where {T,V} = push!(ct, x, one(V))
"""
inc!(ct, x, [v=1])
Increments the count for `x` by `v` (defaulting to one)
"""
inc!(ct::Accumulator, x, a::Number) = (ct[x] += a)
inc!(ct::Accumulator{T,V}, x) where {T,V} = inc!(ct, x, one(V))

# inc! is preferred over push!, but we need to provide push! for the Bag interpreation
# which is used by classified_collections.jl
push!(ct::Accumulator, x) = inc!(ct, x)
push!(ct::Accumulator, x, a::Number) = inc!(ct, x, a)

# To remove ambiguities related to Accumulator now being a subtype of Associative
push!(ct::Accumulator{T,V}, x::T) where T<:Pair where V = push!(ct, x, one(V))
push!(ct::Accumulator{T,V}, x::Pair) where {T,V} = push!(ct, convert(T, x))
push!(ct::Accumulator, x::Pair) = inc!(ct, x)



"""
dec!(ct, x, [v=1])
Decrements the count for `x` by `v` (defaulting to one)
"""
dec!(ct::Accumulator, x, a::Number) = (ct[x] -= a)
dec!(ct::Accumulator{T,V}, x) where {T,V} = dec!(ct, x, one(V))

#TODO: once we are done deprecating `pop!` for `reset!` then add `pop!` as an alias for `dec!`

"""
merge!(ct1, others...)
function push!(ct::Accumulator, r::Accumulator)
for (x, v) in r
push!(ct, x, v)
Merges the other counters into `ctl`,
summing the counts for all elements.
"""
function merge!(ct::Accumulator, other::Accumulator)
for (x, v) in other
inc!(ct, x, v)
end
ct
end

pop!(ct::Accumulator, x) = pop!(ct.map, x)

function merge!(ct1::Accumulator, others::Accumulator...)
for ct in others
push!(ct1,ct)
merge!(ct1,ct)
end
return ct1
end

merge(ct1::Accumulator) = ct1
function merge(ct1::Accumulator{T,V}, others::Accumulator{T,V}...) where {T,V<:Number}

"""
merge(counters...)
Creates a new counter with total counts equal to the sum of the counts in the counters given as arguments.
See also merge!
"""
function merge(ct1::Accumulator, others::Accumulator...)
ct = copy(ct1)
merge!(ct,others...)
return ct
end

"""
reset!(ct::Accumulator, x)
Resets the count of `x` to zero.
Returns its former count.
"""
reset!(ct::Accumulator, x) = pop!(ct.map, x)



## Deprecations
@deprecate pop!(ct::Accumulator, x) reset!(ct, x)
@deprecate push!(ct1::Accumulator, ct2::Accumulator) merge!(ct1,ct2)


25 changes: 14 additions & 11 deletions src/sorted_dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ or SortedSet `sc`. For SortedSet, `haskey(sc,k)` is a synonym for
equivalent to `in(k,keys(sc))`. Time: O(*c* log *n*)
"""
@inline function haskey(m::SortedDict, k_)
i, exactfound = findkey(m.bt,convert(keytype(m),k_))
i, exactfound = findkey(m.bt, convert(keytype(m), k_))
exactfound
end

Expand All @@ -401,30 +401,33 @@ Returns the value associated with key `k` where `sd` is a
SortedDict, or else returns `v` if `k` is not in `sd`. Time: O(*c*
log *n*)
"""
@inline function get(m::SortedDict{K,D,Ord}, k_, default_) where {K,D,Ord <: Ordering}
i, exactfound = findkey(m.bt, convert(K,k_))
return exactfound ? m.bt.data[i].d : convert(D,default_)
function get(default_::Union{Function,Type}, m::SortedDict{K,D}, k_) where {K,D}
i, exactfound = findkey(m.bt, convert(K, k_))
return exactfound ? m.bt.data[i].d : convert(D, default_())
end

get(m::SortedDict, k_, default_) = get(()->default_, m, k_)

"""
get!(sd,k,v)
Returns the value associated with key `k` where `sd` is a
SortedDict, or else returns `v` if `k` is not in `sd`, and in the
latter case, inserts `(k,v)` into `sd`. Time: O(*c* log *n*)
"""
function get!(m::SortedDict{K,D,Ord}, k_, default_) where {K,D,Ord <: Ordering}
function get!(default_::Union{Function,Type}, m::SortedDict{K,D}, k_) where {K,D}
k = convert(K,k_)
i, exactfound = findkey(m.bt, k)
if exactfound
return m.bt.data[i].d
else
default = convert(D,default_)
default = convert(D, default_())
insert!(m.bt,k, default, false)
return default
end
end

get!(m::SortedDict, k_, default_) = get!(()->default_, m, k_)

"""
getkey(sd,k,defaultk)
Expand All @@ -440,7 +443,7 @@ is an Int), then the returned key is the actual stored key rather
than `k`. Time: O(*c* log *n*)
"""
function getkey(m::SortedDict{K,D,Ord}, k_, default_) where {K,D,Ord <: Ordering}
i, exactfound = findkey(m.bt, convert(K,k_))
i, exactfound = findkey(m.bt, convert(K, k_))
exactfound ? m.bt.data[i].k : convert(K, default_)
end

Expand All @@ -456,7 +459,7 @@ is complete, any token addressing the deleted item is invalid.
Returns `sc`. Time: O(*c* log *n*)
"""
@inline function delete!(m::SortedDict, k_)
i, exactfound = findkey(m.bt,convert(keytype(m),k_))
i, exactfound = findkey(m.bt, convert(keytype(m), k_))
!exactfound && throw(KeyError(k_))
delete!(m.bt, i)
m
Expand All @@ -471,7 +474,7 @@ SortedDict or `k` itself in the case of SortedSet. A `KeyError`
results if `k` is not in `sc`. Time: O(*c* log *n*)
"""
@inline function pop!(m::SortedDict, k_)
i, exactfound = findkey(m.bt,convert(keytype(m),k_))
i, exactfound = findkey(m.bt, convert(keytype(m), k_))
!exactfound && throw(KeyError(k_))
d = m.bt.data[i].d
delete!(m.bt, i)
Expand Down Expand Up @@ -538,7 +541,7 @@ returned. This function can be used to reclaim memory after many
deletions. Time: O(*cn* log *n*)
"""
function packcopy(m::SortedDict{K,D,Ord}) where {K,D,Ord <: Ordering}
w = SortedDict(Dict{K,D}(),orderobject(m))
w = SortedDict(Dict{K,D}(), orderobject(m))
mergetwo!(w,m)
w
end
Expand Down
26 changes: 13 additions & 13 deletions src/sorted_set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
## methods similiar to those of the julia Set.


"""
SortedSet(iter, o=Forward)
and
`SortedSet{K}(iter, o=Forward)`
and
`SortedSet(o, iter)`
and
`SortedSet{K}(o, iter)`
Construct a SortedSet using keys given by iterable `iter` (e.g., an
array) and ordering object `o`. The ordering object defaults to
`Forward` if not specified.
"""
mutable struct SortedSet{K, Ord <: Ordering}
bt::BalancedTree23{K,Void,Ord}

"""
SortedSet(iter, o=Forward)
and
`SortedSet{K}(iter, o=Forward)`
and
`SortedSet(o, iter)`
and
`SortedSet{K}(o, iter)`
Construct a SortedSet using keys given by iterable `iter` (e.g., an
array) and ordering object `o`. The ordering object defaults to
`Forward` if not specified.
"""
function SortedSet{K,Ord}(o::Ord=Forward, iter=[]) where {K,Ord<:Ordering}
sorted_set = new{K,Ord}(BalancedTree23{K,Void,Ord}(o))

Expand Down
Loading

4 comments on commit ceb450a

@StephenVavasis
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I look at the doc files associated with this commit, I see many functions listed in sorted_containers.md for which there is no documentation (i.e., just a definition with nothing underneath). Is this what you intended?

@s-celles
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goal wasn't to write docstring for all functions... but just to move documentation build system from Sphinx to Documenter.jl to help running doctests...
I think what you are saying can be done in an other PR to improve documentation

@StephenVavasis
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But what happened to the documentation that was already written on the functions like first() and find()? This documentation seems to be missing from the new md file.

@s-celles
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is a screenshot showing how first documentation appears (automatically from docstring)
screenshot

So doc is not lost (fortunately!)

I suggest to clone my branch
https://github.com/scls19fr/DataStructures.jl/tree/fix346_documenter

and build it using

julia docs/make.jl

the hard part of this PR was to move all doc from md files (initially from rst files) to docstring (into source code over appropriate function definition, sometime 3 times when doc of a function apply to SortedDict, SortedMultiDict, SortedSet

The good side of this, is that it should be easier to document when for example constructors are changing.

Please sign in to comment.