Skip to content

Instantly share code, notes, and snippets.

@unanoc
Created January 24, 2021 18:00
Show Gist options
  • Save unanoc/6bfaecf4b5de5eeab6e7fbb26d18274c to your computer and use it in GitHub Desktop.
Save unanoc/6bfaecf4b5de5eeab6e7fbb26d18274c to your computer and use it in GitHub Desktop.
Cycled buffer implementation
package main
import "fmt"
// Object is an interface for cache value elements.
type Object interface{}
// CycledBuffer is a buffer for storing cache objects.
type CycledBuffer struct {
buff []Object
head, tail int
len int
}
// NewCycledBuffer returns an instance of CycledBuffer.
func NewCycledBuffer(size int) CycledBuffer {
return CycledBuffer{
buff: make([]Object, size),
}
}
// Push appends an object to buffer.
func (cb *CycledBuffer) Push(obj Object) {
if cb.buff == nil {
fmt.Println("cycled bueffer is not initialized")
return
}
// when buffer is full and we push extra objects - we need to move tail forward.
if cb.tail == cb.head && cb.len == len(cb.buff) {
if cb.tail == len(cb.buff)-1 {
cb.tail = 0
} else {
cb.tail++
}
}
if cb.head < len(cb.buff) {
cb.buff[cb.head] = obj
if cb.head == len(cb.buff)-1 {
cb.head = 0
} else {
cb.head++
}
if cb.len < len(cb.buff) {
cb.len++
}
}
}
// Pop gets an object buffer and then drop it.
func (cb *CycledBuffer) Pop() Object {
if cb.buff == nil {
fmt.Println("cycled bueffer is not initialized")
return nil
}
if cb.len == 0 {
fmt.Println("cycled bueffer is empty")
return nil
}
resultIndex := cb.tail
if cb.tail == len(cb.buff)-1 {
cb.tail = 0
} else {
cb.tail++
}
cb.len--
return cb.buff[resultIndex]
}
// Len returns a length of buffer.
func (cb CycledBuffer) Len() int {
return len(cb.buff)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment