Skip to main content

Store

Struct Store 

Source
pub struct Store { /* private fields */ }
Expand description

The embedded keyspace.

Store is Clone (since v1.1.0). A clone is a cheap Arc bump: every clone reaches the same underlying shards + AOF + reaper + pub/sub bus. The reaper thread is joined and each shard’s AOF is flushed exactly once, when the last clone is dropped.

use kevy_embedded::{Config, Store};

let s = Store::open(Config::default().with_ttl_reaper_manual())?;
let s2 = s.clone();
std::thread::spawn(move || {
    s2.set(b"from-thread", b"v").unwrap();
}).join().unwrap();
assert_eq!(s.get(b"from-thread")?, Some(b"v".to_vec()));

Every method takes &self. Sharding (see Config::with_shards) lets a multi-threaded consumer scale across cores; pub/sub is process-wide (handled on shard 0).

Implementations§

Source§

impl Store

Source

pub fn info(&self) -> KevyInfo

One-shot snapshot of the store’s introspection counters. See KevyInfo. Takes the embedded mutex once; safe to call from a health endpoint.

Source

pub fn expire_pending_count(&self) -> usize

Number of live keys that currently carry a TTL (the expire-set size, summed across shards).

Source

pub fn ttl(&self, key: &[u8]) -> Option<Duration>

Remaining TTL for key as a Duration, or None when the key is absent or has no TTL (persistent). For the raw Redis PTTL sentinels (-2 no key, -1 no TTL) use Store::ttl_ms.

Source§

impl Store

Source

pub fn set(&self, key: &[u8], value: &[u8]) -> Result<bool>

SET key value (no TTL, no NX/XX). Returns true always under the embedded API (Redis semantics: SET overwrites; NX/XX vetoes would return false but we don’t expose those here — use Store::with for the full surface).

Source

pub fn set_with_ttl( &self, key: &[u8], value: &[u8], ttl: Duration, ) -> Result<bool>

SET key value PX ms — overwrites + sets TTL. The AOF records an absolute PEXPIREAT deadline (not the relative ttl) so the key expires at the same wall-clock instant after a restart — a relative PEXPIRE would be re-anchored to replay-time, resetting the TTL to a fresh full duration on every restart (INC-2026-06-09).

Source

pub fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>>

GET keySome(bytes) on hit, None on miss or expired.

With eviction off (maxmemory == 0, the default) this takes the read lock and a non-mutating store lookup, so concurrent readers scale across cores — the path a read-heavy embed cache lives on. With eviction on it falls back to the exclusive lock + mutating get so each access still stamps the LRU clock.

Source

pub fn del(&self, keys: &[&[u8]]) -> Result<usize>

DEL key1 [key2 ...]. Returns the count of keys actually removed. Keys fan out to their owning shards.

Source

pub fn exists(&self, keys: &[&[u8]]) -> Result<usize>

EXISTS key1 [key2 ...]. Count of existing keys (duplicates counted multiple times, matching Redis).

Source

pub fn incr(&self, key: &[u8]) -> Result<i64>

INCR key. Returns the post-increment value.

Source

pub fn incr_by(&self, key: &[u8], delta: i64) -> Result<i64>

INCRBY key delta. Negative delta does DECR-style work.

Source

pub fn expire(&self, key: &[u8], ttl: Duration) -> Result<bool>

EXPIRE key seconds. Returns true if a key was touched. The AOF records an absolute PEXPIREAT deadline (see Self::set_with_ttl) so the TTL survives a restart unchanged.

Source

pub fn persist(&self, key: &[u8]) -> Result<bool>

PERSIST key. Returns true if a TTL was actually cleared.

Source

pub fn ttl_ms(&self, key: &[u8]) -> i64

Remaining TTL in ms (or Redis-style -1/-2 for no-TTL/no-key).

Source

pub fn type_of(&self, key: &[u8]) -> &'static str

TYPE key"string", "hash", "list", "set", "zset", or "none".

Source

pub fn dbsize(&self) -> usize

DBSIZE — total live keys across all shards.

Source

pub fn flushall(&self) -> Result<()>

FLUSHALL — empty every shard (each logs FLUSHALL so a replay reaches the same empty state).

Named flushallnot flush — to avoid colliding with Write::flush’s “sync buffered writes to disk” meaning. This call WIPES the store; durability needs no explicit call (each write appends to the AOF, the shard’s BufWriter lands per AppendFsync cadence and on drop).

Source

pub fn flush(&self) -> Result<()>

👎Deprecated since 1.2.0:

renamed to flushall: flush collides with Write::flush (sync-to-disk); this WIPES the store

Deprecated alias for Self::flushall. The old name read like Write::flush (sync-to-disk) but actually WIPES the store — a data-loss footgun.

Source

pub fn key_bytes(&self, key: &[u8]) -> Option<u64>

MEMORY USAGE for one key — Some(bytes) or None if absent.

Source

pub fn used_memory(&self) -> u64

Live used_memory estimate (summed across shards).

Source

pub fn evictions_total(&self) -> u64

INFO-style counter: total keys evicted by maxmemory (all shards).

Source

pub fn expired_keys_total(&self) -> u64

INFO-style counter: total keys expired (lazy + active reaper, all shards).

Source

pub fn hset(&self, key: &[u8], pairs: &[(&[u8], &[u8])]) -> Result<usize>

HSET key field value [field value ...]. Returns count newly added.

Source

pub fn hget(&self, key: &[u8], field: &[u8]) -> Result<Option<Vec<u8>>>

HGET key field. None if absent.

Source

pub fn hdel(&self, key: &[u8], fields: &[&[u8]]) -> Result<usize>

HDEL key field [field ...]. Returns count actually removed.

Source

pub fn lpush(&self, key: &[u8], values: &[&[u8]]) -> Result<usize>

LPUSH key value [value ...]. Returns the new list length.

Source

pub fn rpush(&self, key: &[u8], values: &[&[u8]]) -> Result<usize>

RPUSH key value [value ...]. Returns the new list length.

Source

pub fn lpop(&self, key: &[u8], count: usize) -> Result<Vec<Vec<u8>>>

LPOP key count. Returns popped values from the head.

Source

pub fn rpop(&self, key: &[u8], count: usize) -> Result<Vec<Vec<u8>>>

RPOP key count. Symmetric to LPOP from the tail.

Source

pub fn llen(&self, key: &[u8]) -> Result<usize>

LLEN key. Length of the list at key; 0 if absent.

Source

pub fn sadd(&self, key: &[u8], members: &[&[u8]]) -> Result<usize>

SADD key member [member ...]. Returns count newly added.

Source

pub fn srem(&self, key: &[u8], members: &[&[u8]]) -> Result<usize>

SREM key member [member ...]. Returns count actually removed.

Source

pub fn smembers(&self, key: &[u8]) -> Result<Vec<Vec<u8>>>

SMEMBERS key. Order implementation-defined; empty if absent.

Source

pub fn scard(&self, key: &[u8]) -> Result<usize>

SCARD key. Member count; 0 if absent.

Source

pub fn zadd(&self, key: &[u8], pairs: &[(f64, &[u8])]) -> Result<usize>

ZADD key score member [score member ...]. Returns count newly added.

Source

pub fn zrem(&self, key: &[u8], members: &[&[u8]]) -> Result<usize>

ZREM key member [member ...]. Returns count actually removed.

Source

pub fn zscore(&self, key: &[u8], member: &[u8]) -> Result<Option<f64>>

ZSCORE key member. Some(score) if present.

Source

pub fn zcard(&self, key: &[u8]) -> Result<usize>

ZCARD key. Member count; 0 if absent.

Source

pub fn publish(&self, channel: &[u8], payload: &[u8]) -> usize

PUBLISH channel payload. Delivers payload to every subscriber on channel (direct + pattern matches) inside this process. Returns the count of receivers the message reached.

Source

pub fn subscribe(&self, channels: &[&[u8]]) -> Subscription

Open a Subscription subscribed to channels. Drop the handle to unsubscribe from everything atomically. Pass &[] to start with no subscriptions and add some later via Subscription::subscribe / Subscription::psubscribe.

Source

pub fn psubscribe(&self, patterns: &[&[u8]]) -> Subscription

Convenience: open a Subscription starting on pattern subscriptions.

Source§

impl Store

Source

pub fn atomic<R>( &self, body: impl FnOnce(&mut AtomicCtx<'_>) -> Result<R>, ) -> Result<R>

Run body as a single-shard atomic transaction. Inside the closure every read sees previous writes; on closure return the queued AOF writes are committed under one fsync.

Constraint: every key touched inside the closure must hash to the same shard. The default embedded config uses 1 shard, so any key works.

Source§

impl Store

Source

pub fn atomic_all_shards<R>( &self, body: impl FnOnce(&mut AtomicAllShards<'_>) -> Result<R>, ) -> Result<R>

Run body as a transaction holding write locks on EVERY shard for the closure’s duration. Reads inside the closure see prior writes (full read-modify-write). On closure return, AOF writes commit with one fsync per shard.

Cost: blocks every other writer + reader on this Store for the closure body. Use when atomic multi-shard semantics are required; otherwise prefer the single-shard atomic.

Source§

impl Store

Source

pub fn getbit(&self, key: &[u8], offset: u64) -> Result<u8>

GETBIT key offset — return the bit at offset (MSB-first). 0 for missing key or past-end.

Source

pub fn setbit(&self, key: &[u8], offset: u64, value: u8) -> Result<u8>

SETBIT key offset value — set the bit at offset to value (0 or 1). Extends the underlying string with zero padding as needed. Returns the PREVIOUS bit value.

Source

pub fn bitcount(&self, key: &[u8], range: Option<(i64, i64)>) -> Result<u64>

BITCOUNT key [start end] — count set bits over the optional byte-offset range (inclusive, negatives-from-tail like Redis). None for range = whole string.

Source

pub fn bitpos( &self, key: &[u8], bit: u8, range: Option<(i64, i64)>, ) -> Result<Option<u64>>

BITPOS key bit [start [end]] — find first bit equal to bit (0 or 1) in the optional byte range. Returns None when not found (Redis would reply :-1).

Source

pub fn getrange(&self, key: &[u8], start: i64, end: i64) -> Result<Vec<u8>>

GETRANGE key start end — substring with Redis negative indexing; [start, end] inclusive.

Source

pub fn setrange(&self, key: &[u8], offset: u64, value: &[u8]) -> Result<usize>

SETRANGE key offset value — overwrite bytes at offset; extends with zero padding if past current length. Returns the new total length.

Source

pub fn bitop(&self, op: BitOp, dst: &[u8], srcs: &[&[u8]]) -> Result<usize>

BITOP AND|OR|XOR|NOT destkey srckey [srckey ...] — bitwise op across N source keys, stored at destkey. Returns the destination string length (= longest source length, with shorter sources zero-padded). For Not, exactly one source key (additional ones are rejected).

Source

pub fn time(&self) -> (u64, u32)

TIME(unix_seconds, microseconds) tuple. Useful for time-based embedded logic + tracing.

Source§

impl Store

Source

pub fn setnx(&self, key: &[u8], value: &[u8]) -> Result<bool>

SETNX key value — set only if the key does not exist. Returns true when the SET succeeded; false when it was vetoed by an existing value.

Source

pub fn incrbyfloat(&self, key: &[u8], delta: f64) -> Result<f64>

INCRBYFLOAT key delta — atomic float increment of a string value. Returns the post-increment value parsed as f64.

Source

pub fn decr(&self, key: &[u8]) -> Result<i64>

DECR key — atomic decrement by 1.

Source

pub fn decrby(&self, key: &[u8], delta: i64) -> Result<i64>

DECRBY key delta — atomic decrement by delta.

Source

pub fn strlen(&self, key: &[u8]) -> Result<usize>

STRLEN key — length of the string value at key; 0 if absent. Errors on wrong type.

Source

pub fn append(&self, key: &[u8], data: &[u8]) -> Result<usize>

APPEND key data — append data to the string at key. Creates the key if absent. Returns the new total length.

Source

pub fn hsetnx(&self, key: &[u8], field: &[u8], value: &[u8]) -> Result<bool>

HSETNX key field value — set the hash field only if it does not already exist. Returns true when set; false when the field existed.

Source

pub fn ttl_secs(&self, key: &[u8]) -> i64

TTL key — TTL in seconds (truncated from ms). -1 when the key has no TTL; -2 when absent. Matches Redis wire semantics for the integer reply.

Source§

impl Store

Source

pub fn copy(&self, src: &[u8], dst: &[u8], replace: bool) -> Result<bool>

COPY src dst [REPLACE] — copy src’s value (and TTL if any) to dst. Returns true when the copy happened.

Semantics:

  • false if src doesn’t exist.
  • false if dst exists and replace = false.
  • Preserves source TTL on the destination via pexpireat.
Source

pub fn randomkey(&self) -> Option<Vec<u8>>

RANDOMKEY — return a randomly-chosen existing key, or None when the keyspace is empty.

Implementation: snapshot all keys via collect_keys, then pick a uniform index. For large keyspaces this is O(N); a future ship can add a key_at(rank) Store method for O(1) random pick.

UNLINK key [key ...] — alias for Self::del. In Redis this is the async (non-blocking) variant; kevy is in-process so the sync del IS the unblocking semantic. Returns count actually removed.

Source

pub fn touch(&self, keys: &[&[u8]]) -> Result<usize>

TOUCH key [key ...] — count keys that exist. Side effect: the existence check refreshes LRU/LFU bookkeeping on the touched shards, matching Redis semantics.

Source§

impl Store

Source

pub fn prefix_digest(&self, prefix: &[u8]) -> (u64, u64)

v2.10 — order-insensitive prefix checksum for migration verification: (row_count, xor_of_row_digests). Matches the server’s PREFIX.DIGEST bit for bit (same canonicalization).

Source§

impl Store

Source

pub fn sismember(&self, key: &[u8], member: &[u8]) -> Result<bool>

SISMEMBER key membertrue when member is in the set.

Source

pub fn spop(&self, key: &[u8], count: usize) -> Result<Vec<Vec<u8>>>

SPOP key count — atomically remove + return up to count random members.

AOF form: logged as SREM key <popped…> (the members actually removed), not SPOP key count — a random pick replayed against a store whose internal layout differs (replica applying frames onto snapshot-loaded state) would remove different members. Redis propagates SPOP the same way.

Source

pub fn srandmember(&self, key: &[u8], count: usize) -> Result<Vec<Vec<u8>>>

SRANDMEMBER key count — return up to count random members without removing them.

Source

pub fn zrank(&self, key: &[u8], member: &[u8]) -> Result<Option<usize>>

ZRANK key member — rank (0-based, ascending) of member; None if not present.

Source

pub fn zcount(&self, key: &[u8], min: f64, max: f64) -> Result<usize>

ZCOUNT key min max — count members whose score falls in [min, max] (inclusive). Pass ±INFINITY for open bounds.

Source

pub fn zpopmin(&self, key: &[u8], count: usize) -> Result<Vec<(Vec<u8>, f64)>>

ZPOPMIN key count — atomically remove + return up to count members with the lowest scores. Pairs are (member, score).

Source

pub fn zremrangebyrank( &self, key: &[u8], start: i64, stop: i64, ) -> Result<usize>

ZREMRANGEBYRANK key start stop — remove members in [start, stop] rank range (inclusive, Redis-style negative indexing). Returns count removed.

Source

pub fn zremrangebyscore(&self, key: &[u8], min: f64, max: f64) -> Result<usize>

ZREMRANGEBYSCORE key min max — remove members with scores in [min, max] (inclusive). Returns count removed.

Source

pub fn zrev_range_by_score( &self, key: &[u8], max: f64, min: f64, ) -> Result<Vec<(Vec<u8>, f64)>>

ZREVRANGEBYSCORE key max min — members with scores in [min, max] in DESCENDING score order. Inclusive bounds.

Source

pub fn lset(&self, key: &[u8], idx: i64, value: &[u8]) -> Result<()>

LSET key idx value — set the element at idx (negative indexes count from tail). Errors NoSuchKey / OutOfRange matching Redis.

Source

pub fn ltrim(&self, key: &[u8], start: i64, stop: i64) -> Result<()>

LTRIM key start stop — trim list to [start, stop] inclusive (Redis-style negative indexing).

Source

pub fn rename(&self, src: &[u8], dst: &[u8]) -> Result<bool>

RENAME src dst — atomic rename. Returns true when the rename happened. Errors when src doesn’t exist (Redis would reply -ERR no such key, here Err(NoSuchKey)).

Source

pub fn renamenx(&self, src: &[u8], dst: &[u8]) -> Result<bool>

RENAMENX src dst — rename only when dst doesn’t exist. Returns true when the rename happened.

Source§

impl Store

Source

pub fn hgetall(&self, key: &[u8]) -> Result<Vec<(Vec<u8>, Vec<u8>)>>

HGETALL key — every (field, value) pair in key’s hash, in arbitrary order. Empty when key is absent. Errors on wrong type.

Source

pub fn hexists(&self, key: &[u8], field: &[u8]) -> Result<bool>

HEXISTS key fieldtrue when field is present.

Source

pub fn hlen(&self, key: &[u8]) -> Result<usize>

HLEN key — number of fields; 0 when absent.

Source

pub fn hkeys(&self, key: &[u8]) -> Result<Vec<Vec<u8>>>

HKEYS key — every field name in key’s hash.

Source

pub fn hvals(&self, key: &[u8]) -> Result<Vec<Vec<u8>>>

HVALS key — every value in key’s hash.

Source

pub fn hmget( &self, key: &[u8], fields: &[&[u8]], ) -> Result<Vec<Option<Vec<u8>>>>

HMGET key field [field ...] — read multiple fields in one call. None per requested field that is absent.

Source

pub fn hincrby(&self, key: &[u8], field: &[u8], delta: i64) -> Result<i64>

HINCRBY key field delta — atomic integer increment of a hash field. Returns the post-increment value.

Source

pub fn zrange( &self, key: &[u8], start: i64, stop: i64, ) -> Result<Vec<(Vec<u8>, f64)>>

ZRANGE key start stop WITHSCORES — members in ascending score order between rank start..=stop (Redis-style inclusive indexing; negatives count from the tail). Returns (member, score) pairs.

Source

pub fn zrevrange( &self, key: &[u8], start: i64, stop: i64, ) -> Result<Vec<(Vec<u8>, f64)>>

ZREVRANGE key start stop WITHSCORESzrange with the order reversed (highest score first). The start..=stop indexing is against the reversed list, matching Redis semantics.

Source

pub fn zrange_by_score( &self, key: &[u8], min: f64, max: f64, ) -> Result<Vec<(Vec<u8>, f64)>>

ZRANGEBYSCORE — score-range read. min / max are inclusive; pass f64::NEG_INFINITY / f64::INFINITY for open bounds. Returns (member, score) pairs in ascending score order. Exclusive bounds are ZRANGEBYSCORE ( syntax in Redis; expose via the dedicated Self::zrange_by_score_excl.

Source

pub fn zrange_by_score_excl( &self, key: &[u8], min: ScoreBound, max: ScoreBound, ) -> Result<Vec<(Vec<u8>, f64)>>

Same as Self::zrange_by_score but with explicit inclusive/exclusive control on each bound ((min / (max in Redis syntax).

Source

pub fn zrange_by_score_limit( &self, key: &[u8], min: f64, max: f64, offset: usize, count: usize, ) -> Result<Vec<(Vec<u8>, f64)>>

ZRANGEBYSCORE key min max LIMIT offset count — score-range read with pagination (v2.2; closes the embedded LIMIT gap — the server parser always had it).

Source

pub fn zrevrange_by_score_limit( &self, key: &[u8], max: f64, min: f64, offset: usize, count: usize, ) -> Result<Vec<(Vec<u8>, f64)>>

ZREVRANGEBYSCORE key max min LIMIT offset count — descending score-range read with pagination.

Source

pub fn zpopmin_below( &self, key: &[u8], below: f64, count: usize, ) -> Result<Vec<(Vec<u8>, f64)>>

v2.4 zpopmin_below — pop up to count lowest members with score strictly < below (delayed-job “pop what’s due”). AOF logs the effect (ZREM of the popped members).

Source

pub fn zincrby(&self, key: &[u8], delta: f64, member: &[u8]) -> Result<f64>

ZINCRBY key delta member — atomic float increment of a member’s score. Returns the post-increment score.

Source

pub fn lrange(&self, key: &[u8], start: i64, stop: i64) -> Result<Vec<Vec<u8>>>

LRANGE key start stop — list slice. Negative indices count from the tail. Empty when absent.

Source

pub fn lindex(&self, key: &[u8], idx: i64) -> Result<Option<Vec<u8>>>

LINDEX key idx — element at index idx; None out of range.

Source

pub fn lrem(&self, key: &[u8], count: i64, value: &[u8]) -> Result<usize>

LREM key count value — remove up to |count| occurrences of value. count > 0 from head, count < 0 from tail, count == 0 all. Returns the count actually removed.

Source

pub fn getset(&self, key: &[u8], new: &[u8]) -> Result<Option<Vec<u8>>>

GETSET key new — set key to new, return the previous value (or None when key was absent).

Source

pub fn getdel(&self, key: &[u8]) -> Result<Option<Vec<u8>>>

GETDEL key — delete key, return the previous value (None when key was absent).

Source§

impl Store

Source

pub fn mset(&self, pairs: &[(&[u8], &[u8])]) -> Result<()>

MSET key value [key value ...] — set every pair atomically per-key. Each pair is logged independently to its shard’s AOF (no cross-shard atomic guarantee — a crash mid-call may leave a prefix applied; matches Redis Cluster semantics).

Source

pub fn mget(&self, keys: &[&[u8]]) -> Result<Vec<Option<Vec<u8>>>>

MGET key [key ...] — return Some(value) per requested key that’s present, None per absent / wrong-type.

Source

pub fn keys(&self, pattern: Option<&[u8]>, limit: Option<usize>) -> Vec<Vec<u8>>

KEYS pattern — glob-match every key in the keyspace (across all shards). pattern = None matches everything. limit = None is unbounded; otherwise bounds the TOTAL returned across shards. Glob syntax matches Redis (* / ? / [abc] / escape).

Source

pub fn getex(&self, key: &[u8], ttl: Duration) -> Result<Option<Vec<u8>>>

GETEX key TTL — get the value and update the TTL atomically (single lock cycle on the owning shard). Returns the value; None when absent. AOF-logged as PEXPIRE.

Source

pub fn sinter(&self, keys: &[&[u8]]) -> Result<Vec<Vec<u8>>>

SINTER key [key ...] — set intersection. Reads each key’s members, computes the intersection in BTreeSet order (sorted, no duplicates).

Source

pub fn sunion(&self, keys: &[&[u8]]) -> Result<Vec<Vec<u8>>>

SUNION key [key ...] — set union over N sets.

Source

pub fn sdiff(&self, keys: &[&[u8]]) -> Result<Vec<Vec<u8>>>

SDIFF key [key ...]keys[0] minus the union of every subsequent set.

Source

pub fn expireat(&self, key: &[u8], unix_secs: u64) -> Result<bool>

EXPIREAT key unix_secs — schedule expiry for the given absolute UNIX wall-clock time. Returns true when the key existed and the deadline was set; false when absent.

Source

pub fn pexpireat(&self, key: &[u8], unix_ms: u64) -> Result<bool>

PEXPIREAT key unix_ms — same as expireat but in milliseconds.

Source

pub fn pexpire(&self, key: &[u8], ms: u64) -> Result<bool>

PEXPIRE key ms — relative TTL in milliseconds. (expire takes Duration; this is the integer-ms variant matching the Redis wire command.)

Source

pub fn hincrbyfloat(&self, key: &[u8], field: &[u8], delta: f64) -> Result<f64>

HINCRBYFLOAT key field delta — atomic float increment of a hash field. Returns the post-increment value. Errors on NotFloat when the field is present but not parseable.

Source

pub fn linsert( &self, key: &[u8], before: bool, pivot: &[u8], value: &[u8], ) -> Result<i64>

LINSERT key BEFORE|AFTER pivot value — insert value before or after the first occurrence of pivot in the list. Returns:

  • Ok(new_len) on success (>= 1);
  • Ok(0) when key does not exist;
  • Ok(-1) when pivot was not found in the list.

before = true matches Redis LINSERT … BEFORE, false matches LINSERT … AFTER.

Source

pub fn ping_ns(&self) -> u128

Store::ping_us() — return the round-trip duration of a shard-0 read-lock acquire + release in nanoseconds, for perfgate observability. Always returns immediately; the duration reflects current shard-0 contention (= shorter when idle, longer when many readers/writers compete).

Source§

impl Store

Source

pub fn pipeline(&self) -> Pipeline<'_>

Begin a Pipeline — fluent write queue. Add ops via .set(...).hset(...).zadd(...) then call .commit().

Source§

impl Store

Source

pub fn info_prefix(&self, prefix: &[u8]) -> PrefixInfo

v2.3 info_prefix: count live keys (and TTL’d keys) under a byte prefix, across all shards. O(keyspace) — an ops/stats call, not a hot-path primitive.

Source

pub fn feed_shards(&self) -> usize

Number of independent change streams this store exposes (the embedded write path serializes all shards: always 1).

Source

pub fn changes_tail(&self) -> Result<(u64, u64), FeedError>

The current (generation, next_offset) cursor — where a consumer starting fresh (or resuming after a rebuild) begins.

Source

pub fn changes_since( &self, generation: u64, offset: u64, limit: usize, prefixes: &[&[u8]], ) -> Result<ChangeBatch, FeedError>

Deliver up to limit changes at cursor (generation, offset), optionally prefix-filtered (fail-open on multi-key verbs; the filter never affects the returned cursor). At-least-once: after a Resync rebuild, frames already applied may be seen again.

Source§

impl Store

Source

pub fn blpop( &self, keys: &[&[u8]], timeout: Option<Duration>, ) -> Result<Option<(Vec<u8>, Vec<u8>)>>

BLPOP — block until one of keys has a head element (checked in argument order each round) or timeout passes (None = wait forever). Returns (key, value).

Source

pub fn brpop( &self, keys: &[&[u8]], timeout: Option<Duration>, ) -> Result<Option<(Vec<u8>, Vec<u8>)>>

BRPOP — tail-end counterpart of Self::blpop.

Source

pub fn bzpopmin( &self, keys: &[&[u8]], timeout: Option<Duration>, ) -> Result<Option<(Vec<u8>, Vec<u8>, f64)>>

BZPOPMIN — block until one of keys has a zset member; returns (key, member, score).

Source§

impl Store

Source

pub fn hexpire( &self, key: &[u8], fields: &[&[u8]], ttl: Duration, cond: HExpireCond, ) -> Result<Vec<HExpireCode>>

HEXPIRE — set a relative per-field TTL. One Redis code per field (-2 missing, 0 condition failed, 1 set, 2 deleted).

Source

pub fn hpexpire_at( &self, key: &[u8], fields: &[&[u8]], deadline_ms: u64, cond: HExpireCond, ) -> Result<Vec<HExpireCode>>

HPEXPIREAT — absolute unix-ms per-field deadline (the canonical form; also what the AOF carries).

Source

pub fn httl(&self, key: &[u8], fields: &[&[u8]]) -> Result<Vec<i64>>

HTTL — remaining ms per field (-2 missing, -1 no TTL).

Source

pub fn hpersist(&self, key: &[u8], fields: &[&[u8]]) -> Result<Vec<HExpireCode>>

HPERSIST — clear per-field TTLs (-2 missing, -1 had no TTL, 1 cleared).

Source§

impl Store

Source

pub fn idx_create( &self, name: &[u8], prefix: &[u8], field: &[u8], ty: ValType, kind: IndexKind, ) -> Result<()>

IDX.CREATE equivalent. Builds synchronously; errors on duplicate name / cap / bad spec.

Source

pub fn idx_create_ann( &self, name: &[u8], prefix: &[u8], field: &[u8], params: AnnSpec, ) -> Result<()>

v2.8: declare an ANN index (KIND ann, TYPE vector). params.m / params.ef of 0 select the defaults (16 / 200).

Source

pub fn idx_drop(&self, name: &[u8]) -> bool

IDX.DROP equivalent; false if absent. On a hit the catalog sidecar is re-persisted so the drop survives restart.

Source

pub fn idx_query( &self, name: &[u8], min: &IndexValue, max: &IndexValue, cursor: Option<&Cursor>, limit: usize, ) -> Result<IndexPage>

Range / EQ query with cursor pagination: merged across shards in (value, key) order. cursor = None starts; the returned cursor resumes exclusively.

Source

pub fn idx_count( &self, name: &[u8], min: &IndexValue, max: &IndexValue, ) -> Result<u64>

Count without materializing keys.

Source

pub fn idx_stats(&self, name: &[u8]) -> Result<SegmentStats>

Summed segment stats (entries / bytes / coerce failures / unique-fence duplicates).

Source

pub fn idx_list(&self) -> Vec<(Vec<u8>, Vec<u8>, IndexKind)>

Declared indexes (name, prefix, kind), declaration order.

Source

pub fn idx_match( &self, name: &[u8], query: &[u8], limit: usize, ) -> Result<Vec<(Vec<u8>, f64)>>

v2.7 MATCH — BM25-ranked hits merged across shards (shard-local statistics; see docs/text-search.md).

Source

pub fn idx_create_agg( &self, name: &[u8], prefix: &[u8], field: &[u8], ty: ValType, group_by: &[u8], ) -> Result<()>

v3.1: declare an aggregate index (KIND agg — write-time GROUP BY). ty must be numeric.

Source

pub fn idx_group(&self, name: &[u8], group: &[u8]) -> Result<GroupStats>

v3.1: one group’s merged stats across shards.

Source

pub fn idx_groups( &self, name: &[u8], by: AggBy, limit: usize, ) -> Result<Vec<(Vec<u8>, GroupStats)>>

v3.1: top groups merged + ranked across shards.

Source

pub fn idx_knn( &self, name: &[u8], query: &[f32], k: usize, ef: usize, ) -> Result<Vec<(Vec<u8>, f32)>>

v2.8 KNN — nearest neighbors merged ascending across shards. ef = query beam width (0 = engine default; recall knob).

Source§

impl Store

Source

pub fn view_create( &self, name: &[u8], tree: Tree, order_by: &[u8], desc: bool, mode: ViewMode, ) -> Result<()>

Declare a view (typed tree; via is not supported embedded — read fields in-process). Builds synchronously.

Source

pub fn view_drop(&self, name: &[u8]) -> bool

Drop a view; false if absent.

Source

pub fn view_query( &self, name: &[u8], after: Option<&(IndexValue, Vec<u8>)>, limit: usize, ) -> Result<ViewPage>

Ordered page across shards (after resumes exclusively; DESC views page from the large end).

Source

pub fn view_list(&self) -> Vec<(Vec<u8>, ViewMode, usize)>

Declared views (name, mode, leaves).

Source

pub fn view_count(&self, name: &[u8]) -> Result<u64>

Summed member count across shards.

Source§

impl Store

Source

pub fn snapshot(&self) -> Snapshot

Freeze a consistent point-in-time Snapshot of the whole keyspace (see the module doc for the locking discipline).

Source§

impl Store

Source

pub fn zinterstore( &self, dst: &[u8], keys: &[&[u8]], weights: Option<&[f64]>, aggregate: ZAggregate, ) -> Result<usize>

ZINTERSTORE dst keys… [WEIGHTS …] [AGGREGATE SUM|MIN|MAX] — returns the stored cardinality.

Source

pub fn zunionstore( &self, dst: &[u8], keys: &[&[u8]], weights: Option<&[f64]>, aggregate: ZAggregate, ) -> Result<usize>

ZUNIONSTORE dst keys… [WEIGHTS …] [AGGREGATE …].

Source

pub fn zdiffstore(&self, dst: &[u8], keys: &[&[u8]]) -> Result<usize>

ZDIFFSTORE dst keys… (no weights/aggregate — Redis 6.2).

Source

pub fn zintercard(&self, keys: &[&[u8]], limit: usize) -> Result<usize>

ZINTERCARD keys… [LIMIT n]limit = 0 means unlimited.

Source

pub fn sinterstore(&self, dst: &[u8], keys: &[&[u8]]) -> Result<usize>

SINTERSTORE dst keys… — set-algebra store form (members only).

Source

pub fn sunionstore(&self, dst: &[u8], keys: &[&[u8]]) -> Result<usize>

SUNIONSTORE dst keys….

Source

pub fn sdiffstore(&self, dst: &[u8], keys: &[&[u8]]) -> Result<usize>

SDIFFSTORE dst keys….

Source§

impl Store

Source

pub fn zadd_flags( &self, key: &[u8], pairs: &[(f64, &[u8])], flags: ZaddFlags, ) -> Result<ZaddReport>

Flags-aware ZADD. See ZaddFlags; read ZaddReport::changed for the CH reply shape. The monotonic-heal idiom is zadd_flags(k, pairs, ZaddFlags { gt: true, ..Default::default() }).

Source

pub fn zadd_incr( &self, key: &[u8], delta: f64, member: &[u8], flags: ZaddFlags, ) -> Result<Option<f64>>

ZADD … INCR — a conditional ZINCRBY; None when the flags veto the operation.

Source§

impl Store

Source

pub fn scan( &self, cursor: u64, pattern: Option<&[u8]>, count: usize, ) -> (u64, Vec<Vec<u8>>)

SCAN cursor [MATCH pattern] [COUNT n] — return up to count keys, plus the next cursor. cursor = 0 starts the walk; next_cursor = 0 means the walk completed.

count is the page size; pass usize::MAX to drain in one call.

Source

pub fn keys_iter(&self, pattern: Option<&[u8]>) -> IntoIter<Vec<u8>>

Iterator wrapper around Self::scan — emits every matching key as a Vec<u8>. Drains the keyspace in one snapshot at construction time; matches Rust idioms.

Source

pub fn hscan( &self, key: &[u8], cursor: u64, count: usize, ) -> Result<(u64, Vec<(Vec<u8>, Vec<u8>)>)>

HSCAN key cursor [COUNT n] — return up to count (field, value) pairs from the hash at key, plus the next cursor. cursor = 0 starts; next_cursor = 0 means complete.

Source

pub fn hash_iter(&self, key: &[u8]) -> Result<IntoIter<(Vec<u8>, Vec<u8>)>>

Iterator wrapper around Self::hscan.

Source

pub fn zscan( &self, key: &[u8], cursor: u64, count: usize, ) -> Result<(u64, Vec<(Vec<u8>, f64)>)>

ZSCAN key cursor [COUNT n] — return up to count (member, score) pairs from the sorted set at key, in ascending score order, plus the next cursor.

Source

pub fn zset_iter(&self, key: &[u8]) -> Result<IntoIter<(Vec<u8>, f64)>>

Iterator wrapper around Self::zscan.

Source§

impl Store

Source

pub fn open(config: Config) -> Result<Self>

Open an embedded keyspace per config.

  • Pure in-memory when config.data_dir is None.
  • With persistence: each shard loads its snapshot then replays its AOF (config.shards > 1 re-shards a legacy single AOF on first open).
  • Spawns a background TTL reaper thread when config.ttl_reaper == Background (the default).
  • When config.replica_upstream = Some("host:port"), spawns a background thread that streams replication frames from the named primary and applies them to this store; local writes are rejected with READONLY (see Self::open_replica).
Source

pub fn open_replica(upstream: impl Into<String>) -> Result<Self>

Convenience constructor for an embed-as-read-replica store streaming writes from upstream ("host:port" of a kevy server’s replication listener).

The replica:

  • has its local AOF force-disabled (the upstream stream is the source of truth; replica AOF would diverge and double-apply on restart);
  • rejects every local write with a READONLY io::Error (you can still call read APIs concurrently);
  • reconnects with exponential backoff on disconnect, resuming from the last applied offset;
  • gets a process-unique replica_id so an open / drop / reopen cycle within the primary’s reconnect window does not look like the same slot from the primary’s POV (which would evict backlog frames the new embed still needs from offset 0). Override via Config::with_replica_id when you specifically want the slot to be re-claimed across restarts.

For full builder control (custom replica id, backoff bounds, snapshot dir, etc.) use Self::open with Config::with_replica_upstream + the related setters instead.

Source

pub fn is_replica(&self) -> bool

true when this store was opened against a replication upstream — local writes are rejected with READONLY.

Source

pub fn set_replica_upstream( &self, new_upstream: impl Into<String>, ) -> Result<()>

Retarget this replica at a new primary URL (host:port). The runner picks up the change on its next connect — which is forced now by shutdowning the current socket clone, so the retarget lands within Config::replica_reconnect_min (default 100 ms) of this call.

Returns Err with ErrorKind::InvalidInput when this store is not a replica (no upstream was configured at open). Application code typically drives this from a kevy-elect failover signal — see docs/cluster.md. kevy-embedded itself stays elect-protocol-agnostic; the integration glue lives in the application.

Source

pub fn downgrade(&self) -> WeakStore

Get a weak handle that does not keep the keyspace alive.

Source

pub fn config(&self) -> &Config

The active config (a clone — modifying it has no effect on the running store). Useful for introspection / INFO-style telemetry.

Source

pub fn with<F, R>(&self, f: F) -> R
where F: FnOnce(&mut Store) -> R,

Run f against the underlying kevy_store::Store under its lock. Use for direct access to methods this crate hasn’t wrapped. The closure can mutate, but does not auto-log to the AOF — call Self::log yourself if the mutation must survive a crash.

Sharded stores: this targets shard 0 only. Use Self::with_key to reach the shard owning a specific key.

Source

pub fn with_key<F, R>(&self, key: &[u8], f: F) -> R
where F: FnOnce(&mut Store) -> R,

Like Self::with but targets the shard that owns key.

Source

pub fn collect_keys( &self, pattern: Option<&[u8]>, limit: Option<usize>, ) -> Vec<Vec<u8>>

KEYS / SCAN-glob across every shard — the cross-shard replacement for with(|s| s.collect_keys(pat, lim)), which only sees shard 0 once sharding is on. Behaves identically to with(...) when shard_count() == 1. limit bounds the total returned across shards. Takes a read lock per shard (concurrent-safe).

Source

pub fn for_each_shard<F: FnMut(&mut Store)>(&self, f: F)

Run f against each shard’s underlying kevy_store::Store (in shard-index order) — the cross-shard escape hatch. The caller assembles the merged result. Pairs with Self::shard_count. For a single key, prefer Self::with_key; for a glob scan, prefer Self::collect_keys.

Source

pub fn shard_count(&self) -> usize

Number of keyspace shards (== Config::shards).

Source

pub fn log(&self, parts: &[&[u8]]) -> Result<()>

Append a raw RESP-frame argument list to the shard owning its key’s AOF. No-op when persistence is disabled.

Source

pub fn tick(&self) -> ExpireStats

Run one TTL-reaper tick across every shard. Required call cadence in Manual mode (~10×/s to match Redis hz=10). Returns the summed stats.

Source§

impl Store

Source

pub fn fsync_aof(&self) -> Result<()>

Durability barrier (v2.1): flush + fdatasync every shard’s AOF now, regardless of the configured appendfsync policy. On Ok(()), every write acknowledged before this call is on stable storage. The EverySec serving-store idiom:

store.atomic(|c| { /* critical write */ Ok(()) })?;
store.fsync_aof()?; // durable-on-ack for THIS block only

Cost: one fdatasync per dirty shard; a no-op on clean shards. Under appendfsync = always it is a no-op (already durable).

Source

pub fn rewrite_aof(&self) -> Result<Option<RewriteStats>>

BGREWRITEAOF: rebuild every shard’s AOF from current state. Synchronous (despite the RESP name). Returns the summed stats (None if persistence is off / no shard rewrote). Shards mid rewrite are skipped. Emits KevyMetric::Rewrite per shard.

Source

pub fn save_snapshot(&self) -> Result<bool>

Snapshot every shard to its dump-{i}.rdb (single shard: the configured name), atomically. Ok(false) when persistence is disabled.

Trait Implementations§

Source§

impl Clone for Store

Source§

fn clone(&self) -> Store

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Store

§

impl !UnwindSafe for Store

§

impl Freeze for Store

§

impl Send for Store

§

impl Sync for Store

§

impl Unpin for Store

§

impl UnsafeUnpin for Store

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.