mem

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 22, 2026 License: Apache-2.0 Imports: 2 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CircularByteArena

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

CircularByteArena is a bounded circular buffer for storing variable-sized event payloads. Multiple producers claim contiguous ranges via TryReserve (lock-free CAS); ranges are returned to the arena via Release.

Visibility / overwrite contract:

  • TryReserve NEVER hands out a range that overlaps a claimed-but-not-yet released range. A producer that cannot make this guarantee receives ok=false and must retry (or drop). Overwriting unread data is therefore impossible by construction — there is no "best effort" mode.
  • A payload written into GetSlice(res.Offset, size) is immutable from the producer's perspective once published, and remains valid for readers until Release(res) is called. Readers must not retain slices past the release point.

Thread safety:

  • TryReserve and GetSlice may be called from multiple goroutines.
  • ReadSlice may be called by any goroutine that holds an unreleased Reservation covering the range.
  • Release may be called from multiple goroutines (consumer release on the dispatch thread, producer release on the drop path).

func NewCircularByteArena

func NewCircularByteArena(capacity uint64) *CircularByteArena

NewCircularByteArena creates a new CircularByteArena with the specified capacity. The capacity is rounded up to a multiple of 8 so that all reservation offsets stay 8-byte aligned across wraps.

func (*CircularByteArena) Capacity

func (a *CircularByteArena) Capacity() uint64

Capacity returns the buffer capacity.

func (*CircularByteArena) Claimed

func (a *CircularByteArena) Claimed() uint64

Claimed returns the monotonic claimed cursor.

func (*CircularByteArena) GetSlice

func (a *CircularByteArena) GetSlice(offset, size uint64) []byte

GetSlice returns a writable slice at the given physical offset for the producer that owns the covering Reservation.

func (*CircularByteArena) ReadSlice

func (a *CircularByteArena) ReadSlice(offset uint64, size uint64) []byte

ReadSlice returns a read-only view of the buffer at the given physical offset. The view is valid only while the covering Reservation is unreleased.

func (*CircularByteArena) Release

func (a *CircularByteArena) Release(r Reservation)

Release returns a claimed range to the arena. Releases may arrive out of reservation order (producers reserve and publish independently); ranges ahead of the frontier are parked until the gap closes.

func (*CircularByteArena) Released

func (a *CircularByteArena) Released() uint64

Released returns the monotonic released frontier.

func (*CircularByteArena) Reset

func (a *CircularByteArena) Reset()

Reset resets the arena to its initial state. WARNING: This is NOT thread-safe and should only be called when no operations are in progress.

func (*CircularByteArena) TryReserve

func (a *CircularByteArena) TryReserve(size uint64) (Reservation, bool)

TryReserve attempts to atomically claim size bytes (rounded up to 8-byte alignment). The payload never straddles the physical end of the buffer: if it would, the tail is claimed as padding and the payload starts at offset 0.

Returns ok=false when the arena does not currently have room, i.e. the consumer has not yet released enough space. The caller decides the wait / drop policy. size must be <= Capacity().

type MPSCRingBuffer

type MPSCRingBuffer[T any] struct {
	// contains filtered or unexported fields
}

MPSCRingBuffer is a lock-free Multiple Producer Single Consumer ring buffer. It uses atomic CAS operations for concurrent producers and a two-phase commit protocol.

Performance characteristics:

  • ~30-50ns per operation under contention
  • ~15-25ns per operation without contention
  • Cache-line padding prevents false sharing

Two-phase commit protocol:

  1. Producer claims a slot by CAS on write pointer
  2. Producer writes data to the slot
  3. Producer commits by advancing the committed pointer (in order)

Thread safety:

  • Multiple goroutines can safely call Write (multiple producers)
  • Exactly ONE goroutine should call Read (single consumer)
  • IsEmpty, IsFull, Count, Capacity are safe to call from any goroutine

func NewMPSCRingBuffer

func NewMPSCRingBuffer[T any](size uint64) *MPSCRingBuffer[T]

NewMPSCRingBuffer creates a new MPSC ring buffer with the specified size. Size will be rounded up to the next power of 2 for efficient masking.

func (*MPSCRingBuffer[T]) Capacity

func (rb *MPSCRingBuffer[T]) Capacity() uint64

Capacity returns the capacity of the ring buffer.

func (*MPSCRingBuffer[T]) Count

func (rb *MPSCRingBuffer[T]) Count() uint64

Count returns the number of committed items currently available to read.

func (*MPSCRingBuffer[T]) IsEmpty

func (rb *MPSCRingBuffer[T]) IsEmpty() bool

IsEmpty returns true if the ring buffer has no committed items to read.

func (*MPSCRingBuffer[T]) IsFull

func (rb *MPSCRingBuffer[T]) IsFull() bool

IsFull returns true if the ring buffer is full.

func (*MPSCRingBuffer[T]) PendingCount

func (rb *MPSCRingBuffer[T]) PendingCount() uint64

PendingCount returns the number of items claimed but not yet committed. This can be useful for debugging or monitoring.

func (*MPSCRingBuffer[T]) Read

func (rb *MPSCRingBuffer[T]) Read() (T, bool)

Read reads an item from the ring buffer. Returns the item and true if successful, or zero value and false if empty. Only one goroutine should call Read (single consumer).

func (*MPSCRingBuffer[T]) Reset

func (rb *MPSCRingBuffer[T]) Reset()

Reset clears the ring buffer by resetting all pointers. WARNING: This is NOT thread-safe and should only be called when no operations are in progress.

func (*MPSCRingBuffer[T]) Write

func (rb *MPSCRingBuffer[T]) Write(item T) bool

Write writes an item to the ring buffer. Returns true if successful, false if the buffer is full. Multiple goroutines can safely call Write concurrently.

type Reservation

type Reservation struct {
	Start  uint64 // monotonic start of the claimed range (includes boundary padding)
	End    uint64 // monotonic end of the claimed range
	Offset uint64 // physical offset of the payload within the buffer
}

Reservation identifies a claimed byte range in a CircularByteArena. Start/End are monotonic (never-wrapping) positions; Offset is the physical position of the payload inside the buffer. A Reservation must eventually be passed to Release exactly once, otherwise the arena stalls.

type SPSCRingBuffer

type SPSCRingBuffer[T any] struct {
	// contains filtered or unexported fields
}

SPSCRingBuffer is a lock-free Single Producer Single Consumer ring buffer. It uses atomic operations for proper memory ordering between producer and consumer threads.

Performance characteristics:

  • ~10-20ns per operation with no contention
  • Cache-line padding prevents false sharing
  • Uses monotonically increasing counters (no wrap-around issues)

Thread safety:

  • Exactly ONE goroutine should call Write (producer)
  • Exactly ONE goroutine should call Read (consumer)
  • IsEmpty, IsFull, Count, Capacity are safe to call from any goroutine

func NewSPSCRingBuffer

func NewSPSCRingBuffer[T any](size uint64) *SPSCRingBuffer[T]

NewSPSCRingBuffer creates a new SPSC ring buffer with the specified size. Size will be rounded up to the next power of 2 for efficient masking.

func (*SPSCRingBuffer[T]) Capacity

func (rb *SPSCRingBuffer[T]) Capacity() uint64

Capacity returns the capacity of the ring buffer.

func (*SPSCRingBuffer[T]) Count

func (rb *SPSCRingBuffer[T]) Count() uint64

Count returns the number of items currently in the ring buffer.

func (*SPSCRingBuffer[T]) IsEmpty

func (rb *SPSCRingBuffer[T]) IsEmpty() bool

IsEmpty returns true if the ring buffer is empty.

func (*SPSCRingBuffer[T]) IsFull

func (rb *SPSCRingBuffer[T]) IsFull() bool

IsFull returns true if the ring buffer is full.

func (*SPSCRingBuffer[T]) Peek

func (rb *SPSCRingBuffer[T]) Peek() (T, bool)

Peek returns the oldest item without removing it from the buffer. Returns the item and true if successful, or zero value and false if empty. Only one goroutine should call Peek (single consumer).

func (*SPSCRingBuffer[T]) Read

func (rb *SPSCRingBuffer[T]) Read() (T, bool)

Read reads an item from the ring buffer. Returns the item and true if successful, or zero value and false if empty. Only one goroutine should call Read (single consumer).

func (*SPSCRingBuffer[T]) Reset

func (rb *SPSCRingBuffer[T]) Reset()

Reset clears the ring buffer by resetting read and write pointers. WARNING: This is NOT thread-safe and should only be called when no operations are in progress.

func (*SPSCRingBuffer[T]) Write

func (rb *SPSCRingBuffer[T]) Write(item T) bool

Write writes an item to the ring buffer. Returns true if successful, false if the buffer is full. Only one goroutine should call Write (single producer).

type SimpleByteArena

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

SimpleByteArena is a bounded, non-atomic circular byte arena for single-threaded use (the dispatch goroutine produces and consumes commands on the same thread). It provides the same reservation/release contract as CircularByteArena but without CAS operations.

Visibility / overwrite contract: TryReserve never hands out a range that overlaps an unreleased range, so unconsumed data can never be overwritten. Because producer and consumer share one goroutine, a full arena cannot be waited out — callers must treat ok=false as a fatal configuration error.

Thread safety: NOT thread-safe. Must be accessed from a single goroutine.

func NewSimpleByteArena

func NewSimpleByteArena(capacity uint64) *SimpleByteArena

NewSimpleByteArena creates a new SimpleByteArena with the specified capacity, rounded up to a multiple of 8 for aligned offsets.

func (*SimpleByteArena) Capacity

func (a *SimpleByteArena) Capacity() uint64

Capacity returns the buffer capacity.

func (*SimpleByteArena) Claimed

func (a *SimpleByteArena) Claimed() uint64

Claimed returns the monotonic claimed cursor.

func (*SimpleByteArena) GetSlice

func (a *SimpleByteArena) GetSlice(offset, size uint64) []byte

GetSlice returns a writable slice at the given physical offset for the owner of the covering Reservation.

func (*SimpleByteArena) ReadSlice

func (a *SimpleByteArena) ReadSlice(offset, size uint64) []byte

ReadSlice returns a read-only view of the buffer at the given physical offset. The view is valid only while the covering Reservation is unreleased.

func (*SimpleByteArena) Release

func (a *SimpleByteArena) Release(r Reservation)

Release returns a claimed range to the arena. Commands are normally released in reservation order, but out-of-order releases are tolerated.

func (*SimpleByteArena) Released

func (a *SimpleByteArena) Released() uint64

Released returns the monotonic released frontier.

func (*SimpleByteArena) Reset

func (a *SimpleByteArena) Reset()

Reset resets the arena to its initial state.

func (*SimpleByteArena) TryReserve

func (a *SimpleByteArena) TryReserve(size uint64) (Reservation, bool)

TryReserve attempts to claim size bytes (rounded up to 8-byte alignment). The payload never straddles the physical end of the buffer. Returns ok=false when there is not enough unreleased space; size must be <= Capacity().

type SliceArena

type SliceArena[T any] struct {
	// contains filtered or unexported fields
}

SliceArena is a circular arena for allocating contiguous slices of type T. It provides zero-allocation storage that can be reused by wrapping around.

This is NOT a FIFO queue - it allocates contiguous slices that wrap around when there's not enough space at the end.

Use case: Pre-allocate a pool of objects and get slices from it without heap allocations. The returned slices are valid until the arena wraps around.

Note: This is single-threaded (not thread-safe).

func NewSliceArena

func NewSliceArena[T any](capacity int) *SliceArena[T]

NewSliceArena creates a new SliceArena with the given capacity.

func (*SliceArena[T]) Allocate

func (a *SliceArena[T]) Allocate(n int) []T

Allocate reserves n consecutive slots and returns a slice to them. The returned slice is valid until the arena wraps around. If n > capacity, the arena wraps to the beginning.

func (*SliceArena[T]) Capacity

func (a *SliceArena[T]) Capacity() int

Capacity returns the arena capacity

func (*SliceArena[T]) Reset

func (a *SliceArena[T]) Reset()

Reset resets the arena to initial state

Jump to

Keyboard shortcuts

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