diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 110ea6d..2ef15e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: matrix: version: - '1.0' - - '1.5' + - '1' - 'nightly' os: - ubuntu-latest diff --git a/Project.toml b/Project.toml index 7b4d0a8..5d8c970 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "CircularArrayBuffers" uuid = "9de3a189-e0c0-4e15-ba3b-b14b9fb0aec1" authors = ["Jun Tian and contributors"] -version = "0.1.2" +version = "0.1.3" [compat] julia = "1" diff --git a/src/CircularArrayBuffers.jl b/src/CircularArrayBuffers.jl index 1270f7f..97d83f2 100644 --- a/src/CircularArrayBuffers.jl +++ b/src/CircularArrayBuffers.jl @@ -79,6 +79,42 @@ 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) + @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 + 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_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] + else + cb.buffer[start_idx:end_idx] .= data + end + + if cb.nframes + d > capacity(cb) + cb.first += cb.nframes + d - capacity(cb) + if cb.first > capacity(cb) + cb.first -= capacity(cb) + end + cb.nframes = capacity(cb) + else + cb.nframes += d + end + end + cb +end + function Base.pop!(cb::CircularArrayBuffer{T, N}) where {T,N} if cb.nframes <= 0 throw(ArgumentError("buffer must be non-empty")) diff --git a/test/runtests.jl b/test/runtests.jl index 3750486..a3e2779 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -126,4 +126,32 @@ using Test @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) + append!(b, zeros(2)) + append!(b, 1:4) + @test b == [ + 0 1 3 + 0 2 4 + ] + + + b = CircularArrayBuffer{Int}(2,3) + for i in 1:5 + push!(b, fill(i, 2)) + end + empty!(b) + append!(b, 1:4) + @test b == [ + 1 3 + 2 4 + ] + + append!(b, 5:8) + @test b == [ + 3 5 7 + 4 6 8 + ] + end end