mirror of https://bitbucket.org/ausocean/av.git
used size ring buffer rather than channel
This commit is contained in:
parent
1b6a2ae8ea
commit
89b4468f6c
|
@ -38,7 +38,8 @@ RingBuffer aims to provide functionality of a RingBuffer data structure.
|
|||
It may be used in concurrent routines.
|
||||
*/
|
||||
type ringBuffer struct {
|
||||
memory [][]byte
|
||||
dataMemory [][]byte
|
||||
sizeMemory []int
|
||||
size int
|
||||
noOfElements int
|
||||
first int
|
||||
|
@ -51,17 +52,18 @@ type ringBuffer struct {
|
|||
|
||||
/*
|
||||
New returns the addres of a new ring buffer with the parameters specified.
|
||||
It initialises fields and allocates the required memory.
|
||||
It initialises fields and allocates the required dataMemory.
|
||||
*/
|
||||
func NewRingBuffer(size int, elementSize int) (rb *ringBuffer) {
|
||||
if size <= 0 || elementSize <= 0 {
|
||||
return nil
|
||||
}
|
||||
rb = new(ringBuffer)
|
||||
rb.memory = make([][]byte, size)
|
||||
for i := range rb.memory {
|
||||
rb.memory[i] = make([]byte, elementSize)
|
||||
rb.dataMemory = make([][]byte, size)
|
||||
for i := range rb.dataMemory {
|
||||
rb.dataMemory[i] = make([]byte, elementSize)
|
||||
}
|
||||
rb.sizeMemory = make([]int, size)
|
||||
rb.size = size
|
||||
rb.noOfElements = 0
|
||||
rb.first = -1
|
||||
|
@ -92,7 +94,7 @@ func (rb *ringBuffer) Get() ([]byte, error) {
|
|||
if nextlast == rb.size {
|
||||
nextlast = 0
|
||||
}
|
||||
return rb.memory[nextlast], nil
|
||||
return rb.dataMemory[nextlast], nil
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -109,11 +111,11 @@ func (rb *ringBuffer) DoneWriting(size int) error {
|
|||
if rb.first == -1 {
|
||||
rb.first++
|
||||
}
|
||||
rb.sizeChannel <- size
|
||||
rb.last++
|
||||
if rb.last == rb.size {
|
||||
rb.last = 0
|
||||
}
|
||||
rb.sizeMemory[rb.last] = size
|
||||
rb.noOfElements++
|
||||
rb.currentlyWriting = false
|
||||
return nil
|
||||
|
@ -126,17 +128,17 @@ calls to Get. The address of the data is returned, as well as the size of
|
|||
the data contained at this address. An error is returned if the buffer is
|
||||
empty, or there has been a second call to Read before a call to DoneReading.
|
||||
*/
|
||||
func (rb *ringBuffer) Read() ([]byte, int, error) {
|
||||
func (rb *ringBuffer) Read() ([]byte, error) {
|
||||
rb.mutex.Lock()
|
||||
defer rb.mutex.Unlock()
|
||||
if !rb.CanRead() {
|
||||
return nil, 0, errors.New("Buffer is empty, nothging to read!")
|
||||
return nil, errors.New("Buffer is empty, nothging to read!")
|
||||
}
|
||||
if rb.currentlyReading {
|
||||
return nil, 0, errors.New("Second call to Read! Call DoneReading first!")
|
||||
return nil, errors.New("Second call to Read! Call DoneReading first!")
|
||||
}
|
||||
rb.currentlyReading = true
|
||||
return rb.memory[rb.first], <-rb.sizeChannel, nil
|
||||
return rb.dataMemory[rb.first][:rb.sizeMemory[rb.first]], nil
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -49,10 +49,10 @@ func noErrorFail(t *testing.T) {
|
|||
// size of 10 and arbitrary element size of 10
|
||||
func TestMake(t *testing.T) {
|
||||
rb = NewRingBuffer(10, 10)
|
||||
if len(rb.memory) != 10 {
|
||||
if len(rb.dataMemory) != 10 {
|
||||
t.Errorf("Len of buffer is wrong!")
|
||||
}
|
||||
if len(rb.memory[0]) != 10 {
|
||||
if len(rb.dataMemory[0]) != 10 {
|
||||
t.Errorf("Len of individual element is wrong!")
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func TestDoneReading1(t *testing.T) {
|
|||
// Test read when there hasn't been anything written to buffer
|
||||
func TestReadingWithoutWrite(t *testing.T) {
|
||||
rb = NewRingBuffer(10, 10)
|
||||
_, _, err := rb.Read()
|
||||
_, err := rb.Read()
|
||||
if err == nil {
|
||||
noErrorFail(t)
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ func TestDoneReading2(t *testing.T) {
|
|||
rb = NewRingBuffer(10, 10)
|
||||
_, err := rb.Get()
|
||||
rb.DoneWriting(1)
|
||||
_, _, err = rb.Read()
|
||||
_, err = rb.Read()
|
||||
if err != nil {
|
||||
falseErrorFail(t, err)
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ func TestWritingAndReading1(t *testing.T) {
|
|||
if err := rb.DoneWriting(1); err != nil {
|
||||
falseErrorFail(t, err)
|
||||
}
|
||||
if _, _, err := rb.Read(); err != nil {
|
||||
if _, err := rb.Read(); err != nil {
|
||||
falseErrorFail(t, err)
|
||||
}
|
||||
if err := rb.DoneReading(); err != nil {
|
||||
|
@ -157,7 +157,7 @@ func TestWritingAndReading2(t *testing.T) {
|
|||
}
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
if _, _, err := rb.Read(); err != nil {
|
||||
if _, err := rb.Read(); err != nil {
|
||||
falseErrorFail(t, err)
|
||||
}
|
||||
if err := rb.DoneReading(); err != nil {
|
||||
|
@ -178,7 +178,7 @@ func TestWritingAndReading3(t *testing.T) {
|
|||
var err1 error
|
||||
var err2 error
|
||||
for i := 0; i < 2; i++ {
|
||||
_, _, err1 = rb.Read()
|
||||
_, err1 = rb.Read()
|
||||
err2 = rb.DoneReading()
|
||||
}
|
||||
if err1 == nil {
|
||||
|
@ -200,7 +200,7 @@ func TestWritingAndReading4(t *testing.T) {
|
|||
falseErrorFail(t, err)
|
||||
}
|
||||
}
|
||||
if _, _, err := rb.Read(); err != nil {
|
||||
if _, err := rb.Read(); err != nil {
|
||||
falseErrorFail(t, err)
|
||||
}
|
||||
if err := rb.DoneReading(); err != nil {
|
||||
|
@ -242,7 +242,7 @@ func TestWritingAndReading6(t *testing.T) {
|
|||
falseErrorFail(t, err2)
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
_, _, err1 = rb.Read()
|
||||
_, err1 = rb.Read()
|
||||
err2 = rb.DoneReading()
|
||||
}
|
||||
if err1 != nil {
|
||||
|
@ -278,7 +278,7 @@ func TestWritingAndReading7(t *testing.T) {
|
|||
falseErrorFail(t, err2)
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
_, _, err1 = rb.Read()
|
||||
_, err1 = rb.Read()
|
||||
err2 = rb.DoneReading()
|
||||
}
|
||||
if err1 != nil {
|
||||
|
@ -315,7 +315,7 @@ func TestWritingAndReading8(t *testing.T) {
|
|||
falseErrorFail(t, err2)
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
_, _, err1 = rb.Read()
|
||||
_, err1 = rb.Read()
|
||||
}
|
||||
if err1 == nil {
|
||||
noErrorFail(t)
|
||||
|
@ -329,7 +329,7 @@ func TestConcurrency1(t *testing.T) {
|
|||
rb = NewRingBuffer(1000, 10)
|
||||
go func() {
|
||||
for i := 0; i < 100; i++ {
|
||||
if data, _, err1 := rb.Read(); data != nil {
|
||||
if data, err1 := rb.Read(); data != nil {
|
||||
err2 := rb.DoneReading()
|
||||
if err1 != nil {
|
||||
falseErrorFail(t, err1)
|
||||
|
|
Loading…
Reference in New Issue