ringbuffer

package module
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2025 License: MIT Imports: 5 Imported by: 0

README

mmap_ringbuffer

A high-performance, memory-mapped ring buffer implementation in Go, designed for efficient inter-process or inter-thread communication. This library provides a lock-free (with minimal locking) ring buffer backed by memory-mapped files, making it suitable for high-throughput scenarios.

Features

  • Memory-mapped file as a shared ring buffer
  • Minimal locking for write operations
  • Efficient for high message throughput

Installation

go get github.com/EBWi11/mmap_ringbuffer

Usage

Basic Example
package main

import (
    "fmt"
    "github.com/EBWi11/mmap_ringbuffer"
)

func main() {
    // Create a new ring buffer with 1MB size
    rb, err := ringbuffer.NewRingBuffer("/tmp/rb.mmap", 1024*1024, true)
    if err != nil {
        panic(err)
    }
    defer rb.Close()

    // Write a message
    msg := []byte("hello, mmap ringbuffer!")
    ok, err := rb.WriteMsg(msg)
    if ok && err == nil {
        fmt.Println("Message written successfully")
    }

    // Read a message
    readMsg, err := rb.ReadMsg()
    if err == nil {
        fmt.Printf("Read message: %s\n", string(readMsg))
    }
}
Producer-Consumer Example
package main

import (
    "fmt"
    "sync"
    "github.com/EBWi11/mmap_ringbuffer"
)

func producer(rb *ringbuffer.RingBuffer, wg *sync.WaitGroup) {
    defer wg.Done()
    
    for i := 0; i < 1000; i++ {
        msg := []byte(fmt.Sprintf("message-%d", i))
        ok, err := rb.WriteMsg(msg)
        if !ok || err != nil {
            fmt.Printf("Failed to write: %v\n", err)
            return
        }
    }
}

func consumer(rb *ringbuffer.RingBuffer, wg *sync.WaitGroup) {
    defer wg.Done()
    
    for {
        msg, err := rb.ReadMsg()
        if err == ringbuffer.ErrBufferEmpty {
            continue
        }
        if err != nil {
            fmt.Printf("Failed to read: %v\n", err)
            return
        }
        fmt.Printf("Received: %s\n", string(msg))
    }
}

func main() {
    rb, err := ringbuffer.NewRingBuffer("/tmp/rb.mmap", 1024*1024, true)
    if err != nil {
        panic(err)
    }
    defer rb.Close()

    var wg sync.WaitGroup
    wg.Add(2)

    go producer(rb, &wg)
    go consumer(rb, &wg)

    wg.Wait()
}

API Reference

NewRingBuffer
func NewRingBuffer(filename string, size int, remove bool) (*RingBuffer, error)

Creates a new ring buffer backed by a memory-mapped file.

  • filename: Path to the memory-mapped file
  • size: Size of the buffer in bytes
  • remove: If true, removes any existing file before creating
OpenRingBuffer
func OpenRingBuffer(filename string) (*RingBuffer, error)

Opens an existing ring buffer file.

WriteMsg
func (r *RingBuffer) WriteMsg(msg []byte) (bool, error)

Writes a message to the buffer. Returns true and nil if successful.

  • Returns ErrBufferFull if the buffer is full
  • Returns ErrInvalidSize if the message is empty or too large
  • Returns ErrClosed if the buffer is closed
ReadMsg
func (r *RingBuffer) ReadMsg() ([]byte, error)

Reads a message from the buffer. Returns the message and nil if successful.

  • Returns ErrBufferEmpty if the buffer is empty
  • Returns ErrClosed if the buffer is closed
Close
func (r *RingBuffer) Close() error

Closes the ring buffer and releases the memory-mapped file.

Error Types

  • ErrBufferFull: Returned when trying to write to a full buffer
  • ErrInvalidSize: Returned when trying to write an empty or too large message
  • ErrBufferEmpty: Returned when trying to read from an empty buffer
  • ErrClosed: Returned when trying to use a closed buffer

Performance Considerations

  • The buffer size should be chosen carefully based on your use case
  • For high-throughput scenarios, consider using a larger buffer size
  • The buffer uses a header of 8 bytes (4 bytes for head, 4 bytes for tail)
  • Maximum message size is limited to half of the buffer size

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrBufferFull  = errors.New("ring buffer is full")
	ErrInvalidSize = errors.New("invalid message size")
	ErrBufferEmpty = errors.New("ring buffer is empty")
	ErrClosed      = errors.New("ring buffer is closed")
)

Functions

This section is empty.

Types

type RingBuffer

type RingBuffer struct {
	// contains filtered or unexported fields
}

RingBuffer implements a memory-mapped ring buffer. Memory layout: [magic(4)][head(4)][tail(4)][data...]

func NewRingBuffer

func NewRingBuffer(mmapFileName string, size int, remove bool) (*RingBuffer, error)

NewRingBuffer creates a new mmap-backed ring buffer file

func OpenRingBuffer

func OpenRingBuffer(mmapFileName string) (*RingBuffer, error)

func (*RingBuffer) Close

func (r *RingBuffer) Close() error

Close releases mmap

func (*RingBuffer) GetHeadTail

func (r *RingBuffer) GetHeadTail() (uint32, uint32)

func (*RingBuffer) ReadMsg

func (r *RingBuffer) ReadMsg() ([]byte, error)

ReadMsg reads a message from the ring buffer Returns (msg, nil) if successful, (nil, error) if failed

func (*RingBuffer) WriteMsg

func (r *RingBuffer) WriteMsg(msg []byte) (bool, error)

WriteMsg writes a message to the ring buffer Returns (true, nil) if successful, (false, error) if failed

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL