NAME

Data::RingBuffer::Shared - Shared-memory fixed-size ring buffer for Linux

SYNOPSIS

use Data::RingBuffer::Shared;

my $ring = Data::RingBuffer::Shared::Int->new(undef, 100);
$ring->write(42);
$ring->write(99);
say $ring->latest;        # 99 (most recent)
say $ring->latest(1);     # 42 (previous)
say $ring->size;          # 2

# overwrites oldest when full — never blocks
$ring->write($_) for 1..200;
say $ring->size;          # 100 (capacity)
say $ring->latest;        # 200

# read by sequence number
my $seq = $ring->write(777);
say $ring->read_seq($seq);  # 777

# wait for new data
my $cnt = $ring->count;
$ring->wait_for($cnt, 5.0);

# F64 variant
my $f = Data::RingBuffer::Shared::F64->new(undef, 1000);
$f->write(3.14);

# dump entire ring as list (oldest first)
my @vals = $ring->to_list;

DESCRIPTION

Fixed-size circular buffer in shared memory. Writes overwrite the oldest entry when the buffer is full — writes never block or fail. Readers access data by relative position (0=latest) or absolute sequence number.

Unlike Data::Queue::Shared (consumed on read, blocks when full) and Data::PubSub::Shared (subscription tracking), RingBuffer is a simple overwriting window with no consumer state.

Useful for metrics rings, sensor data, rolling windows, debug traces.

Linux-only. Requires 64-bit Perl.

Variants

Data::RingBuffer::Shared::Int - int64_t values
Data::RingBuffer::Shared::F64 - double values

METHODS

Constructors

$r = Data::RingBuffer::Shared::Int->new($path, $capacity);
$r = Data::RingBuffer::Shared::Int->new(undef, $capacity);
$r = Data::RingBuffer::Shared::Int->new_memfd($name, $cap);
$r = Data::RingBuffer::Shared::Int->new_from_fd($fd);

Write

my $seq = $ring->write($value);  # returns sequence number

Always succeeds. Overwrites oldest when full.

Read

my $val = $ring->latest;       # most recent (undef if empty)
my $val = $ring->latest($n);   # nth most recent (0=latest)
my $val = $ring->read_seq($s); # by sequence (undef if overwritten)

my @all = $ring->to_list;      # entire ring, oldest first

Status

$ring->size;       # entries in buffer (max = capacity)
$ring->capacity;
$ring->head;       # next write position (monotonic)
$ring->count;      # total writes (for wait_for)

Waiting

my $ok = $ring->wait_for($expected_count);          # block until count changes
my $ok = $ring->wait_for($expected_count, $timeout);

Returns 1 if new data arrived (count != expected), 0 on timeout.

Lifecycle

$ring->clear;      # reset head/count (NOT concurrency-safe)
$ring->sync;  $ring->unlink;  $ring->path;  $ring->memfd;
$ring->stats;

eventfd

$ring->eventfd;  $ring->eventfd_set($fd);  $ring->fileno;
$ring->notify;   $ring->eventfd_consume;

BENCHMARKS

Single-process (1M ops, x86_64 Linux, Perl 5.40, cap=1000):

Int write       11.7M/s
Int latest      11.1M/s
Int read_seq    10.4M/s
F64 write        8.8M/s
F64 latest      12.0M/s

STATS

stats() returns a hashref: size, capacity, head, count, writes, overwrites, mmap_size.

SECURITY

The mmap region is writable by all processes that open it. Do not share backing files with untrusted processes.

SEE ALSO

Data::Queue::Shared - FIFO queue (consumed on read)

Data::PubSub::Shared - publish-subscribe ring (subscription tracking)

Data::Buffer::Shared - typed shared array

Data::BitSet::Shared - shared bitset

Data::Pool::Shared - fixed-size object pool

Data::Stack::Shared - LIFO stack

Data::Deque::Shared - double-ended queue

Data::Log::Shared - append-only log

Data::Heap::Shared - priority queue

Data::Graph::Shared - directed weighted graph

Data::Sync::Shared - synchronization primitives

Data::HashMap::Shared - concurrent hash table

Data::ReqRep::Shared - request-reply

AUTHOR

vividsnow

LICENSE

Same terms as Perl itself.