Buffer
A Buffer
is a used to buffer the data flowing the connections of a model. Data can be read from and written into a buffer. The mode of the buffer determines the way to read from and write into the buffers.
Buffer Modes
BufferMode
determines the way the data is read from and written into a Buffer
. Basically, there are four buffer modes: Normal
, Cyclic
, Fifo
and Lifo
. Normal
, Fifo
and Lifo
are subtypes of LinearMode
and Cyclic
is a subtype of CyclicMode
.
Buffer Constructors
The Buffer
construction is very similar to the construction of arrays in Julia. Just specify the mode, element type and length of the buffer. Here are some examples:
julia> using Causal # hide
julia> Buffer{Fifo}(2, 5)
2×5 Buffer{Fifo,Float64,2}
julia> Buffer{Cyclic}(2, 10)
2×10 Buffer{Cyclic,Float64,2}
julia> Buffer{Lifo}(Bool, 2, 5)
2×5 Buffer{Lifo,Bool,2}
julia> Buffer(5)
5-element Buffer{Cyclic,Float64,1}
Writing Data into Buffers
Writing data into a Buffer
is done with write!
function. Recall that when the buffer is full, no more data can be written into the buffer if the buffer mode is of type LinearMode
.
julia> normalbuf = Buffer{Normal}(3)
3-element Buffer{Normal,Float64,1}
julia> foreach(item -> write!(normalbuf, item), 1:3)
julia> normalbuf
3-element Buffer{Normal,Float64,1}:
3.0
2.0
1.0
julia> write!(normalbuf, 4.)
ERROR: Buffer is full
This situation is the same for Lifo
and Fifo
buffers, but not the case for Cyclic
buffer.
julia> cyclicbuf = Buffer{Cyclic}(3)
3-element Buffer{Cyclic,Float64,1}
julia> foreach(item -> write!(cyclicbuf, item), 1:3)
julia> cyclicbuf
3-element Buffer{Cyclic,Float64,1}:
3.0
2.0
1.0
julia> write!(cyclicbuf, 3.)
3.0
julia> write!(cyclicbuf, 4.)
4.0
Reading Data from Buffers
Reading data from a Buffer
is done with read
function.
julia> using Causal # hide
julia> nbuf, cbuf, fbuf, lbuf = Buffer{Normal}(5), Buffer{Cyclic}(5), Buffer{Lifo}(5), Buffer{Fifo}(5)
(Buffer(mode:Normal, eltype:Float64, size:(5,), index:1, state:empty), Buffer(mode:Cyclic, eltype:Float64, size:(5,), index:1, state:empty), Buffer(mode:Lifo, eltype:Float64, size:(5,), index:1, state:empty), Buffer(mode:Fifo, eltype:Float64, size:(5,), index:1, state:empty))
julia> foreach(buf -> foreach(item -> write!(buf, item), 1 : 5), [nbuf, cbuf, fbuf, lbuf])
julia> for buf in [nbuf, cbuf, fbuf, lbuf]
@show buf
for i in 1 : 5
@show read(buf)
end
end
buf = Buffer(mode:Normal, eltype:Float64, size:(5,), index:6, state:full)
read(buf) = 5.0
read(buf) = 5.0
read(buf) = 5.0
read(buf) = 5.0
read(buf) = 5.0
buf = Buffer(mode:Cyclic, eltype:Float64, size:(5,), index:1, state:full)
read(buf) = 5.0
read(buf) = 5.0
read(buf) = 5.0
read(buf) = 5.0
read(buf) = 5.0
buf = Buffer(mode:Lifo, eltype:Float64, size:(5,), index:6, state:full)
read(buf) = 5.0
read(buf) = 4.0
read(buf) = 3.0
read(buf) = 2.0
read(buf) = 1.0
buf = Buffer(mode:Fifo, eltype:Float64, size:(5,), index:6, state:full)
read(buf) = 1.0
read(buf) = 2.0
read(buf) = 3.0
read(buf) = 4.0
read(buf) = 5.0
AbstractArray Interface of Buffers
A Buffer
can be indexed using the similar syntax of arrays in Julia. That is, getindex
and setindex!
methods can be used with known Julia syntax. i.e. getindex(buf, idx)
is equal to buf[idx]
and setindex(buf, val, idx)
is equal to buf[idx] = val
.
julia> buf = Buffer(5)
5-element Buffer{Cyclic,Float64,1}
julia> size(buf)
(5,)
julia> length(buf)
5
julia> for val in 1 : 5
write!(buf, 2val)
end
julia> buf[1]
10.0
julia> buf[3:4]
2-element Array{Float64,1}:
6.0
4.0
julia> buf[[3, 5]]
2-element Array{Float64,1}:
6.0
2.0
julia> buf[end]
2.0
julia> buf[1] = 5
5
julia> buf[3:5] = [7, 8, 9]
3-element Array{Int64,1}:
7
8
9
Full API
Causal.Buffer
— Typemutable struct Buffer{M<:BufferMode, T, N} <: AbstractArray{T,N}
Constructs a Buffer
of size sz
with element type of T
. M
is the mode of the Buffer
that determines how data is to read from and written into the Buffer
. There exists for different buffer modes:
The default mode for Buffer
is Cyclic
and default element type is Float64
.
Buffer{M}(sz::Int...) where {M, T}
Constructs a Buffer
of size sz
and with element type of T
and mode M
.
Buffer(dtype::Type{T}, sz::Int...) where T
Constructs a Buffer
of size sz
and element type T
. The mode of buffer is Cyclic
.
Buffer(sz::Int...)
Constructs a Buffer
of size sz
with mode Cyclic
and element type of Float64
.
Buffer{M}(data::AbstractVecOrMat{T}) where {M, T<:Real}
Constructs a Buffer
with data
.
Fields
internals::Array{Array{T,N},1} where N where T
Internal data containers
src::Int64
Input containter
dst::Int64
Output container
index::Int64
Buffer index
state::Symbol
Current state of buffer. May be :full, :empty, :nonempty
id::Base.UUID
Unique identifier
Example
julia> buf = Buffer(5)
5-element Buffer{Cyclic,Float64,1}
julia> buf = Buffer{Fifo}(2, 5)
2×5 Buffer{Fifo,Float64,2}
julia> buf = Buffer{Lifo}(collect(reshape(1:8, 2, 4)))
2×4 Buffer{Lifo,Int64,2}
Causal.BufferMode
— Typeabstract type BufferMode
Abstract type for buffer mode. Subtypes of BufferMode
is CyclicMode
and LinearMode
.
Causal.Cyclic
— Typestruct Cyclic <: CyclicMode
Cyclic buffer mode. The data is written to buffer until the buffer is full. When the buffer is full, new data is written by overwriting the data available in the buffer starting from the beginning of the buffer. When the buffer is read, the element written last is returned and the returned element is not deleted from the buffer.
Causal.CyclicMode
— Typeabstract type CyclicMode <: BufferMode
Abstract type of cyclic buffer modes. See Cyclic
Causal.Fifo
— Typestruct Fifo <: LinearMode
Fifo (First-in-last-out) buffer mode. This type of buffer is a first-in-first-out buffer. The data is written to the buffer until the buffer is full. When the buffer is full, no more element can be written into the buffer. When read, the first element written into the buffer is returned. The returned element is deleted from the buffer.
Causal.Lifo
— Typestruct Lifo <: LinearMode
Lifo (Last-in-first-out) buffer mode. This type of buffer is a last-in-first-out buffer. Data is written to the buffer until the buffer is full. When the buffer is full, no more element can be written into the buffer. When read, the last element written into buffer is returned. The returned element is deleted from the buffer.
Causal.LinearMode
— TypeCausal.Normal
— Typestruct Normal <: LinearMode
LinearMode buffer mode. The data is written to buffer until the buffer is full. When it is full, no more data is written to the buffer. When read, the data written last is returned and the returned data is not deleted from the internal container of the buffer.
Base.getindex
— Methodgetindex(buf, idx)
Returns an element from buf
at index idx
. Same as buf[idx]
Example
julia> buf = Buffer(2, 5); # Construct a buffer.
julia> write!(buf, reshape(2 : 2 : 20, 2, 5)) # Write data into buffer.
julia> buf[1]
18.0
julia> buf[1, 2]
14.0
julia> buf[1, end]
2.0
julia> buf[:, 2]
2-element Array{Float64,1}:
14.0
16.0
Base.isempty
— Methodisempty(buf)
Returns true
if the index of buf
is 1.
Base.read
— Methodread(buf)
Reads an element from buf
. Reading is performed according to the mode of buf
. See also: Normal
, Cyclic
, Lifo
, Fifo
for buffer modes.
Example
julia> buf = Buffer(3)
3-element Buffer{Cyclic,Float64,1}
julia> write!(buf, [2, 4, 6])
julia> for i = 1 : 3
@show (read(buf), buf.internals)
end
(read(buf), buf.internals) = (6.0, [[6.0, 4.0, 2.0], [4.0, 2.0, 0.0]])
(read(buf), buf.internals) = (6.0, [[6.0, 4.0, 2.0], [4.0, 2.0, 0.0]])
(read(buf), buf.internals) = (6.0, [[6.0, 4.0, 2.0], [4.0, 2.0, 0.0]])
julia> buf = Buffer{Fifo}(5)
5-element Buffer{Fifo,Float64,1}
julia> write!(buf, [2, 4, 6])
julia> for i = 1 : 3
@show (read(buf), buf.internals)
end
(read(buf), buf.internals) = (2.0, [[6.0, 4.0, 0.0, 0.0, 0.0], [4.0, 2.0, 0.0, 0.0, 0.0]])
(read(buf), buf.internals) = (4.0, [[6.0, 0.0, 0.0, 0.0, 0.0], [4.0, 2.0, 0.0, 0.0, 0.0]])
(read(buf), buf.internals) = (6.0, [[0.0, 0.0, 0.0, 0.0, 0.0], [4.0, 2.0, 0.0, 0.0, 0.0]])
Base.setindex!
— Methodsetindex!(buf, item, idx)
Sets val
to buf
at index idx
. Same as buf[idx] = val
.
Example
julia> buf = Buffer(2, 5);
julia> buf[1] = 1
1
julia> buf[:, 2] = [1, 1]
2-element Array{Int64,1}:
1
1
julia> buf[end] = 10
10
julia> buf.internals
2-element Array{Array{Float64,2},1}:
[1.0 1.0 … 0.0 0.0; 0.0 1.0 … 0.0 10.0]
[0.0 0.0 … 0.0 0.0; 0.0 0.0 … 0.0 0.0]
Base.size
— Methodsize(buf)
Returns the size of buf
.
Causal.clean!
— Methodclean!(buf)
Cleans the contents of buf
.
Causal.content
— Methodcontent(buf; flip)
Returns the current data of buf
. If flip
is true
, the data to be returned is flipped. See also snapshot
Example
julia> buf = Buffer(5);
julia> write!(buf, 1:3)
julia> content(buf, flip=false)
3-element Array{Float64,1}:
3.0
2.0
1.0
julia> buf = Buffer(2, 5);
julia> write!(buf, reshape(1:10, 2, 5))
julia> content(buf)
2×5 Array{Float64,2}:
1.0 3.0 5.0 7.0 9.0
2.0 4.0 6.0 8.0 10.0
Causal.datalength
— MethodReturns the maximum number of data that can be hold in buf
.
Example
julia> buf = Buffer(5);
julia> datalength(buf)
5
julia> buf2 = Buffer(2, 10);
julia> datalength(buf2)
10
Causal.inbuf
— Methodinbuf(buf)
Returns the element of internals
of buf
that is used to input data to buf
. See also [outbuf
][@ref)
Causal.isfull
— Methodisfull(buf)
Returns true
if the index of buf
is equal to the length of buf
.
Causal.ishit
— Methodishit(buf)
Returns true when buf
index is an integer multiple of datalength of buf
.
Example
julia> buf = Buffer(3);
julia> for val in 1 : 7
write!(buf, val)
@show ishit(buf)
end
ishit(buf) = false
ishit(buf) = false
ishit(buf) = true
ishit(buf) = false
ishit(buf) = false
ishit(buf) = true
ishit(buf) = false
Causal.mode
— MethodCausal.outbuf
— Methodoutbuf(buf)
Returns the element of intervals
of buf
that is used to take data out of buf
. See also: inbuf
Causal.snapshot
— Methodsnapshot(buf)
Returns all elements in buf
. See also: content
Causal.write!
— Methodwrite!(buf, val)
Writes each column of vals
into buf
.
!!! warning Buffer mode determines how data is written into buffers. See also: Normal
, Cyclic
, Lifo
, Fifo
for buffer modes.
Example
julia> buf = Buffer(5)
5-element Buffer{Cyclic,Float64,1}
julia> write!(buf, 1.)
1.0
julia> write!(buf, [2, 3])
julia> buf.internals
2-element Array{Array{Float64,1},1}:
[3.0, 2.0, 1.0, 0.0, 0.0]
[2.0, 1.0, 0.0, 0.0, 0.0]
julia> buf = Buffer(2,5)
2×5 Buffer{Cyclic,Float64,2}
julia> write!(buf, [1, 1])
2-element Array{Int64,1}:
1
1
julia> write!(buf, [2 3; 2 3])
julia> buf.internals
2-element Array{Array{Float64,2},1}:
[3.0 2.0 … 0.0 0.0; 3.0 2.0 … 0.0 0.0]
[2.0 1.0 … 0.0 0.0; 2.0 1.0 … 0.0 0.0]