diff --git a/README.md b/README.md index 397bf3c..b402410 100644 --- a/README.md +++ b/README.md @@ -83,10 +83,10 @@ vector _without_ the last element. julia> push(v, 6) Persistent{Int64}[1, 2, 3, 4, 5, 6] -julia> peek(v) +julia> pop(v) 5 -julia> pop(v) +julia> butlast(v) Persistent{Int64}[1, 2, 3, 4] ``` @@ -192,7 +192,6 @@ element removed (disjoined). - `children` instead of `arrayof` - standardize "short-fn" interfaces: - `lastchild` instead of `arrayof(node)[end]` -- `peek` should become `pop`, `pop` should become `butlast` - What is Base doing for Arrays w.r.t. `boundscheck!`, can we drop boundcheck for iteration ```jl diff --git a/benchmark/PersistentVectorBench.jl b/benchmark/PersistentVectorBench.jl index 577b7b0..f2814b6 100644 --- a/benchmark/PersistentVectorBench.jl +++ b/benchmark/PersistentVectorBench.jl @@ -10,7 +10,7 @@ const rands = rand(1:1000000, 100000) function appending(::Type{PersistentVector}) function () v = PersistentVector{Int}() - for i=1:250000 + for i = 1:250000 v = append(v, i) end end @@ -18,7 +18,7 @@ end function appending(::Type{Array}) function () a = Int[] - for i=1:250000 + for i = 1:250000 a = push!(a, i) end end @@ -73,7 +73,7 @@ function popping(::Type{PersistentVector}) function () v2 = v for _ in 1:length(v2) - v2 = pop(v2) + v2 = butlast(v2) end end end diff --git a/src/BitmappedVectorTrie.jl b/src/BitmappedVectorTrie.jl index c1f1736..6b4925e 100644 --- a/src/BitmappedVectorTrie.jl +++ b/src/BitmappedVectorTrie.jl @@ -12,7 +12,7 @@ abstract type BitmappedTrie{T} end # Copy elements from one Array to another, up to `n` elements. # function copy_to(from::Array{T}, to::Array{T}, n::Int) where {T} - for i=1:n + for i = 1:n to[i] = from[i] end to @@ -80,14 +80,14 @@ struct DenseLeaf{T} <: DenseBitmappedTrie{T} end DenseLeaf{T}() where {T} = DenseLeaf{T}(T[]) -arrayof( node::DenseNode) = node.arr -shift( node::DenseNode) = node.shift -maxlength( node::DenseNode) = node.maxlength +arrayof(node::DenseNode) = node.arr +shift(node::DenseNode) = node.shift +maxlength(node::DenseNode) = node.maxlength Base.length(node::DenseNode) = node.length -arrayof( leaf::DenseLeaf) = leaf.arr -shift( ::DenseLeaf) = shiftby -maxlength( leaf::DenseLeaf) = trielen +arrayof(leaf::DenseLeaf) = leaf.arr +shift(::DenseLeaf) = shiftby +maxlength(leaf::DenseLeaf) = trielen Base.length(leaf::DenseLeaf) = length(arrayof(leaf)) function promoted(node::DenseBitmappedTrie{T}) where T @@ -108,7 +108,7 @@ function demoted(node::DenseNode{T}) where T end end -function witharr(node::DenseNode{T}, arr::Array, lenshift::Int=0) where T +function witharr(node::DenseNode{T}, arr::Array, lenshift::Int = 0) where T DenseNode{T}(arr, shift(node), length(node) + lenshift, maxlength(node)) end witharr(leaf::DenseLeaf{T}, arr::Array) where {T} = DenseLeaf{T}(arr) @@ -158,14 +158,14 @@ function assoc(node::DenseNode, i::Int, el) witharr(node, newarr) end -peek(bt::DenseBitmappedTrie) = bt[end] +pop(bt::DenseBitmappedTrie) = bt[end] -# Pop is usually destructive, but that doesn't make sense for an immutable -# structure, so `pop` is defined to return a Trie without its last -# element. Use `peek` to access the last element. +# butlast is usually destructive, but that doesn't make sense for an immutable +# structure, so `butlast` is defined to return a Trie without its last +# element. Use `pop` to access the last element. # -pop(leaf::DenseLeaf) = witharr(leaf, arrayof(leaf)[1:end-1]) -function pop(node::DenseNode) +butlast(leaf::DenseLeaf) = witharr(leaf, arrayof(leaf)[1:end - 1]) +function butlast(node::DenseNode) newarr = arrayof(node)[:] newarr[end] = pop(newarr[end]) witharr(node, newarr, -1) @@ -183,7 +183,7 @@ struct SparseNode{T} <: SparseBitmappedTrie{T} maxlength::Int bitmap::Int end -SparseNode(T::Type) = SparseNode{T}(SparseBitmappedTrie{T}[], shiftby*7, 0, trielen^7, 0) +SparseNode(T::Type) = SparseNode{T}(SparseBitmappedTrie{T}[], shiftby * 7, 0, trielen^7, 0) struct SparseLeaf{T} <: SparseBitmappedTrie{T} arr::Vector{T} @@ -191,14 +191,14 @@ struct SparseLeaf{T} <: SparseBitmappedTrie{T} end SparseLeaf{T}() where {T} = SparseLeaf{T}(T[], 0) -arrayof( n::SparseNode) = n.arr -shift( n::SparseNode) = n.shift -maxlength( n::SparseNode) = n.maxlength +arrayof(n::SparseNode) = n.arr +shift(n::SparseNode) = n.shift +maxlength(n::SparseNode) = n.maxlength Base.length(n::SparseNode) = n.length -arrayof( l::SparseLeaf) = l.arr -shift( ::SparseLeaf) = 0 -maxlength( l::SparseLeaf) = trielen +arrayof(l::SparseLeaf) = l.arr +shift(::SparseLeaf) = 0 +maxlength(l::SparseLeaf) = trielen Base.length(l::SparseLeaf) = length(arrayof(l)) function demoted(n::SparseNode{T}) where T @@ -210,9 +210,9 @@ function demoted(n::SparseNode{T}) where T round(Int, maxlength(n) / trielen), 0) end -bitpos( t::SparseBitmappedTrie, i::Int) = 1 << (mask(t, i) - 1) +bitpos(t::SparseBitmappedTrie, i::Int) = 1 << (mask(t, i) - 1) hasindex(t::SparseBitmappedTrie, i::Int) = t.bitmap & bitpos(t, i) != 0 -index( t::SparseBitmappedTrie, i::Int) = +index(t::SparseBitmappedTrie, i::Int) = 1 + count_ones(t.bitmap & (bitpos(t, i) - 1)) function update(l::SparseLeaf{T}, i::Int, el::T) where T @@ -223,7 +223,7 @@ function update(l::SparseLeaf{T}, i::Int, el::T) where T newarr = arrayof(l)[:] newarr[idx] = el else - newarr = vcat(arrayof(l)[1:idx-1], [el], arrayof(l)[idx:end]) + newarr = vcat(arrayof(l)[1:idx - 1], [el], arrayof(l)[idx:end]) end (SparseLeaf{T}(newarr, bitmap), !hasi) end @@ -236,7 +236,7 @@ function update(n::SparseNode{T}, i::Int, el::T) where T newarr[idx] = updated else child, inc = update(demoted(n), i, el) - newarr = vcat(arrayof(n)[1:idx-1], [child], arrayof(n)[idx:end]) + newarr = vcat(arrayof(n)[1:idx - 1], [child], arrayof(n)[idx:end]) end (SparseNode{T}(newarr, n.shift, @@ -277,7 +277,7 @@ end function directindex(t::SparseBitmappedTrie, v::Vector{Int}) isempty(v) && return arrayof(t) local node = arrayof(t) - for i=v + for i = v node = node[i] node = isa(node, SparseBitmappedTrie) ? arrayof(node) : node end diff --git a/src/FunctionalCollections.jl b/src/FunctionalCollections.jl index 5f4a0e7..75fa6c0 100644 --- a/src/FunctionalCollections.jl +++ b/src/FunctionalCollections.jl @@ -11,9 +11,8 @@ const pvec = PersistentVector export PersistentVector, pvec, append, push, - assoc, - peek, - pop + assoc, pop, + butlast include("PersistentMap.jl") @@ -51,7 +50,7 @@ export @Persistent fromexpr(ex::Expr, ::Type{pvec}) = :(pvec($(esc(ex)))) fromexpr(ex::Expr, ::Type{pset}) = :(pset($(map(esc, ex.args[2:end])...))) function fromexpr(ex::Expr, ::Type{phmap}) - kvtuples = [:($(esc(kv.args[end-1])), $(esc(kv.args[end]))) + kvtuples = [:($(esc(kv.args[end - 1])), $(esc(kv.args[end]))) for kv in ex.args[2:end]] :(phmap($(kvtuples...))) end diff --git a/src/PersistentQueue.jl b/src/PersistentQueue.jl index 04c6e4d..2c538ed 100644 --- a/src/PersistentQueue.jl +++ b/src/PersistentQueue.jl @@ -14,26 +14,26 @@ queue = PersistentQueue Base.length(q::PersistentQueue) = q.length Base.isempty(q::PersistentQueue) = (q.length === 0) -peek(q::PersistentQueue) = isempty(q.out) ? head(reverse(q.in)) : head(q.out) +pop(q::PersistentQueue) = isempty(q.out) ? head(reverse(q.in)) : head(q.out) -pop(q::PersistentQueue{T}) where {T} = +butlast(q::PersistentQueue{T}) where {T} = if isempty(q.out) - PersistentQueue{T}(EmptyList{T}(), tail(reverse(q.in)), length(q) - 1) - else - PersistentQueue{T}(q.in, tail(q.out), length(q) - 1) - end + PersistentQueue{T}(EmptyList{T}(), tail(reverse(q.in)), length(q) - 1) +else + PersistentQueue{T}(q.in, tail(q.out), length(q) - 1) +end enq(q::PersistentQueue{T}, val) where {T} = if isempty(q.in) && isempty(q.out) - PersistentQueue{T}(q.in, val..EmptyList{T}(), 1) - else - PersistentQueue{T}(val..q.in, q.out, length(q) + 1) - end + PersistentQueue{T}(q.in, val..EmptyList{T}(), 1) +else + PersistentQueue{T}(val..q.in, q.out, length(q) + 1) +end Base.iterate(q::PersistentQueue) = iterate(q, (q.in, q.out)) -Base.iterate(::PersistentQueue{T}, ::Tuple{EmptyList{T}, EmptyList{T}}) where {T} = nothing -Base.iterate(::PersistentQueue{T}, (in, out)::Tuple{AbstractList{T}, PersistentList{T}}) where {T} = +Base.iterate(::PersistentQueue{T}, ::Tuple{EmptyList{T},EmptyList{T}}) where {T} = nothing +Base.iterate(::PersistentQueue{T}, (in, out)::Tuple{AbstractList{T},PersistentList{T}}) where {T} = head(out), (in, tail(out)) -Base.iterate(q::PersistentQueue{T}, (in, out)::Tuple{PersistentList{T}, EmptyList{T}}) where {T} = +Base.iterate(q::PersistentQueue{T}, (in, out)::Tuple{PersistentList{T},EmptyList{T}}) where {T} = iterate(q, (EmptyList{T}(), reverse(in))) diff --git a/src/PersistentVector.jl b/src/PersistentVector.jl index 8ec580c..c2e6003 100644 --- a/src/PersistentVector.jl +++ b/src/PersistentVector.jl @@ -50,7 +50,7 @@ function Base.getindex(v::PersistentVector, i::Int) end end -peek(v::PersistentVector) = v[end] +pop(v::PersistentVector) = v[end] function push(v::PersistentVector{T}, el) where T if length(v.tail) < trielen @@ -80,10 +80,10 @@ function assoc(v::PersistentVector{T}, i::Int, el) where T end end -function pop(v::PersistentVector{T}) where T +function butlast(v::PersistentVector{T}) where T if isempty(v.tail) - newtail = peek(v.trie)[1:end-1] - PersistentVector{T}(pop(v.trie), newtail, v.length - 1) + newtail = pop(v.trie)[1:end-1] + PersistentVector{T}(butlast(v.trie), newtail, v.length - 1) else newtail = v.tail[1:end-1] PersistentVector{T}(v.trie, newtail, v.length - 1) diff --git a/test/PersistentQueueTest.jl b/test/PersistentQueueTest.jl index e927cff..cf9dc43 100644 --- a/test/PersistentQueueTest.jl +++ b/test/PersistentQueueTest.jl @@ -13,20 +13,20 @@ using Test @test !isempty(PersistentQueue([1])) end - @testset "peek" begin - @test peek(PersistentQueue(1:100)) == 100 - @test try peek(PersistentQueue{Int}()); false catch e true end - end - @testset "pop" begin - @test pop(PersistentQueue(1:100)) == PersistentQueue(1:99) + @test pop(PersistentQueue(1:100)) == 100 @test try pop(PersistentQueue{Int}()); false catch e true end end + @testset "butlast" begin + @test butlast(PersistentQueue(1:100)) == PersistentQueue(1:99) + @test try butlast(PersistentQueue{Int}()); false catch e true end + end + @testset "enq" begin q = PersistentQueue{Int}() - @test peek(enq(q, 1)) == 1 - @test peek(pop(pop(enq(enq(enq(q, 1), 2), 3)))) == 3 + @test pop(enq(q, 1)) == 1 + @test pop(butlast(butlast(enq(enq(enq(q, 1), 2), 3)))) == 3 end @testset "iteration" begin @@ -45,7 +45,7 @@ using Test @test length(PersistentQueue([1, 2, 3])) == 3 @test length(PersistentQueue{Int}()) == 0 - @test length(pop(PersistentQueue([1, 2, 3]))) == 2 + @test length(butlast(PersistentQueue([1, 2, 3]))) == 2 end end diff --git a/test/PersistentVectorTest.jl b/test/PersistentVectorTest.jl index c70bbb4..4038d85 100644 --- a/test/PersistentVectorTest.jl +++ b/test/PersistentVectorTest.jl @@ -5,7 +5,7 @@ import Base.vec function vec(r::UnitRange) v = PersistentVector{Int}() for i in r - v = push(v, i) + v = push(v, i) end v end @@ -13,7 +13,7 @@ end function Base.Array(r::UnitRange) arr = Array(Int, r) for i in r - arr[i] = i + arr[i] = i end arr end @@ -22,13 +22,13 @@ end @testset "range constructor" begin @test typeof(vec(1:1000)) == PersistentVector{Int} - @test typeof(pop(vec(1:1000))) == PersistentVector{Int} + @test typeof(butlast(vec(1:1000))) == PersistentVector{Int} end @testset "length" begin @test length(vec(1:32)) == 32 @test length(vec(1:10000)) == 10000 - @test length(pop(vec(1:1000))) == 999 + @test length(butlast(vec(1:1000))) == 999 end @testset "accessing elements" begin @@ -46,7 +46,7 @@ end end @testset "accessing last" begin - @test peek(vec(1:1000)) == 1000 + @test pop(vec(1:1000)) == 1000 @test vec(1:1000)[end] == 1000 end @@ -90,16 +90,16 @@ end @testset "map" begin v1 = vec(1:5) - @test map((x)->x+1, v1) == PersistentVector([2, 3, 4, 5, 6]) - v2 = PersistentVector{Tuple{Int,Int}}([(1,2),(4,3)]) - @test map((x)->(x[2],x[1]), v2) == PersistentVector{Tuple{Int,Int}}([(2,1),(3,4)]) + @test map((x)->x + 1, v1) == PersistentVector([2, 3, 4, 5, 6]) + v2 = PersistentVector{Tuple{Int,Int}}([(1, 2),(4, 3)]) + @test map((x)->(x[2], x[1]), v2) == PersistentVector{Tuple{Int,Int}}([(2, 1),(3, 4)]) end @testset "filter" begin v1 = vec(1:5) @test filter(iseven, v1) == PersistentVector([2, 4]) - v2 = PersistentVector{Tuple{Int,Int}}([(1,2),(4,3)]) - @test filter((x)->x[2] > x[1], v2) == PersistentVector{Tuple{Int,Int}}([(1,2)]) + v2 = PersistentVector{Tuple{Int,Int}}([(1, 2),(4, 3)]) + @test filter((x)->x[2] > x[1], v2) == PersistentVector{Tuple{Int,Int}}([(1, 2)]) end @testset "hash" begin