summaryrefslogtreecommitdiff
path: root/go/circular-buffer/circular_buffer.go
blob: 7d15aa1a27c0036cba7a022583b5220feaa64841 (plain)
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
51
52
53
54
package circular

import "errors"

const testVersion = 3

// Buffer is circular buffer
type Buffer struct {
	v    []byte // values
	rpos int    // read position
	wpos int    // write position
	n    int    // occupied cells
}

// NewBuffer allocates new buffer
func NewBuffer(size int) *Buffer {
	return &Buffer{v: make([]byte, size)}
}

// ReadByte reads byte from buffer
func (b *Buffer) ReadByte() (byte, error) {
	if b.n == 0 {
		return 0, errors.New("empty")
	}
	val := b.v[b.rpos]
	b.rpos = (b.rpos + 1) % len(b.v)
	b.n--
	return val, nil
}

// WriteByte appends byte to buffer
func (b *Buffer) WriteByte(c byte) error {
	if b.n == len(b.v) {
		return errors.New("full")
	}
	b.v[b.wpos] = c
	b.wpos = (b.wpos + 1) % len(b.v)
	b.n++
	return nil
}

// Overwrite oldest value
func (b *Buffer) Overwrite(c byte) {
	if err := b.WriteByte(c); err != nil {
		b.v[b.rpos] = c
		b.rpos = (b.rpos + 1) % len(b.v)
	}
}

// Reset buffer
func (b *Buffer) Reset() {
	b.n = 0
	b.rpos = b.wpos
}