package queue
import (
"errors"
)
var errInvalidSize = errors.New("buffer size must be > 0")
type CircularBuffer struct {
total int
items []interface{}
}
func NewCircularBuffer(size int) (*CircularBuffer, error) {
if size <= 0 {
return nil, errInvalidSize
}
return &CircularBuffer{
total: 0,
items: make([]interface{}, size),
}, nil
}
func (c *CircularBuffer) index() int {
return c.total % len(c.items)
}
func (c *CircularBuffer) Add(item interface{}) {
c.items[c.index()] = item
c.total++
}
func (c *CircularBuffer) List() []interface{} {
size := cap(c.items)
index := c.index()
switch {
case c.total == 0:
return nil
case c.total < size:
resp := make([]interface{}, c.total)
copy(resp, c.items[:c.index()])
return resp
}
resp := make([]interface{}, size)
firstHalf := c.items[index:]
copy(resp, firstHalf)
secondHalf := c.items[:index]
copy(resp[len(firstHalf):], secondHalf)
return resp
}
func (c *CircularBuffer) Total() int {
return c.total
}
func (c *CircularBuffer) Latest() interface{} {
if c.total == 0 {
return nil
}
latest := (c.total - 1) % len(c.items)
return c.items[latest]
}