use super::flags::*;
use super::{VerbMeta, v};
#[rustfmt::skip]
pub(super) const ROWS: &[VerbMeta] = &[
v("HDEL", "hash", -3, W, "Delete one or more hash fields.", "1.0.0", "HDEL key field [field ...]",
"O(M) fields",
"full"),
v("HEXISTS", "hash", 3, R, "Check whether a hash field exists.", "1.0.0", "HEXISTS key field",
"O(1)",
"full"),
v("HEXPIRE", "hash", -6, W, "Set per-field TTLs on a hash, in seconds.", "1.0.0", "HEXPIRE key seconds [NX|XX|GT|LT] FIELDS numfields field [field ...]",
"O(F) fields in the FIELDS clause",
"differs: the FIELDS parse error reads 'Mandatory keyword FIELDS is missing' where Redis says 'Mandatory argument FIELDS'"),
v("HGET", "hash", 3, R, "Return the value of a hash field.", "1.0.0", "HGET key field",
"O(1)",
"full"),
v("HGETALL", "hash", 2, R, "Return all fields and values of a hash.", "1.0.0", "HGETALL key",
"O(N) fields, with a full copy of every name and value",
"full"),
v("HINCRBY", "hash", 4, W, "Increment the integer value of a hash field.", "1.0.0", "HINCRBY key field increment",
"O(1)",
"full"),
v("HINCRBYFLOAT", "hash", 4, W, "Increment the float value of a hash field.", "1.0.0", "HINCRBYFLOAT key field increment",
"O(1)",
"full"),
v("HRANDFIELD", "hash", -2, R, "Return random fields from a hash; a negative count allows repeats, WITHVALUES pairs each with its value.", "6.2.0", "HRANDFIELD key [count [WITHVALUES]]",
"O(count) for the positive form (partial Fisher-Yates over a materialised field list), O(|count|) for the negative form",
"full"),
v("HKEYS", "hash", 2, R, "Return all field names of a hash.", "1.0.0", "HKEYS key",
"O(N) fields",
"full"),
v("HLEN", "hash", 2, R, "Return the number of fields in a hash.", "1.0.0", "HLEN key",
"O(1)",
"full"),
v("HMGET", "hash", -3, R, "Return the values of multiple hash fields.", "1.0.0", "HMGET key field [field ...]",
"O(M) fields requested",
"full"),
v("HMSET", "hash", -4, W, "Deprecated alias of HSET that replies OK.", "1.0.0", "HMSET key field value [field value ...]",
"O(M) pairs",
"full"),
v("HPERSIST", "hash", -5, W, "Remove per-field TTLs from a hash.", "1.0.0", "HPERSIST key FIELDS numfields field [field ...]",
"O(F) fields",
"differs: silently accepts a stray NX|XX|GT|LT token before FIELDS (it shares HEXPIRE's parser) where Redis rejects it"),
v("HPEXPIRE", "hash", -6, W, "Set per-field TTLs on a hash, in milliseconds.", "1.0.0", "HPEXPIRE key milliseconds [NX|XX|GT|LT] FIELDS numfields field [field ...]",
"O(F) fields",
"differs: same FIELDS error-text deviation as HEXPIRE"),
v("HPEXPIREAT", "hash", -6, W, "Set per-field expiries as absolute Unix-millisecond deadlines.", "1.0.0", "HPEXPIREAT key unix-time-milliseconds [NX|XX|GT|LT] FIELDS numfields field [field ...]",
"O(F) fields",
"differs: same FIELDS error-text deviation as HEXPIRE"),
v("HSCAN", "hash", -3, R, "Iterate a hash's fields and values (single-batch cursor).", "1.0.0", "HSCAN key cursor [MATCH pattern] [COUNT count]",
"O(N) — the whole hash is copied and returned in one batch",
"differs: not a cursor iterator — the cursor is always 0 and the entire hash comes back in a single reply; NOVALUES is not parsed and COUNT is validated then ignored"),
v("HSET", "hash", -4, W, "Set one or more hash fields; returns the number of new fields.", "1.0.0", "HSET key field value [field value ...]",
"O(M) pairs",
"full"),
v("HSETNX", "hash", 4, W, "Set a hash field only if it does not exist.", "1.0.0", "HSETNX key field value",
"O(1)",
"full"),
v("HPTTL", "hash", -5, R, "Return per-field remaining TTLs in milliseconds (-1 no TTL, -2 missing).", "4.0.0", "HPTTL key FIELDS numfields field [field ...]",
"O(F) fields",
"differs: silently accepts a stray NX|XX|GT|LT token before FIELDS where Redis rejects it"),
v("HTTL", "hash", -5, R, "Return per-field remaining TTLs in seconds (-1 no TTL, -2 missing).", "1.0.0", "HTTL key FIELDS numfields field [field ...]",
"O(F) fields",
"differs: silently accepts a stray NX|XX|GT|LT token before FIELDS where Redis rejects it"),
v("HVALS", "hash", 2, R, "Return all values of a hash.", "1.0.0", "HVALS key",
"O(N) fields",
"full"),
v("BLPOP", "list", -3, WB, "Blocking left pop across one or more lists (effect logged as LPOP).", "1.0.0", "BLPOP key [key ...] timeout",
"O(1) to serve; the park is O(1) and waiters are woken FIFO per key",
"differs: on a multi-shard server the multi-key form does not honour Redis's left-to-right key priority — keys on the connection's own shard are served before remote ones"),
v("BRPOP", "list", -3, WB, "Blocking right pop across one or more lists (effect logged as RPOP).", "1.0.0", "BRPOP key [key ...] timeout",
"O(1) to serve; FIFO park",
"differs: same multi-key priority deviation as BLPOP"),
v("BRPOPLPUSH", "list", 4, WB, "Blocking RPOPLPUSH: pop the source tail and push it onto the destination head.", "1.0.0", "BRPOPLPUSH source destination timeout",
"O(1) to serve",
"differs: a cross-shard move is not atomic — the element is popped on the source's shard and pushed on the destination's, and between those two steps it is in neither list. Co-locate the keys with a {hashtag} to get Redis's atomic path"),
v("LINDEX", "list", 3, R, "Return the element at the given list index.", "1.0.0", "LINDEX key index",
"O(1) — the list is a VecDeque, so an index is a direct offset (Redis's quicklist is O(N))",
"full"),
v("LLEN", "list", 2, R, "Return the length of a list.", "1.0.0", "LLEN key",
"O(1)",
"full"),
v("LMOVE", "list", 5, W, "Atomically move an element between two lists.", "1.0.0", "LMOVE source destination LEFT|RIGHT LEFT|RIGHT",
"O(1)",
"differs: a cross-shard move is not atomic — see BRPOPLPUSH"),
v("LPOP", "list", -2, W, "Pop one or more elements from the head of a list.", "1.0.0", "LPOP key [count]",
"O(C) elements popped",
"differs: LPOP key 0 on an existing key replies a nil array where Redis replies an empty array"),
v("LPOS", "list", -3, R, "Return the index of matching elements in a list.", "1.0.0", "LPOS key element [RANK rank] [COUNT num-matches] [MAXLEN len]",
"O(N) always — the whole list is copied before RANK / COUNT / MAXLEN are applied, so MAXLEN bounds the comparisons but not the copy",
"full"),
v("LPUSH", "list", -3, W, "Prepend one or more elements to a list.", "1.0.0", "LPUSH key element [element ...]",
"O(M) values, O(1) amortised each",
"full"),
v("LRANGE", "list", 4, R, "Return a range of list elements.", "1.0.0", "LRANGE key start stop",
"O(M) elements returned — the start offset is skipped in O(1) (Redis is O(S+M))",
"full"),
v("LREM", "list", 4, W, "Remove elements equal to the given value from a list.", "1.0.0", "LREM key count element",
"O(N*R) worst case — the scan is O(N) but each removal shifts up to half the deque (Redis is O(N+R))",
"full"),
v("LINSERT", "list", 5, W, "Insert an element before or after a pivot element.", "1.0.0", "LINSERT key BEFORE|AFTER pivot element",
"O(N) — the pivot is found by a scan from the head",
"full"),
v("LSET", "list", 4, W, "Set the list element at the given index.", "1.0.0", "LSET key index element",
"O(1) — a direct index write (Redis is O(N) for a mid-list index)",
"full"),
v("LTRIM", "list", 4, W, "Trim a list to the given range.", "1.0.0", "LTRIM key start stop",
"O(R) elements removed",
"full"),
v("RPOP", "list", -2, W, "Pop one or more elements from the tail of a list.", "1.0.0", "RPOP key [count]",
"O(C) elements popped",
"differs: RPOP key 0 on an existing key replies a nil array where Redis replies an empty array"),
v("RPOPLPUSH", "list", 3, W, "Pop the source tail and push it onto the destination head.", "1.0.0", "RPOPLPUSH source destination",
"O(1)",
"differs: a cross-shard move is not atomic — see BRPOPLPUSH"),
v("RPUSH", "list", -3, W, "Append one or more elements to a list.", "1.0.0", "RPUSH key element [element ...]",
"O(M) values, O(1) amortised each",
"full"),
v("SADD", "set", -3, W, "Add one or more members to a set.", "1.0.0", "SADD key member [member ...]",
"O(M) members",
"full"),
v("SCARD", "set", 2, R, "Return the number of members in a set.", "1.0.0", "SCARD key",
"O(1)",
"full"),
v("SDIFF", "set", -2, R, "Return the difference of the given sets (cross-shard gather).", "1.0.0", "SDIFF key [key ...]",
"O(sum of the source cardinalities)",
"full"),
v("SDIFFSTORE", "set", -3, W, "Store the difference of the given sets into destination.", "1.0.0", "SDIFFSTORE destination key [key ...]",
"O(sum of the source cardinalities) + O(result) to write the destination on its own shard",
"full"),
v("SINTER", "set", -2, R, "Return the intersection of the given sets (cross-shard gather).", "1.0.0", "SINTER key [key ...]",
"O(sum of the source cardinalities) — there is NO smallest-set-first ordering, so SINTER huge tiny costs O(huge) where Redis costs O(tiny * k)",
"full"),
v("SINTERSTORE", "set", -3, W, "Store the intersection of the given sets into destination.", "1.0.0", "SINTERSTORE destination key [key ...]",
"O(sum of the source cardinalities) + O(result); same no-smallest-first algorithm",
"full"),
v("SISMEMBER", "set", 3, R, "Check whether a value is a member of a set.", "1.0.0", "SISMEMBER key member",
"O(1)",
"full"),
v("SMEMBERS", "set", 2, R, "Return all members of a set.", "1.0.0", "SMEMBERS key",
"O(N) members",
"full"),
v("SPOP", "set", -2, W, "Remove and return one or more random members of a set.", "1.0.0", "SPOP key [count]",
"O(count) expected — each member is drawn by probing a random slot and taking the first occupied one",
"full"),
v("SRANDMEMBER", "set", -2, R, "Return one or more random members of a set without removing them. A negative count allows repeats.", "1.0.0", "SRANDMEMBER key [count]",
"O(count) expected when count is a small fraction of the set (random-slot probing); O(N) once count exceeds a quarter of it, where copying and shuffling beats rejection sampling",
"full"),
v("SREM", "set", -3, W, "Remove one or more members from a set.", "1.0.0", "SREM key member [member ...]",
"O(M) members",
"full"),
v("SSCAN", "set", -3, R, "Iterate a set's members (single-batch cursor).", "1.0.0", "SSCAN key cursor [MATCH pattern] [COUNT count]",
"O(N) — the whole set is copied and returned in one batch",
"differs: not a cursor iterator — the cursor is always 0 and the entire set comes back in one reply; COUNT is validated then ignored"),
v("SUNION", "set", -2, R, "Return the union of the given sets (cross-shard gather).", "1.0.0", "SUNION key [key ...]",
"O(sum of the source cardinalities)",
"full"),
v("SUNIONSTORE", "set", -3, W, "Store the union of the given sets into destination.", "1.0.0", "SUNIONSTORE destination key [key ...]",
"O(sum of the source cardinalities) + O(result)",
"full"),
v("BZPOPMIN", "zset", -3, WB, "Blocking pop of the lowest-scored member across one or more sorted sets.", "1.0.0", "BZPOPMIN key [key ...] timeout",
"O(log N) per pop; the park is O(1)",
"full"),
v("ZADD", "zset", -4, W, "Add members with scores to a sorted set, with conditional flags.", "1.0.0", "ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]",
"O(M log N) — O(1) hash insert plus O(log N) tree insert per member",
"full"),
v("ZCARD", "zset", 2, R, "Return the number of members in a sorted set.", "1.0.0", "ZCARD key",
"O(1)",
"full"),
v("ZCOUNT", "zset", 4, R, "Count members with scores within the given bounds.", "1.0.0", "ZCOUNT key min max",
"O(log N) — two rank descents on the order-statistic tree bracket the score range; nothing is scanned",
"full"),
v("ZDIFFSTORE", "zset", -4, W, "Store the difference of the given sorted sets into destination.", "1.0.0", "ZDIFFSTORE destination numkeys key [key ...]",
"O(sum of the source cardinalities + R log R); each source is extracted whole on its own shard",
"full"),
v("ZINCRBY", "zset", 4, W, "Increment a member's score in a sorted set.", "1.0.0", "ZINCRBY key increment member",
"O(log N)",
"full"),
v("ZINTERCARD", "zset", -3, R, "Return the cardinality of the intersection of the given sorted sets.", "1.0.0", "ZINTERCARD numkeys key [key ...] [LIMIT limit]",
"O(sum of the source cardinalities) — LIMIT does not short-circuit the gather, only the combine",
"full"),
v("ZINTERSTORE", "zset", -4, W, "Store the intersection of the given sorted sets into destination.", "1.0.0", "ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]",
"O(sum of the source cardinalities + R log R)",
"full"),
v("ZPOPMIN", "zset", -2, W, "Pop up to count members with the lowest scores.", "1.0.0", "ZPOPMIN key [count]",
"O(M log N)",
"full"),
v("ZPOPMIN.BELOW", "zset", -3, &["write", "extension"], "kevy extension: pop up to count lowest members with score strictly below the threshold (delayed-job primitive).", "3.0.0", "ZPOPMIN.BELOW key below [count]",
"O(M log N) — take_while stops at the first score at or above the threshold, so it never walks past the due prefix",
"kevy-only: a delayed-job primitive (score = due time); no Redis analogue"),
v("ZRANGE", "zset", -4, R, "Return members by rank range.", "1.0.0", "ZRANGE key start stop [WITHSCORES]",
"O(log N + M) — one rank descent seeks to start, then the M requested members are walked",
"differs: only the legacy 'key start stop [WITHSCORES]' form is accepted — the Redis 6.2 BYSCORE / BYLEX / REV / LIMIT arguments are a syntax error"),
v("ZRANGEBYSCORE", "zset", -4, R, "Return members with scores within the given bounds.", "1.0.0", "ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]",
"O(log N + M) — a rank descent seeks to the score bound, then only the M in-range members are walked; LIMIT is still applied after the match set is materialised, so it bounds the reply, not the walk",
"full"),
v("ZRANK", "zset", 3, R, "Return a member's rank, ordered from the lowest score.", "1.0.0", "ZRANK key member",
"O(log N) — a hash lookup for the score, then one descent of the rank-augmented (score, member) tree",
"differs: the Redis 7.2 WITHSCORE option is not supported"),
v("ZREM", "zset", -3, W, "Remove one or more members from a sorted set.", "1.0.0", "ZREM key member [member ...]",
"O(M log N)",
"full"),
v("ZREMRANGEBYRANK", "zset", 4, W, "Remove members within the given rank range.", "1.0.0", "ZREMRANGEBYRANK key start stop",
"O(log N + M log N) — a rank descent seeks to start, then M member deletes",
"full"),
v("ZREMRANGEBYSCORE", "zset", 4, W, "Remove members with scores within the given bounds.", "1.0.0", "ZREMRANGEBYSCORE key min max",
"O(log N + M log N) — a seek finds the hit set, then M deletes",
"full"),
v("ZREVRANGEBYSCORE", "zset", -4, R, "Return members with scores within the given bounds, highest first.", "1.0.0", "ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]",
"O(log N + M) — a seeked forward walk of the M matches, then the result is reversed",
"full"),
v("ZREVRANGE", "zset", -4, R, "Return members by rank range, highest score first.", "1.0.0", "ZREVRANGE key start stop [WITHSCORES]",
"O(N + M) — the set is read in rank order and reversed, then the M requested members are taken",
"full"),
v("ZSCAN", "zset", -3, R, "Iterate a sorted set's members and scores (single-batch cursor).", "1.0.0", "ZSCAN key cursor [MATCH pattern] [COUNT count]",
"O(N) — the whole set is materialised",
"differs: not a cursor iterator — every call returns the whole set with cursor 0, and COUNT is parsed then ignored"),
v("ZSCORE", "zset", 3, R, "Return a member's score.", "1.0.0", "ZSCORE key member",
"O(1) — a hash lookup",
"full"),
v("ZUNIONSTORE", "zset", -4, W, "Store the union of the given sorted sets into destination.", "1.0.0", "ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]",
"O(sum of the source cardinalities + R log R)",
"full"),
];