-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathWindowBuffer.jl
50 lines (39 loc) · 1.65 KB
/
WindowBuffer.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using DataStructures
"""
Maintains a rolling window of the last `window_size` values
using an efficient circular buffer with O(1) push and pop operations.
# Arguments
- `window_size::Int`: The size of the window to maintain.
- `copy::Bool=false`: If `true`, the result will be a copy of the data as `Vector{In}`,
otherwise it will be a `view` into the underlying buffer.
The implementation is based on [DataStructures.jl](https://juliacollections.github.io/DataStructures.jl/latest/)'s [CircularBuffer](https://juliacollections.github.io/DataStructures.jl/latest/circ_buffer/).
Note that the returned value is a view into the buffer, so it is not a copy of the data,
hence the result should not be modified or stored for later use.
If temporary storage of the result or modification of the values is needed, a copy should be made.
"""
mutable struct WindowBuffer{T,copy} <: StreamOperation
const buffer::CircularBuffer{T}
const copy::Bool
WindowBuffer{T}(
window_size::Int
;
copy::Bool=false
) where {T} = begin
buffer = CircularBuffer{T}(window_size)
new{T,copy}(buffer, copy)
end
end
@inline function (op::WindowBuffer{T})(executor, value::T) where {T}
# automatically handles overwriting in a circular manner
push!(op.buffer, value)
nothing
end
@inline is_valid(op::WindowBuffer) = isfull(op.buffer)
@inline function get_state(op::WindowBuffer{T,false}) where {T}
view(op.buffer, :)
end
@inline function get_state(op::WindowBuffer{T,true}) where {T}
collect(op.buffer)
end
@inline Base.empty!(op::WindowBuffer) = empty!(op.buffer)
@inline Base.length(op::WindowBuffer) = length(op.buffer)