https://github.com/hedzr/go-ringbuf
Lock-free MPMC Ring Buffer (Generic) for SMP, in golang. Some posts in chinese:
https://github.com/hedzr/go-ringbuf
circular-buffer circular-queue generic-programming generics go go-generics golang golang-library golang-package lock-free ring-buffer ringbuffer smp
Last synced: 8 days ago
JSON representation
Lock-free MPMC Ring Buffer (Generic) for SMP, in golang. Some posts in chinese:
- Host: GitHub
- URL: https://github.com/hedzr/go-ringbuf
- Owner: hedzr
- License: apache-2.0
- Created: 2020-07-02T06:51:01.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2025-02-07T00:00:09.000Z (12 months ago)
- Last Synced: 2025-03-29T21:04:17.846Z (10 months ago)
- Topics: circular-buffer, circular-queue, generic-programming, generics, go, go-generics, golang, golang-library, golang-package, lock-free, ring-buffer, ringbuffer, smp
- Language: Go
- Homepage: https://hedzr.com/algorithm/golang/ringbuf-index/
- Size: 140 KB
- Stars: 98
- Watchers: 3
- Forks: 7
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# go-ringbuf [V2]

[](https://github.com/hedzr/go-ringbuf/releases)
[](https://pkg.go.dev/github.com/hedzr/go-ringbuf)
[](https://godoc.org/github.com/hedzr/go-ringbuf)
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fhedzr%2Fgo-ringbuf?ref=badge_shield)
[](https://goreportcard.com/report/github.com/hedzr/go-ringbuf)
[](https://coveralls.io/github/hedzr/go-ringbuf?branch=master)
`go-ringbuf` provides a high-performance, lock-free circular queue (ring buffer) implementation in golang.
MPMC (multiple producers and multiple consumers) enabled.
## History
### v2.2.3
- fixed issue [#9](https://github.com/hedzr/go-ringbuf/issues/9) (via pr [#10](https://github.com/hedzr/go-ringbuf/pull/10), thx [@srgg](https://github.com/srgg)) a datarace problem caused by an uncheckd cas load failue
### v2.2.2
- [resp for #7] `NewOverlappedRingBuffer` returns `RichOverlappedRingBuffer[T]` now, which gives some new alternatives apis of `Enqueue` so that you can collect `overwrites` and `size` from the returning data.
> The legacy codes keep its stable with the original `Enqueue`.
> For a normal ringbuf, non-overlapped, nothing's changed since the current capacity (size) is not a very important value for measuring.
> If not, issue me.
### v2.2.1
- security updates
### v2.2.0
- added new impl to support overlapped ringbuf
- security updates
### v2.1.0
- remove extras deps
- replaced 'hedzr/log' with 'log/slog', 'hedzr/errors.v3' with 'errors'
- remove WithLogger()
### v2.0.+
security updates
### v2.0.0 @20220408 - go 1.18+
generic version for MPMC Ring Buffer.
- rewritten with go generics
### v1.0.+ [archived]
security updates
### v1.0.0 @20220408
Last release for classical version.
Next release (v2) will move to go 1.18+ with generic enabled.
### v0.9.1 @2022
- review all codes
- updated deps
- review and solve uncertain misreport failed licenses
- ~~we have two deps: [hedzr/errors](https://github.com/hedzr/errors) and [hedzr/log](https://github.com/hedzr/log), and both them have no 3rd-party deps.~~
- since 2.1.0, any deps removed.
- we have no more 3rd-party deps.
- we assumed a free license under MIT (unified).
## Getting Start
```bash
go get -v github.com/hedzr/go-ringbuf/v2
```
### Samples
```go
package main
import (
"fmt"
"log"
"github.com/hedzr/go-ringbuf/v2"
)
func main() {
testIntRB()
testStringRB()
}
func testStringRB() {
var err error
var rb = ringbuf.New[string](80)
err = rb.Enqueue("abcde")
errChk(err)
var item string
item, err = rb.Dequeue()
errChk(err)
fmt.Printf("dequeue ok: %v\n", item)
}
func testIntRB() {
var err error
var rb = ringbuf.New[int](80)
err = rb.Enqueue(3)
errChk(err)
var item int
item, err = rb.Dequeue()
errChk(err)
fmt.Printf("dequeue ok: %v\n", item)
}
func errChk(err error) {
if err != nil {
log.Fatal(err)
}
}
```
### Using Ring-Buffer as a fixed resource pool
The following codes is for v1, needed for rewriting
```go
func newRes() *Res{...}
var rb mpmc.RingBuffer
func initFunc() (err error) {
const maxSize = 16
if rb = mpmc.New(uint32(maxSize)); rb == nil {
err = errors.New("cannot create mpmc.RingBuffer")
return
}
// CapReal() will be available since v0.8.8, or replace it with Cap() - 1
for i := uint32(0); i < rb.CapReal(); i++ {
if err = rb.Enqueue(newRes()); err != nil {
return
}
}
}
func loopFor() {
var err error
for {
it, err := rb.Dequeue()
checkErr(err)
if res, ok := it.(*Res); ok {
// do stuff with `res`, and put it back into ring-buffer
err = rb.Enqueue(it)
}
}
}
```
### Using Overlapped Ring Buffer
Since v2.2.0, `NewOverlappedRingBuffer()` can initiate a different ring buffer, which
allows us to overwrite the head element if putting new element into a **full** ring buffer.
```go
func testStringRB() {
var err error
var rb = ringbuf.NewOverlappedRingBuffer[string](80)
err = rb.Enqueue("abcde")
errChk(err)
var item string
item, err = rb.Dequeue()
errChk(err)
fmt.Printf("dequeue ok: %v\n", item)
}
```
## Contrib
Welcome
## LICENSE
Apache 2.0