Skip to content

todo: change peek to pop and pop to butlast #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
```

Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions benchmark/PersistentVectorBench.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ 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
end
function appending(::Type{Array})
function ()
a = Int[]
for i=1:250000
for i = 1:250000
a = push!(a, i)
end
end
Expand Down Expand Up @@ -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
Expand Down
52 changes: 26 additions & 26 deletions src/BitmappedVectorTrie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -183,22 +183,22 @@ 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}
bitmap::Int
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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down
7 changes: 3 additions & 4 deletions src/FunctionalCollections.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ const pvec = PersistentVector

export PersistentVector, pvec,
append, push,
assoc,
peek,
pop
assoc, pop,
butlast

include("PersistentMap.jl")

Expand Down Expand Up @@ -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
Expand Down
26 changes: 13 additions & 13 deletions src/PersistentQueue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
8 changes: 4 additions & 4 deletions src/PersistentVector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
18 changes: 9 additions & 9 deletions test/PersistentQueueTest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
20 changes: 10 additions & 10 deletions test/PersistentVectorTest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ 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

function Base.Array(r::UnitRange)
arr = Array(Int, r)
for i in r
arr[i] = i
arr[i] = i
end
arr
end
Expand All @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down