• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

smallnest / chanx / 6137542235

10 Sep 2023 01:46PM UTC coverage: 90.345% (+0.2%) from 90.179%
6137542235

push

github

smallnest
use github action insead of travis

131 of 145 relevant lines covered (90.34%)

0.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.03
/ringbuffer.go
1
package chanx
2

3
import (
4
        "errors"
5
)
6

7
var ErrIsEmpty = errors.New("ringbuffer is empty")
8

9
// RingBuffer is a ring buffer for common types.
10
// It never is full and always grows if it will be full.
11
// It is not thread-safe(goroutine-safe) so you must use the lock-like synchronization primitive to use it in multiple writers and multiple readers.
12
type RingBuffer[T any] struct {
13
        buf         []T
14
        initialSize int
15
        size        int
16
        r           int // read pointer
17
        w           int // write pointer
18
}
19

20
func NewRingBuffer[T any](initialSize int) *RingBuffer[T] {
1✔
21
        if initialSize <= 0 {
1✔
22
                panic("initial size must be great than zero")
×
23
        }
24
        // initial size must >= 2
25
        if initialSize == 1 {
2✔
26
                initialSize = 2
1✔
27
        }
1✔
28

29
        return &RingBuffer[T]{
1✔
30
                buf:         make([]T, initialSize),
1✔
31
                initialSize: initialSize,
1✔
32
                size:        initialSize,
1✔
33
        }
1✔
34
}
35

36
func (r *RingBuffer[T]) Read() (T, error) {
1✔
37
        var t T
1✔
38
        if r.r == r.w {
2✔
39
                return t, ErrIsEmpty
1✔
40
        }
1✔
41

42
        v := r.buf[r.r]
1✔
43
        r.r++
1✔
44
        if r.r == r.size {
1✔
45
                r.r = 0
×
46
        }
×
47

48
        return v, nil
1✔
49
}
50

51
func (r *RingBuffer[T]) Pop() T {
1✔
52
        v, err := r.Read()
1✔
53
        if err == ErrIsEmpty { // Empty
1✔
54
                panic(ErrIsEmpty.Error())
×
55
        }
56

57
        return v
1✔
58
}
59

60
func (r *RingBuffer[T]) Peek() T {
1✔
61
        if r.r == r.w { // Empty
1✔
62
                panic(ErrIsEmpty.Error())
×
63
        }
64

65
        v := r.buf[r.r]
1✔
66
        return v
1✔
67
}
68

69
func (r *RingBuffer[T]) Write(v T) {
1✔
70
        r.buf[r.w] = v
1✔
71
        r.w++
1✔
72

1✔
73
        if r.w == r.size {
2✔
74
                r.w = 0
1✔
75
        }
1✔
76

77
        if r.w == r.r { // full
2✔
78
                r.grow()
1✔
79
        }
1✔
80
}
81

82
func (r *RingBuffer[T]) grow() {
1✔
83
        var size int
1✔
84
        if r.size < 1024 {
2✔
85
                size = r.size * 2
1✔
86
        } else {
1✔
87
                size = r.size + r.size/4
×
88
        }
×
89

90
        buf := make([]T, size)
1✔
91

1✔
92
        copy(buf[0:], r.buf[r.r:])
1✔
93
        copy(buf[r.size-r.r:], r.buf[0:r.r])
1✔
94

1✔
95
        r.r = 0
1✔
96
        r.w = r.size
1✔
97
        r.size = size
1✔
98
        r.buf = buf
1✔
99
}
100

101
func (r *RingBuffer[T]) IsEmpty() bool {
1✔
102
        return r.r == r.w
1✔
103
}
1✔
104

105
// Capacity returns the size of the underlying buffer.
106
func (r *RingBuffer[T]) Capacity() int {
1✔
107
        return r.size
1✔
108
}
1✔
109

110
func (r *RingBuffer[T]) Len() int {
1✔
111
        if r.r == r.w {
2✔
112
                return 0
1✔
113
        }
1✔
114

115
        if r.w > r.r {
2✔
116
                return r.w - r.r
1✔
117
        }
1✔
118

119
        return r.size - r.r + r.w
1✔
120
}
121

122
func (r *RingBuffer[T]) Reset() {
1✔
123
        r.r = 0
1✔
124
        r.w = 0
1✔
125
        r.size = r.initialSize
1✔
126
        r.buf = make([]T, r.initialSize)
1✔
127
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc