NAME
Data::SortedSet::Shared::Strings - string-keyed shared-memory sorted set (ZSET)
SYNOPSIS
use Data::SortedSet::Shared::Strings;
# anonymous (fork-shared); or pass set => $path, keys => $path for file-backed
my $z = Data::SortedSet::Shared::Strings->new(max => 1_000_000);
$z->add("alice", 1500);
$z->incr("alice", 50); # 1550
my @top = $z->rev_range_by_rank(0, 9); # ("alice", "bob", ...)
my $score = $z->score("alice");
my ($who, $sc) = $z->pop_min; # remove + return the lowest
DESCRIPTION
A string-keyed sorted set in shared memory: the same API as Data::SortedSet::Shared but with string members instead of int64 ids. It is a thin layer composing two shared structures -- a Data::SortedSet::Shared for the (id, score) ordering and a Data::Intern::Shared mapping each string key to a dense id. Keys are interned on the way in and decoded back to strings on the way out.
Because both backing stores live in shared memory, the set works across processes: every process resolves a key to the same id, so a string-keyed leaderboard, priority queue, or rate limiter can be shared by many workers.
Ties among equal scores break by interning id (roughly insertion order of first-seen keys), not lexicographically. Keys are interned by byte content and stay interned until clear (see "LIMITS" in Data::Intern::Shared). Linux-only, 64-bit Perl.
METHODS
Construction
my $z = Data::SortedSet::Shared::Strings->new(
max => $max_members, # required
set => $path_or_undef, # SortedSet backing (undef = anonymous)
keys => $path_or_undef, # Intern backing (undef = anonymous)
max_keys => $max_members, # distinct-key capacity (default: max)
arena => $bytes, # key-arena bytes (default: max_keys * 32)
);
my $z = Data::SortedSet::Shared::Strings->wrap($set, $intern);
new creates (or reopens) both backing stores; for cross-process file-backed use, every process passes the same set/keys paths. wrap wraps two already-constructed objects (e.g. memfd-backed ones shared by fd). set and key_table return the underlying Data::SortedSet::Shared and Data::Intern::Shared objects.
API
Every method takes/returns string members; otherwise the semantics are exactly those of Data::SortedSet::Shared:
$z->add($str, $score); # 1 new / 0 updated / undef if a pool is full
$z->incr($str, $delta); # add to the score (creates the key if absent); returns the new score
$z->remove($str); # true if removed, false if absent
$z->add_many([ [$s1,$sc1], ... ]);
$z->clear;
$z->score($str); $z->rank($str); $z->rev_rank($str); $z->exists($str);
$z->count; $z->count_in_score($min, $max);
$z->at_rank($r);
$z->range_by_rank($start, $stop, %opts); # ($str, ...) or ($str,$score,...) with withscores
$z->rev_range_by_rank($start, $stop, %opts);
$z->range_by_score($min, $max, %opts); # limit / offset / withscores
$z->rev_range_by_score($max, $min, %opts);
my ($str, $score) = $z->pop_min; # pop_max / peek_min / peek_max
$z->each(sub { my ($str, $score) = @_; ... });
$z->sync; $z->unlink; $z->stats; # stats: { set => {...}, keys => {...} }
remove leaves the key interned (ids are stable); the key universe (max_keys) must therefore accommodate every distinct key ever added, not just those currently present. clear is the one exception -- it resets both the set and the key table, so ids minted before a clear no longer resolve. add returns undef (and incr croaks) if the key table or the member pool is full. add_many interns each row's key in order, stopping only if the key table fills, then bulk-adds; it returns the number of members newly inserted (fewer than the rows given if either pool fills -- keys interned past the member pool's capacity stay interned but unadded). Malformed rows and NaN-scored rows are skipped without interning their key.
SEE ALSO
Data::SortedSet::Shared, Data::Intern::Shared.
AUTHOR
vividsnow
LICENSE
This is free software; you can redistribute it and/or modify it under the same terms as Perl itself.