Skip to content

Commit

Permalink
Add split(c, n)
Browse files Browse the repository at this point in the history
Returns an `n` elements at a time iterator over collection

```jldoctest
julia> collect(split([1,2,3,4,5], 2))
3-element Array{Array{Int64,1},1}:
 [1,2]
 [3,4]
 [5]
```

workerpool and retry tweaks per @amitmurthy comments
  • Loading branch information
samoconnor committed Mar 12, 2016
1 parent df8eb15 commit 7281a03
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 6 deletions.
8 changes: 5 additions & 3 deletions base/error.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ end


"""
retry(f, [condition], n=3; max_delay=10)
retry(f, [condition]; n=3; max_delay=10)
Returns a lambda that retries function `f` up to `n` times in the
event of an exception. If `condition` is a `Type` then retry only
Expand All @@ -61,7 +61,9 @@ for exceptions of that type. If `condition` is a function
e.g. `retry(http_get, e->e.status == "503")(url)` or `retry(read, UVError)(io)`.
"""
function retry(f::Function, condition::Function=e->true, n::Int=3; max_delay=10)
function retry(f::Function, condition::Function=e->true;
n::Int=3, max_delay::Int=10)

(args...) -> begin
delay = 0.05
for i = 1:n
Expand All @@ -78,7 +80,7 @@ function retry(f::Function, condition::Function=e->true, n::Int=3; max_delay=10)
end
end

retry(f::Function, condition::Type, n::Int=3) = retry(f, e->isa(e, condition), n)
retry(f::Function, t::Type; kw...) = retry(f, e->isa(e, t); kw...)


"""
Expand Down
53 changes: 53 additions & 0 deletions base/iterator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -341,3 +341,56 @@ function collect{I<:IteratorND}(g::Generator{I})
dest[1] = first
return map_to!(g.f, 2, st, dest, g.iter)
end


"""
split(collection, n)
Returns an `n` elements at a time iterator over collection
```jldoctest
julia> collect(split([1,2,3,4,5], 2))
3-element Array{Array{Int64,1},1}:
[1,2]
[3,4]
[5]
julia> collect(split("Hello World!", 5))
3-element Array{ASCIIString,1}:
"Hello"
" Worl"
"d!"
```
"""
function split{T}(c::T, n::Int)
@assert n > 0
return SplitIterator{T}(c, n)
end

type SplitIterator{T}
c::T
n::Int
end

eltype{T<:Union{Vector,AbstractString}}(::Type{SplitIterator{T}}) = T
eltype{T}(::Type{SplitIterator{T}}) = Vector{eltype(T)}

start(itr::SplitIterator) = start(itr.c)

done(itr::SplitIterator, state) = done(itr.c, state)

function next{T<:Union{Vector,AbstractString}}(itr::SplitIterator{T}, state)
l = state
r = min(state + itr.n-1, length(itr.c))
return itr.c[l:r], r + 1
end

function next(itr::SplitIterator, state)
v = Vector{eltype(itr.c)}(itr.n)
i = 0
while !done(itr.c, state) && i < itr.n
i += 1
v[i], state = next(itr.c, state)
end
return resize!(v, i), state
end
4 changes: 2 additions & 2 deletions base/mapiterator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ wait(state::AsyncMapState) = wait(state.task_done)

# Open a @sync block and initialise iterator state.
function start(itr::AsyncMapIterator)
Base.sync_begin()
sync_begin()
AsyncMapState(start(itr.arg_enum), 0, Condition(), false)
end

# Close @sync block when iterator is done.
function done(itr::AsyncMapIterator, state::AsyncMapState)
if !state.done && done(itr.arg_enum, state.enum_state)
state.done = true
Base.sync_end()
sync_end()
end
return state.done
end
Expand Down
2 changes: 1 addition & 1 deletion base/workerpool.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type WorkerPool
channel::RemoteChannel{Channel{Int}}

# Create a shared queue of available workers...
WorkerPool() = new(RemoteChannel(()->Channel{Int}(128)))
WorkerPool() = new(RemoteChannel(()->Channel{Int}(typemax(Int))))
end


Expand Down
2 changes: 2 additions & 0 deletions doc/stdlib/collections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,8 @@ Iterable Collections
Return an array of type ``Array{element_type,1}`` of all items in a collection.

.. function:: collect(n, collection)

.. function:: issubset(a, b)
⊆(a,b) -> Bool
⊈(a,b) -> Bool
Expand Down
29 changes: 29 additions & 0 deletions test/functional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,32 @@ end
@test_throws DimensionMismatch Base.IteratorND(1:2, (2,3))

@test collect(Base.Generator(+, [1,2], [10,20])) == [11,22]

# split(c, n)

let v = collect(split([1,2,3,4,5], 1))
@test all(i->v[i][1] == i, v)
end

let v = collect(split([1,2,3,4,5], 2))
@test v[1] == [1,2]
@test v[2] == [3,4]
@test v[3] == [5]
end

let v = collect(split(enumerate([1,2,3,4,5]), 3))
@test v[1] == [(1,1),(2,2),(3,3)]
@test v[2] == [(4,4),(5,5)]
end

for n in [5,6]
@test collect(split([1,2,3,4,5], n))[1] == [1,2,3,4,5]
@test collect(split(enumerate([1,2,3,4,5]), n))[1] ==
[(1,1),(2,2),(3,3),(4,4),(5,5)]
end


@test_throws AssertionError split([1,2,3,4,5], 0)
@test_throws AssertionError split([1,2,3,4,5], -1)

@test join(split("Hello World!", 5), "|") == "Hello| Worl|d!"

0 comments on commit 7281a03

Please sign in to comment.