From 01cf9e394b73b0b6499096304e388755f750c8db Mon Sep 17 00:00:00 2001 From: Jun Tian Date: Sat, 26 Feb 2022 10:30:08 +0800 Subject: [PATCH] support popfirst --- src/CircularArrayBuffers.jl | 32 +++++++++++++++++++++++--------- test/runtests.jl | 17 +++++++++-------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/CircularArrayBuffers.jl b/src/CircularArrayBuffers.jl index 97d83f2..974677e 100644 --- a/src/CircularArrayBuffers.jl +++ b/src/CircularArrayBuffers.jl @@ -15,9 +15,9 @@ mutable struct CircularArrayBuffer{T,N} <: AbstractArray{T,N} step_size::Int end -const CircularVectorBuffer{T} = CircularArrayBuffer{T, 1} +const CircularVectorBuffer{T} = CircularArrayBuffer{T,1} -CircularVectorBuffer{T}(n::Integer) where T = CircularArrayBuffer{T}(n) +CircularVectorBuffer{T}(n::Integer) where {T} = CircularArrayBuffer{T}(n) function CircularArrayBuffer{T}(d::Integer...) where {T} N = length(d) @@ -65,7 +65,7 @@ function Base.empty!(cb::CircularArrayBuffer) cb end -function Base.push!(cb::CircularArrayBuffer{T, N}, data) where {T,N} +function Base.push!(cb::CircularArrayBuffer{T,N}, data) where {T,N} if cb.nframes == capacity(cb) cb.first = (cb.first == capacity(cb) ? 1 : cb.first + 1) else @@ -79,22 +79,22 @@ function Base.push!(cb::CircularArrayBuffer{T, N}, data) where {T,N} cb end -function Base.append!(cb::CircularArrayBuffer{T, N}, data) where {T,N} - d, r = divrem(length(data) , cb.step_size) +function Base.append!(cb::CircularArrayBuffer{T,N}, data) where {T,N} + d, r = divrem(length(data), cb.step_size) @assert r == 0 if length(data) >= length(cb.buffer) cb.nframes = capacity(cb) cb.first = 1 cb.buffer[:] .= @view data[end-length(cb.buffer)+1:end] else - start_idx = (cb.first-1) * cb.step_size + length(cb) + 1 + start_idx = (cb.first - 1) * cb.step_size + length(cb) + 1 end_idx = start_idx + length(data) - 1 if start_idx > length(cb.buffer) start_idx -= length(cb.buffer) end_idx -= length(cb.buffer) end if end_idx > length(cb.buffer) - n_first_part = length(cb.buffer)-start_idx+1 + n_first_part = length(cb.buffer) - start_idx + 1 n_second_part = length(data) - n_first_part cb.buffer[end-n_first_part+1:end] .= @view data[1:n_first_part] cb.buffer[1:n_second_part] .= @view data[end-n_second_part+1:end] @@ -115,14 +115,28 @@ function Base.append!(cb::CircularArrayBuffer{T, N}, data) where {T,N} cb end -function Base.pop!(cb::CircularArrayBuffer{T, N}) where {T,N} +function Base.pop!(cb::CircularArrayBuffer{T,N}) where {T,N} if cb.nframes <= 0 throw(ArgumentError("buffer must be non-empty")) else - res = @views cb[ntuple(_ -> (:), N - 1)..., cb.nframes] + res = @views cb.buffer[ntuple(_ -> (:), N - 1)..., _buffer_frame(cb, cb.nframes)] cb.nframes -= 1 res end end +function Base.popfirst!(cb::CircularArrayBuffer{T,N}) where {T,N} + if cb.nframes <= 0 + throw(ArgumentError("buffer must be non-empty")) + else + res = @views cb.buffer[ntuple(_ -> (:), N - 1)..., _buffer_frame(cb, 1)] + cb.nframes -= 1 + cb.first += 1 + if cb.first > capacity(cb) + cb.first = 1 + end + res + end +end + end diff --git a/test/runtests.jl b/test/runtests.jl index a3e2779..5e4a6cb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -72,16 +72,17 @@ using Test @test length(b) == 2 @test b[[1, 2]] == [7, 8] - x = pop!(b) - @test x == 8 + x = popfirst!(b) + @test x == 7 @test length(b) == 1 - @test b[1] == 7 + @test b[1] == 8 x = pop!(b) - @test x == 7 + @test x == 8 @test length(b) == 0 @test_throws ArgumentError pop!(b) + @test_throws ArgumentError popfirst!(b) end @testset "2D Float64" begin @@ -123,12 +124,12 @@ using Test @test b == reshape([c for x in 5:7 for c in x * A], 2, 2, 3) x = pop!(b) - @test x == 7 * ones(2,2) + @test x == 7 * ones(2, 2) @test b == reshape([c for x in 5:6 for c in x * A], 2, 2, 2) end @testset "append!" begin - b = CircularArrayBuffer{Int}(2,3) + b = CircularArrayBuffer{Int}(2, 3) append!(b, zeros(2)) append!(b, 1:4) @test b == [ @@ -136,8 +137,8 @@ using Test 0 2 4 ] - - b = CircularArrayBuffer{Int}(2,3) + + b = CircularArrayBuffer{Int}(2, 3) for i in 1:5 push!(b, fill(i, 2)) end