use super::Args;
use yo_common::parse_i64;
#[derive(Debug, Clone, Copy)]
pub struct Spec {
pub name: &'static str,
pub arity: i32,
pub flags: &'static [&'static str],
pub first_key: i32,
pub last_key: i32,
pub step: i32,
pub acl: &'static [&'static str],
pub since: &'static str,
pub complexity: &'static str,
pub summary: &'static str,
pub group: &'static str,
}
const AC_TX_FAST: &[&str] = &["@fast", "@transaction"];
const AC_PUBSUB_SLOW: &[&str] = &["@pubsub", "@slow"];
const AC_PUBSUB_FAST: &[&str] = &["@pubsub", "@fast"];
const READ_FAST: &[&str] = &["readonly", "fast"];
const WRITE_FAST_OOM: &[&str] = &["write", "denyoom", "fast"];
const WRITE_OOM: &[&str] = &["write", "denyoom"];
const WRITE_OOM_ADMIN: &[&str] = &["write", "denyoom", "admin"];
const AC_READ_FAST: &[&str] = &["@read", "@string", "@fast"];
const AC_BIT_READ_FAST: &[&str] = &["@read", "@bitmap", "@fast"];
const AC_BIT_READ: &[&str] = &["@read", "@bitmap", "@slow"];
const AC_BIT_WRITE: &[&str] = &["@write", "@bitmap", "@slow"];
const AC_HLL_WRITE_FAST: &[&str] = &["@write", "@hyperloglog", "@fast"];
const AC_HLL_WRITE: &[&str] = &["@write", "@hyperloglog", "@slow"];
const AC_HLL_READ: &[&str] = &["@read", "@hyperloglog", "@slow"];
const AC_HLL_ADMIN: &[&str] = &["@hyperloglog", "@admin", "@slow", "@dangerous"];
const AC_READ_SLOW: &[&str] = &["@read", "@string", "@slow"];
const AC_WRITE_FAST: &[&str] = &["@write", "@string", "@fast"];
const AC_WRITE_SLOW: &[&str] = &["@write", "@string", "@slow"];
const WRITE_FAST: &[&str] = &["write", "fast"];
const AC_SET_READ_FAST: &[&str] = &["@read", "@set", "@fast"];
const AC_SET_READ_SLOW: &[&str] = &["@read", "@set", "@slow"];
const AC_SET_WRITE_FAST: &[&str] = &["@write", "@set", "@fast"];
const AC_SET_WRITE_SLOW: &[&str] = &["@write", "@set", "@slow"];
const AC_HASH_READ_FAST: &[&str] = &["@read", "@hash", "@fast"];
const AC_HASH_READ_SLOW: &[&str] = &["@read", "@hash", "@slow"];
const AC_HASH_WRITE_FAST: &[&str] = &["@write", "@hash", "@fast"];
const AC_HASH_SLOW: &[&str] = &["@hash", "@slow"];
const READ_SLOW: &[&str] = &["readonly"];
const WRITE_SLOW: &[&str] = &["write"];
const AC_LIST_READ_FAST: &[&str] = &["@read", "@list", "@fast"];
const AC_LIST_READ_SLOW: &[&str] = &["@read", "@list", "@slow"];
const AC_LIST_WRITE_FAST: &[&str] = &["@write", "@list", "@fast"];
const AC_LIST_WRITE_SLOW: &[&str] = &["@write", "@list", "@slow"];
const AC_LIST_WRITE_BLOCKING: &[&str] = &["@write", "@list", "@slow", "@blocking"];
const AC_ZSET_READ_FAST: &[&str] = &["@read", "@sortedset", "@fast"];
const AC_ZSET_READ_SLOW: &[&str] = &["@read", "@sortedset", "@slow"];
const AC_ZSET_WRITE_FAST: &[&str] = &["@write", "@sortedset", "@fast"];
const AC_ZSET_WRITE_SLOW: &[&str] = &["@write", "@sortedset", "@slow"];
const AC_ZSET_BLOCKING_FAST: &[&str] = &["@write", "@sortedset", "@fast", "@blocking"];
const AC_ZSET_BLOCKING_SLOW: &[&str] = &["@write", "@sortedset", "@slow", "@blocking"];
const AC_GEO_READ: &[&str] = &["@read", "@geo", "@slow"];
const AC_GEO_WRITE: &[&str] = &["@write", "@geo", "@slow"];
const AC_NONE: &[&str] = &[];
const VECTOR_READ: &[&str] = &["readonly", "module"];
const VECTOR_READ_FAST: &[&str] = &["readonly", "module", "fast"];
const VECTOR_WRITE_OOM: &[&str] = &["write", "denyoom", "module"];
const VECTOR_WRITE: &[&str] = &["write", "module"];
const VECTOR_WRITE_FAST: &[&str] = &["write", "module", "fast"];
const AC_SEARCH: &[&str] = &["@search"];
const AC_SEARCH_DROP: &[&str] = &["@write", "@slow", "@dangerous", "@search"];
const AC_SEARCH_WRITE: &[&str] = &["@write", "@search"];
const AC_SEARCH_LIST: &[&str] = &["@admin", "@slow", "@search"];
const AC_SEARCH_ADMIN: &[&str] = &["@admin", "@search"];
const AC_SEARCH_DEBUG: &[&str] = &["@admin", "@slow", "@dangerous", "@search"];
const AC_SEARCH_TAGS: &[&str] = &["@read", "@slow", "@dangerous", "@search"];
const AC_SEARCH_READ: &[&str] = &["@read", "@search"];
const SEARCH_READ: &[&str] = &["readonly", "module"];
const SEARCH_WRITE_OOM: &[&str] = &["write", "denyoom", "module"];
const SEARCH_WRITE: &[&str] = &["write", "module"];
const AC_JSON_READ: &[&str] = &["@read", "@json"];
const AC_JSON_WRITE: &[&str] = &["@write", "@json"];
const JSON_READ: &[&str] = &["readonly", "module"];
const JSON_WRITE: &[&str] = &["write", "module"];
const JSON_WRITE_OOM: &[&str] = &["write", "denyoom", "module"];
const JSON_READ_MOVABLE: &[&str] = &["readonly", "module", "movablekeys"];
const AC_BLOOM_READ: &[&str] = &["@read", "@bloom"];
const AC_BLOOM_READ_FAST: &[&str] = &["@read", "@fast", "@bloom"];
const AC_BLOOM_WRITE: &[&str] = &["@write", "@bloom"];
const AC_BLOOM_WRITE_FAST: &[&str] = &["@write", "@fast", "@bloom"];
const BLOOM_READ: &[&str] = &["readonly", "module", "fast"];
const BLOOM_WRITE: &[&str] = &["write", "denyoom", "module"];
const AC_CUCKOO_READ: &[&str] = &["@read", "@cuckoo"];
const AC_CUCKOO_READ_FAST: &[&str] = &["@read", "@fast", "@cuckoo"];
const AC_CUCKOO_WRITE: &[&str] = &["@write", "@cuckoo"];
const AC_CUCKOO_WRITE_FAST: &[&str] = &["@write", "@fast", "@cuckoo"];
const CUCKOO_READ: &[&str] = &["readonly", "module", "fast"];
const CUCKOO_WRITE: &[&str] = &["write", "denyoom", "module"];
const CUCKOO_DELETE: &[&str] = &["write", "module", "fast"];
const AC_CMS_READ: &[&str] = &["@read", "@cms"];
const AC_CMS_READ_FAST: &[&str] = &["@read", "@fast", "@cms"];
const AC_CMS_WRITE: &[&str] = &["@write", "@cms"];
const AC_CMS_WRITE_FAST: &[&str] = &["@write", "@fast", "@cms"];
const CMS_READ: &[&str] = &["readonly", "module"];
const CMS_WRITE: &[&str] = &["write", "denyoom", "module"];
const AC_TOPK_READ: &[&str] = &["@read", "@topk"];
const AC_TOPK_READ_FAST: &[&str] = &["@read", "@fast", "@topk"];
const AC_TOPK_WRITE: &[&str] = &["@write", "@topk"];
const AC_TOPK_WRITE_FAST: &[&str] = &["@write", "@fast", "@topk"];
const TOPK_READ: &[&str] = &["readonly", "module"];
const TOPK_WRITE: &[&str] = &["write", "denyoom", "module"];
const AC_TDIGEST_READ_FAST: &[&str] = &["@read", "@fast", "@tdigest"];
const AC_TDIGEST_READ: &[&str] = &["@read", "@tdigest"];
const AC_TDIGEST_WRITE_FAST: &[&str] = &["@write", "@fast", "@tdigest"];
const AC_TDIGEST_WRITE: &[&str] = &["@write", "@tdigest"];
const TDIGEST_READ: &[&str] = &["readonly", "module"];
const TDIGEST_WRITE: &[&str] = &["write", "denyoom", "module"];
const TDIGEST_MERGE: &[&str] = &["write", "denyoom", "module", "movablekeys"];
const AC_TS_READ_FAST: &[&str] = &["@read", "@fast", "@timeseries"];
const AC_TS_WRITE: &[&str] = &["@write", "@timeseries"];
const AC_TS_READ: &[&str] = &["@read", "@timeseries"];
const AC_TS_WRITE_FAST: &[&str] = &["@write", "@fast", "@timeseries"];
const TS_READ: &[&str] = &["readonly", "module"];
const TS_READ_MOVABLE: &[&str] = &["readonly", "module", "movablekeys"];
const TS_WRITE: &[&str] = &["write", "denyoom", "module"];
const TS_DELETE: &[&str] = &["write", "module"];
const TS_RULE: &[&str] = &["write", "module", "fast"];
const AC_GRAPH_READ_FAST: &[&str] = &["@read", "@graph", "@fast"];
const AC_GRAPH_READ_SLOW: &[&str] = &["@read", "@graph", "@slow"];
const AC_GRAPH_WRITE_FAST: &[&str] = &["@write", "@graph", "@fast"];
const AC_ARRAY_READ_FAST: &[&str] = &["@read", "@array", "@fast"];
const AC_ARRAY_READ_SLOW: &[&str] = &["@read", "@array", "@slow"];
const AC_ARRAY_WRITE_FAST: &[&str] = &["@write", "@array", "@fast"];
const AC_ARRAY_WRITE_SLOW: &[&str] = &["@write", "@array", "@slow"];
const AC_STREAM_READ_FAST: &[&str] = &["@read", "@stream", "@fast"];
const AC_STREAM_READ_SLOW: &[&str] = &["@read", "@stream", "@slow"];
const AC_STREAM_WRITE_FAST: &[&str] = &["@write", "@stream", "@fast"];
const AC_STREAM_WRITE_SLOW: &[&str] = &["@write", "@stream", "@slow"];
const AC_STREAM_BLOCKING_READ: &[&str] = &["@read", "@stream", "@slow", "@blocking"];
const AC_STREAM_BLOCKING_WRITE: &[&str] = &["@write", "@stream", "@slow", "@blocking"];
const AC_STREAM_CONTAINER: &[&str] = &["@slow"];
const READ_BLOCKING_MOVABLE: &[&str] = &["readonly", "blocking", "movablekeys"];
const WRITE_BLOCKING_MOVABLE: &[&str] = &["write", "blocking", "movablekeys"];
const READ_MOVABLE: &[&str] = &["readonly", "movablekeys"];
const WRITE_MOVABLE: &[&str] = &["write", "denyoom", "movablekeys"];
const MIGRATE_FLAGS: &[&str] = &["write", "movablekeys"];
const AC_CONN: &[&str] = &["@fast", "@connection"];
const AC_KEY_READ: &[&str] = &["@keyspace", "@read", "@fast"];
const AC_KEY_READ_SLOW: &[&str] = &["@keyspace", "@read", "@slow"];
const AC_KEY_READ_ALL: &[&str] = &["@keyspace", "@read", "@slow", "@dangerous"];
const AC_KEY_WRITE_SLOW: &[&str] = &["@keyspace", "@write", "@slow"];
const AC_KEY_WRITE_FAST: &[&str] = &["@keyspace", "@write", "@fast"];
const AC_KEY_FLUSH: &[&str] = &["@keyspace", "@write", "@slow", "@dangerous"];
const AC_SWAPDB: &[&str] = &["@keyspace", "@write", "@fast", "@dangerous"];
const AC_RESTORE: &[&str] = &["@keyspace", "@write", "@slow", "@dangerous"];
const AC_WAIT: &[&str] = &["@slow", "@blocking", "@connection"];
const AC_SORT_WRITE: &[&str] = &[
"@write",
"@set",
"@sortedset",
"@list",
"@slow",
"@dangerous",
];
const AC_SORT_READ: &[&str] = &[
"@read",
"@set",
"@sortedset",
"@list",
"@slow",
"@dangerous",
];
pub static COMMANDS: &[Spec] = &[
Spec {
name: "set",
arity: -3,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_SLOW,
since: "1.0.0",
complexity: "O(1)",
summary: "Set a key to a string value, whatever it held before.",
group: "string",
},
Spec {
name: "get",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_READ_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "The string value of a key.",
group: "string",
},
Spec {
name: "getset",
arity: 3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Set a key and hand back what it held.",
group: "string",
},
Spec {
name: "getdel",
arity: 2,
flags: &["write", "fast"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "6.2.0",
complexity: "O(1)",
summary: "Read a key and delete it in the same step.",
group: "string",
},
Spec {
name: "getex",
arity: -2,
flags: &["write", "fast"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "6.2.0",
complexity: "O(1)",
summary: "Read a key and change its deadline in the same step.",
group: "string",
},
Spec {
name: "setnx",
arity: 3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Set a key only if it is not there.",
group: "string",
},
Spec {
name: "setex",
arity: 4,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_SLOW,
since: "2.0.0",
complexity: "O(1)",
summary: "Set a key and give it a deadline in seconds.",
group: "string",
},
Spec {
name: "psetex",
arity: 4,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_SLOW,
since: "2.6.0",
complexity: "O(1)",
summary: "Set a key and give it a deadline in milliseconds.",
group: "string",
},
Spec {
name: "mset",
arity: -3,
flags: WRITE_OOM,
first_key: 1,
last_key: -1,
step: 2,
acl: AC_WRITE_SLOW,
since: "1.0.1",
complexity: "O(N) with N the number of keys",
summary: "Set several keys, all of them or none.",
group: "string",
},
Spec {
name: "msetnx",
arity: -3,
flags: WRITE_OOM,
first_key: 1,
last_key: -1,
step: 2,
acl: AC_WRITE_SLOW,
since: "1.0.1",
complexity: "O(N) with N the number of keys",
summary: "Set several keys only if none of them are there.",
group: "string",
},
Spec {
name: "mget",
arity: -2,
flags: READ_FAST,
first_key: 1,
last_key: -1,
step: 1,
acl: AC_READ_FAST,
since: "1.0.0",
complexity: "O(N) with N the number of keys",
summary: "The values of several keys, in the order asked for.",
group: "string",
},
Spec {
name: "append",
arity: 3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "2.0.0",
complexity: "O(M) with M the length of the value being appended",
summary: "Add to the end of a string, creating it if it is not there.",
group: "string",
},
Spec {
name: "strlen",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_READ_FAST,
since: "2.2.0",
complexity: "O(1)",
summary: "How long a string value is, without reading it.",
group: "string",
},
Spec {
name: "setrange",
arity: 4,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_SLOW,
since: "2.2.0",
complexity: "O(M) with M the length of the replacement",
summary: "Overwrite part of a string at an offset, zero filling the gap.",
group: "string",
},
Spec {
name: "getrange",
arity: 4,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_READ_SLOW,
since: "2.4.0",
complexity: "O(N) with N the length of the answer",
summary: "Part of a string, by an inclusive range that may count backwards.",
group: "string",
},
Spec {
name: "substr",
arity: 4,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_READ_SLOW,
since: "1.0.0",
complexity: "O(N) with N the length of the answer",
summary: "GETRANGE under the name it had before 2.4.",
group: "string",
},
Spec {
name: "incr",
arity: 2,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Add one, starting from zero if the key is not there.",
group: "string",
},
Spec {
name: "decr",
arity: 2,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Take one away, starting from zero if the key is not there.",
group: "string",
},
Spec {
name: "incrby",
arity: 3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Add a number, starting from zero if the key is not there.",
group: "string",
},
Spec {
name: "decrby",
arity: 3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Take a number away, starting from zero if the key is not there.",
group: "string",
},
Spec {
name: "incrbyfloat",
arity: 3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "2.6.0",
complexity: "O(1)",
summary: "Add a float, starting from zero if the key is not there.",
group: "string",
},
Spec {
name: "lcs",
arity: -3,
flags: &["readonly"],
first_key: 1,
last_key: 2,
step: 1,
acl: AC_READ_SLOW,
since: "7.0.0",
complexity: "O(N*M) with N and M the lengths of the two values",
summary: "The longest subsequence two string values have in common.",
group: "string",
},
Spec {
name: "msetex",
arity: -4,
flags: &["write", "denyoom", "movablekeys"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_WRITE_SLOW,
since: "8.4.0",
complexity: "O(N) with N the number of keys",
summary: "Set several keys with one deadline and one condition over all of them.",
group: "string",
},
Spec {
name: "delex",
arity: -2,
flags: &["write", "fast"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "8.4.0",
complexity: "O(1) by value, O(N) by digest",
summary: "Delete a key only if it still holds what the caller thinks.",
group: "string",
},
Spec {
name: "digest",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_READ_FAST,
since: "8.4.0",
complexity: "O(N) with N the length of the value",
summary: "The XXH3 of a string value, as sixteen hex characters.",
group: "string",
},
Spec {
name: "increx",
arity: -2,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_WRITE_FAST,
since: "8.8.0",
complexity: "O(1)",
summary: "Count, with a bound, a saturation policy and a deadline.",
group: "string",
},
Spec {
name: "setbit",
arity: 4,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BIT_WRITE,
since: "2.2.0",
complexity: "O(1)",
summary: "Set one bit of a string, growing it to reach the offset.",
group: "bitmap",
},
Spec {
name: "getbit",
arity: 3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BIT_READ_FAST,
since: "2.2.0",
complexity: "O(1)",
summary: "Read one bit of a string, or nought past its end.",
group: "bitmap",
},
Spec {
name: "bitcount",
arity: -2,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BIT_READ,
since: "2.6.0",
complexity: "O(N)",
summary: "Count the set bits of a string, or of a range of it.",
group: "bitmap",
},
Spec {
name: "bitpos",
arity: -3,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BIT_READ,
since: "2.8.7",
complexity: "O(N)",
summary: "Find the first bit set to one or nought in a string.",
group: "bitmap",
},
Spec {
name: "bitop",
arity: -4,
flags: WRITE_OOM,
first_key: 2,
last_key: -1,
step: 1,
acl: AC_BIT_WRITE,
since: "2.6.0",
complexity: "O(N) with N the length of the longest source",
summary: "Combine strings bit by bit and store the result.",
group: "bitmap",
},
Spec {
name: "bitfield",
arity: -2,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BIT_WRITE,
since: "3.2.0",
complexity: "O(1) per subcommand",
summary: "Read and write packed integer fields inside a string.",
group: "bitmap",
},
Spec {
name: "bitfield_ro",
arity: -2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BIT_READ_FAST,
since: "6.0.0",
complexity: "O(1) per subcommand",
summary: "The read only half of BITFIELD, for a replica to answer.",
group: "bitmap",
},
Spec {
name: "pfadd",
arity: -2,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HLL_WRITE_FAST,
since: "2.8.9",
complexity: "O(1) an element",
summary: "Add elements to a sketch, answering whether it changed.",
group: "hyperloglog",
},
Spec {
name: "pfcount",
arity: -2,
flags: &["readonly"],
first_key: 1,
last_key: -1,
step: 1,
acl: AC_HLL_READ,
since: "2.8.9",
complexity: "O(1) for one key, O(N) for N of them",
summary: "Estimate how many distinct elements the sketches hold.",
group: "hyperloglog",
},
Spec {
name: "pfmerge",
arity: -2,
flags: WRITE_OOM,
first_key: 1,
last_key: -1,
step: 1,
acl: AC_HLL_WRITE,
since: "2.8.9",
complexity: "O(N) in the number of sketches",
summary: "Merge sketches into the first one, which is a union.",
group: "hyperloglog",
},
Spec {
name: "pfdebug",
arity: 3,
flags: WRITE_OOM_ADMIN,
first_key: 2,
last_key: 2,
step: 1,
acl: AC_HLL_ADMIN,
since: "2.8.9",
complexity: "O(N)",
summary: "Look inside a sketch, and in one case convert it.",
group: "hyperloglog",
},
Spec {
name: "pfselftest",
arity: 1,
flags: &["admin"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_HLL_ADMIN,
since: "2.8.9",
complexity: "O(1)",
summary: "Check the sketch code, which our tests do at build time.",
group: "hyperloglog",
},
Spec {
name: "sadd",
arity: -3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SET_WRITE_FAST,
since: "1.0.0",
complexity: "O(N) with N the number of members being added",
summary: "Add members to a set, creating it if it is not there.",
group: "set",
},
Spec {
name: "srem",
arity: -3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SET_WRITE_FAST,
since: "1.0.0",
complexity: "O(N) with N the number of members being removed",
summary: "Take members out of a set, deleting the key if none are left.",
group: "set",
},
Spec {
name: "scard",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SET_READ_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "How many members a set has.",
group: "set",
},
Spec {
name: "sismember",
arity: 3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SET_READ_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Whether a member is in a set.",
group: "set",
},
Spec {
name: "smismember",
arity: -3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SET_READ_FAST,
since: "6.2.0",
complexity: "O(N) with N the number of members being asked about",
summary: "Whether each of several members is in a set, in the order asked.",
group: "set",
},
Spec {
name: "smembers",
arity: 2,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SET_READ_SLOW,
since: "1.0.0",
complexity: "O(N) with N the size of the set",
summary: "Every member of a set.",
group: "set",
},
Spec {
name: "spop",
arity: -2,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SET_WRITE_FAST,
since: "1.0.0",
complexity: "O(1) without a count, O(N) with one",
summary: "Take members out of a set at random and hand them back.",
group: "set",
},
Spec {
name: "srandmember",
arity: -2,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SET_READ_SLOW,
since: "1.0.0",
complexity: "O(1) without a count, O(N) with one",
summary: "Members of a set at random, leaving the set as it was.",
group: "set",
},
Spec {
name: "smove",
arity: 4,
flags: WRITE_FAST,
first_key: 1,
last_key: 2,
step: 1,
acl: AC_SET_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Move one member from one set to another.",
group: "set",
},
Spec {
name: "sscan",
arity: -3,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SET_READ_SLOW,
since: "2.8.0",
complexity: "O(1) a call, O(N) for a whole iteration",
summary: "Walk part of a set and say where to carry on from.",
group: "set",
},
Spec {
name: "sinter",
arity: -2,
flags: &["readonly"],
first_key: 1,
last_key: -1,
step: 1,
acl: AC_SET_READ_SLOW,
since: "1.0.0",
complexity: "O(N*M) worst case, N the smallest set and M the number of sets",
summary: "The members every one of these sets has.",
group: "set",
},
Spec {
name: "sintercard",
arity: -3,
flags: READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SET_READ_SLOW,
since: "7.0.0",
complexity: "O(N*M) worst case, N the smallest set and M the number of sets",
summary: "How many members every one of these sets has, up to a limit.",
group: "set",
},
Spec {
name: "sinterstore",
arity: -3,
flags: WRITE_OOM,
first_key: 1,
last_key: -1,
step: 1,
acl: AC_SET_WRITE_SLOW,
since: "1.0.0",
complexity: "O(N*M) worst case, N the smallest set and M the number of sets",
summary: "Store the members every one of these sets has.",
group: "set",
},
Spec {
name: "sunion",
arity: -2,
flags: &["readonly"],
first_key: 1,
last_key: -1,
step: 1,
acl: AC_SET_READ_SLOW,
since: "1.0.0",
complexity: "O(N) in the total number of members",
summary: "The members any of these sets has, each once.",
group: "set",
},
Spec {
name: "sunionstore",
arity: -3,
flags: WRITE_OOM,
first_key: 1,
last_key: -1,
step: 1,
acl: AC_SET_WRITE_SLOW,
since: "1.0.0",
complexity: "O(N) in the total number of members",
summary: "Store the members any of these sets has.",
group: "set",
},
Spec {
name: "sdiff",
arity: -2,
flags: &["readonly"],
first_key: 1,
last_key: -1,
step: 1,
acl: AC_SET_READ_SLOW,
since: "1.0.0",
complexity: "O(N) in the total number of members",
summary: "The members of the first set that no later set has.",
group: "set",
},
Spec {
name: "sdiffstore",
arity: -3,
flags: WRITE_OOM,
first_key: 1,
last_key: -1,
step: 1,
acl: AC_SET_WRITE_SLOW,
since: "1.0.0",
complexity: "O(N) in the total number of members",
summary: "Store the members of the first set that no later set has.",
group: "set",
},
Spec {
name: "sunioncard",
arity: -3,
flags: READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SET_READ_SLOW,
since: "8.10.0",
complexity: "O(N) in the total number of members",
summary: "How many members any of these sets has, up to a limit.",
group: "set",
},
Spec {
name: "sdiffcard",
arity: -3,
flags: READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SET_READ_SLOW,
since: "8.10.0",
complexity: "O(N) in the total number of members",
summary: "How many members the first set has that no later set has, up to a limit.",
group: "set",
},
Spec {
name: "hset",
arity: -4,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "2.0.0",
complexity: "O(N) with N the number of pairs being written",
summary: "Write fields into a hash, creating it if it is not there.",
group: "hash",
},
Spec {
name: "hsetnx",
arity: 4,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "Write a field only if the hash does not have it already.",
group: "hash",
},
Spec {
name: "hmset",
arity: -4,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "2.0.0",
complexity: "O(N) with N the number of pairs being written",
summary: "Write fields into a hash and answer OK. Use HSET.",
group: "hash",
},
Spec {
name: "hget",
arity: 3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "The value of one field of a hash.",
group: "hash",
},
Spec {
name: "hmget",
arity: -3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_FAST,
since: "2.0.0",
complexity: "O(N) with N the number of fields asked for",
summary: "The values of several fields, one reply entry each.",
group: "hash",
},
Spec {
name: "hdel",
arity: -3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "2.0.0",
complexity: "O(N) with N the number of fields being removed",
summary: "Take fields out of a hash, deleting the key if none are left.",
group: "hash",
},
Spec {
name: "hlen",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "How many fields a hash has.",
group: "hash",
},
Spec {
name: "hexists",
arity: 3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "Whether a hash has a field.",
group: "hash",
},
Spec {
name: "hstrlen",
arity: 3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_FAST,
since: "3.2.0",
complexity: "O(1)",
summary: "How many bytes a field's value is, without sending it.",
group: "hash",
},
Spec {
name: "hgetall",
arity: 2,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_SLOW,
since: "2.0.0",
complexity: "O(N) in the size of the hash",
summary: "Every field and value, as a map on RESP3.",
group: "hash",
},
Spec {
name: "hkeys",
arity: 2,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_SLOW,
since: "2.0.0",
complexity: "O(N) in the size of the hash",
summary: "Every field of a hash.",
group: "hash",
},
Spec {
name: "hvals",
arity: 2,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_SLOW,
since: "2.0.0",
complexity: "O(N) in the size of the hash",
summary: "Every value of a hash.",
group: "hash",
},
Spec {
name: "hincrby",
arity: 4,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "Add an integer to a field, treating a missing one as zero.",
group: "hash",
},
Spec {
name: "hincrbyfloat",
arity: 4,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "2.6.0",
complexity: "O(1)",
summary: "Add a float to a field, treating a missing one as zero.",
group: "hash",
},
Spec {
name: "hrandfield",
arity: -2,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_SLOW,
since: "6.2.0",
complexity: "O(1) without a count, O(N) with one",
summary: "Fields of a hash at random, leaving the hash as it was.",
group: "hash",
},
Spec {
name: "hscan",
arity: -3,
flags: &["readonly"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_SLOW,
since: "2.8.0",
complexity: "O(1) a call, O(N) for a whole iteration",
summary: "Walk part of a hash and say where to carry on from.",
group: "hash",
},
Spec {
name: "hexpire",
arity: -6,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "7.4.0",
complexity: "O(N) with N the number of fields named",
summary: "Put a deadline in seconds on hash fields.",
group: "hash",
},
Spec {
name: "hpexpire",
arity: -6,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "7.4.0",
complexity: "O(N) with N the number of fields named",
summary: "Put a deadline in milliseconds on hash fields.",
group: "hash",
},
Spec {
name: "hexpireat",
arity: -6,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "7.4.0",
complexity: "O(N) with N the number of fields named",
summary: "Put an absolute deadline in unix seconds on hash fields.",
group: "hash",
},
Spec {
name: "hpexpireat",
arity: -6,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "7.4.0",
complexity: "O(N) with N the number of fields named",
summary: "Put an absolute deadline in unix milliseconds on hash fields.",
group: "hash",
},
Spec {
name: "httl",
arity: -5,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_FAST,
since: "7.4.0",
complexity: "O(N) with N the number of fields named",
summary: "How long hash fields have left, in seconds.",
group: "hash",
},
Spec {
name: "hpttl",
arity: -5,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_FAST,
since: "7.4.0",
complexity: "O(N) with N the number of fields named",
summary: "How long hash fields have left, in milliseconds.",
group: "hash",
},
Spec {
name: "hexpiretime",
arity: -5,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_FAST,
since: "7.4.0",
complexity: "O(N) with N the number of fields named",
summary: "When hash fields fall due, in unix seconds.",
group: "hash",
},
Spec {
name: "hpexpiretime",
arity: -5,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_READ_FAST,
since: "7.4.0",
complexity: "O(N) with N the number of fields named",
summary: "When hash fields fall due, in unix milliseconds.",
group: "hash",
},
Spec {
name: "hpersist",
arity: -5,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "7.4.0",
complexity: "O(N) with N the number of fields named",
summary: "Take the deadlines off hash fields.",
group: "hash",
},
Spec {
name: "hgetdel",
arity: -5,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "8.0.0",
complexity: "O(N) with N the number of fields named",
summary: "Read hash fields and delete them.",
group: "hash",
},
Spec {
name: "hgetex",
arity: -5,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "8.0.0",
complexity: "O(N) with N the number of fields named",
summary: "Read hash fields and set their deadlines.",
group: "hash",
},
Spec {
name: "hsetex",
arity: -6,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_HASH_WRITE_FAST,
since: "8.0.0",
complexity: "O(N) with N the number of fields being set",
summary: "Set hash fields and their deadlines together.",
group: "hash",
},
Spec {
name: "himport",
arity: -2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_HASH_SLOW,
since: "8.10.0",
complexity: "Depends on subcommand.",
summary: "A container for session-based hash import commands using fieldsets.",
group: "hash",
},
Spec {
name: "lpush",
arity: -3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_FAST,
since: "1.0.0",
complexity: "O(N) with N the number of elements pushed",
summary: "Push elements onto the head of a list.",
group: "list",
},
Spec {
name: "rpush",
arity: -3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_FAST,
since: "1.0.0",
complexity: "O(N) with N the number of elements pushed",
summary: "Push elements onto the tail of a list.",
group: "list",
},
Spec {
name: "lpushx",
arity: -3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_FAST,
since: "2.2.0",
complexity: "O(N) with N the number of elements pushed",
summary: "Push elements onto the head of a list that already exists.",
group: "list",
},
Spec {
name: "rpushx",
arity: -3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_FAST,
since: "2.2.0",
complexity: "O(N) with N the number of elements pushed",
summary: "Push elements onto the tail of a list that already exists.",
group: "list",
},
Spec {
name: "lpop",
arity: -2,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_FAST,
since: "1.0.0",
complexity: "O(N) with N the count asked for",
summary: "Take elements off the head of a list.",
group: "list",
},
Spec {
name: "rpop",
arity: -2,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_FAST,
since: "1.0.0",
complexity: "O(N) with N the count asked for",
summary: "Take elements off the tail of a list.",
group: "list",
},
Spec {
name: "llen",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_READ_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "How many elements a list holds.",
group: "list",
},
Spec {
name: "lrange",
arity: 4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_READ_SLOW,
since: "1.0.0",
complexity: "O(S+N) with S the offset of the first element and N the range",
summary: "Read a range of a list, both ends included.",
group: "list",
},
Spec {
name: "lindex",
arity: 3,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_READ_SLOW,
since: "1.0.0",
complexity: "O(N) with N the distance to the index from the nearer end",
summary: "Read one element of a list by index.",
group: "list",
},
Spec {
name: "lset",
arity: 4,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_SLOW,
since: "1.0.0",
complexity: "O(N) with N the distance to the index from the nearer end",
summary: "Replace one element of a list by index.",
group: "list",
},
Spec {
name: "linsert",
arity: 5,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_SLOW,
since: "2.2.0",
complexity: "O(N) with N the distance to the pivot from the head",
summary: "Insert an element before or after another one.",
group: "list",
},
Spec {
name: "lrem",
arity: 4,
flags: WRITE_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_SLOW,
since: "1.0.0",
complexity: "O(N) with N the length of the list",
summary: "Remove elements equal to a value from a list.",
group: "list",
},
Spec {
name: "ltrim",
arity: 4,
flags: WRITE_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_WRITE_SLOW,
since: "1.0.0",
complexity: "O(N) with N the number of elements thrown away",
summary: "Keep a range of a list and throw the rest away.",
group: "list",
},
Spec {
name: "lpos",
arity: -3,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_LIST_READ_SLOW,
since: "6.0.6",
complexity: "O(N) with N the length of the list",
summary: "Find where a value sits in a list.",
group: "list",
},
Spec {
name: "rpoplpush",
arity: 3,
flags: WRITE_OOM,
first_key: 1,
last_key: 2,
step: 1,
acl: AC_LIST_WRITE_SLOW,
since: "1.2.0",
complexity: "O(1)",
summary: "Move an element from the tail of one list to the head of another.",
group: "list",
},
Spec {
name: "lmove",
arity: 5,
flags: WRITE_OOM,
first_key: 1,
last_key: 2,
step: 1,
acl: AC_LIST_WRITE_SLOW,
since: "6.2.0",
complexity: "O(1)",
summary: "Move an element from either end of one list to either end of another.",
group: "list",
},
Spec {
name: "lmovem",
arity: -5,
flags: WRITE_OOM,
first_key: 1,
last_key: 2,
step: 1,
acl: AC_LIST_WRITE_SLOW,
since: "8.10.0",
complexity: "O(N) in the number of elements moved",
summary: "Move several elements from either end of one list to either end of another.",
group: "list",
},
Spec {
name: "lmpop",
arity: -4,
flags: &["write", "movablekeys"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_LIST_WRITE_SLOW,
since: "7.0.0",
complexity: "O(N+M) with N the number of keys and M the count popped",
summary: "Pop from the first of several lists that has anything in it.",
group: "list",
},
Spec {
name: "blpop",
arity: -3,
flags: &["write", "blocking"],
first_key: 1,
last_key: -2,
step: 1,
acl: AC_LIST_WRITE_BLOCKING,
since: "2.0.0",
complexity: "O(N) with N the number of keys named",
summary: "Pop the head of the first list that has anything, waiting if none does.",
group: "list",
},
Spec {
name: "brpop",
arity: -3,
flags: &["write", "blocking"],
first_key: 1,
last_key: -2,
step: 1,
acl: AC_LIST_WRITE_BLOCKING,
since: "2.0.0",
complexity: "O(N) with N the number of keys named",
summary: "Pop the tail of the first list that has anything, waiting if none does.",
group: "list",
},
Spec {
name: "blmove",
arity: 6,
flags: &["write", "denyoom", "blocking"],
first_key: 1,
last_key: 2,
step: 1,
acl: AC_LIST_WRITE_BLOCKING,
since: "6.2.0",
complexity: "O(1)",
summary: "Move an element between two lists, waiting for one to arrive.",
group: "list",
},
Spec {
name: "blmovem",
arity: -6,
flags: &["write", "denyoom", "blocking"],
first_key: 1,
last_key: 2,
step: 1,
acl: AC_LIST_WRITE_BLOCKING,
since: "8.10.0",
complexity: "O(N) in the number of elements moved",
summary: "Move several elements between two lists, waiting for them to arrive.",
group: "list",
},
Spec {
name: "brpoplpush",
arity: 4,
flags: &["write", "denyoom", "blocking"],
first_key: 1,
last_key: 2,
step: 1,
acl: AC_LIST_WRITE_BLOCKING,
since: "2.2.0",
complexity: "O(1)",
summary: "Move a tail element to another list's head, waiting for one to arrive.",
group: "list",
},
Spec {
name: "blmpop",
arity: -5,
flags: &["write", "blocking", "movablekeys"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_LIST_WRITE_BLOCKING,
since: "7.0.0",
complexity: "O(N+M) with N the number of keys and M the count popped",
summary: "Pop from the first of several lists that has anything, waiting if none does.",
group: "list",
},
Spec {
name: "zadd",
arity: -4,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_FAST,
since: "1.2.0",
complexity: "O(log(N)) for each member added",
summary: "Add members with scores, or move the scores of members already there.",
group: "zset",
},
Spec {
name: "zincrby",
arity: 4,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_FAST,
since: "1.2.0",
complexity: "O(log(N))",
summary: "Add to a member's score, creating the member at zero if it is not there.",
group: "zset",
},
Spec {
name: "zcard",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_FAST,
since: "1.2.0",
complexity: "O(1)",
summary: "How many members a sorted set has.",
group: "zset",
},
Spec {
name: "zscore",
arity: 3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_FAST,
since: "1.2.0",
complexity: "O(1)",
summary: "A member's score, or nothing if it is not there.",
group: "zset",
},
Spec {
name: "zmscore",
arity: -3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_FAST,
since: "6.2.0",
complexity: "O(N) with N the number of members asked about",
summary: "The scores of several members in one round trip.",
group: "zset",
},
Spec {
name: "zrem",
arity: -3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_FAST,
since: "1.2.0",
complexity: "O(M*log(N)) with M the number of members removed",
summary: "Remove members, deleting the key if the last one goes.",
group: "zset",
},
Spec {
name: "zrank",
arity: -3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_FAST,
since: "2.0.0",
complexity: "O(log(N))",
summary: "Where a member sits counting up from the lowest score.",
group: "zset",
},
Spec {
name: "zrevrank",
arity: -3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_FAST,
since: "2.0.0",
complexity: "O(log(N))",
summary: "Where a member sits counting down from the highest score.",
group: "zset",
},
Spec {
name: "zcount",
arity: 4,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_FAST,
since: "2.0.0",
complexity: "O(log(N))",
summary: "How many members have scores between two bounds.",
group: "zset",
},
Spec {
name: "zlexcount",
arity: 4,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_FAST,
since: "2.8.9",
complexity: "O(log(N))",
summary: "How many members fall between two members, by name.",
group: "zset",
},
Spec {
name: "zrange",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_SLOW,
since: "1.2.0",
complexity: "O(log(N)+M) with M the number of members answered",
summary: "A window of members, by rank or by score or by name, either way round.",
group: "zset",
},
Spec {
name: "zrevrange",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_SLOW,
since: "1.2.0",
complexity: "O(log(N)+M) with M the number of members answered",
summary: "A window by rank, counting down from the highest score.",
group: "zset",
},
Spec {
name: "zrangebyscore",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_SLOW,
since: "1.0.5",
complexity: "O(log(N)+M) with M the number of members answered",
summary: "The members whose scores fall between two bounds.",
group: "zset",
},
Spec {
name: "zrevrangebyscore",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_SLOW,
since: "2.2.0",
complexity: "O(log(N)+M) with M the number of members answered",
summary: "The same window as ZRANGEBYSCORE, highest score first and named high end first.",
group: "zset",
},
Spec {
name: "zrangebylex",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_SLOW,
since: "2.8.9",
complexity: "O(log(N)+M) with M the number of members answered",
summary: "The members that fall between two names, for a set where every score is the same.",
group: "zset",
},
Spec {
name: "zrevrangebylex",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_SLOW,
since: "2.8.9",
complexity: "O(log(N)+M) with M the number of members answered",
summary: "The same window as ZRANGEBYLEX, backwards and named high end first.",
group: "zset",
},
Spec {
name: "zrangestore",
arity: -5,
flags: WRITE_OOM,
first_key: 1,
last_key: 2,
step: 1,
acl: AC_ZSET_WRITE_SLOW,
since: "6.2.0",
complexity: "O(log(N)+M) with M the number of members stored",
summary: "Write a window of one sorted set into another key.",
group: "zset",
},
Spec {
name: "zremrangebyrank",
arity: 4,
flags: WRITE_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_SLOW,
since: "2.0.0",
complexity: "O(log(N)+M) with M the number of members removed",
summary: "Remove the members in a range of ranks.",
group: "zset",
},
Spec {
name: "zremrangebyscore",
arity: 4,
flags: WRITE_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_SLOW,
since: "1.2.0",
complexity: "O(log(N)+M) with M the number of members removed",
summary: "Remove the members whose scores fall between two bounds.",
group: "zset",
},
Spec {
name: "zremrangebylex",
arity: 4,
flags: WRITE_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_SLOW,
since: "2.8.9",
complexity: "O(log(N)+M) with M the number of members removed",
summary: "Remove the members that fall between two names.",
group: "zset",
},
Spec {
name: "zunion",
arity: -3,
flags: READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_ZSET_READ_SLOW,
since: "6.2.0",
complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
summary: "Every member of these sorted sets, with the scores combined.",
group: "zset",
},
Spec {
name: "zinter",
arity: -3,
flags: READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_ZSET_READ_SLOW,
since: "6.2.0",
complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
summary: "Only the members all of these sorted sets have, with the scores combined.",
group: "zset",
},
Spec {
name: "zdiff",
arity: -3,
flags: READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_ZSET_READ_SLOW,
since: "6.2.0",
complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
summary: "The members of the first that none of the rest have.",
group: "zset",
},
Spec {
name: "zunionstore",
arity: -4,
flags: WRITE_MOVABLE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_SLOW,
since: "2.0.0",
complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
summary: "Store the union in another key and say how big it is.",
group: "zset",
},
Spec {
name: "zinterstore",
arity: -4,
flags: WRITE_MOVABLE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_SLOW,
since: "2.0.0",
complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
summary: "Store the intersection in another key and say how big it is.",
group: "zset",
},
Spec {
name: "zdiffstore",
arity: -4,
flags: WRITE_MOVABLE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_SLOW,
since: "6.2.0",
complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
summary: "Store the difference in another key and say how big it is.",
group: "zset",
},
Spec {
name: "zintercard",
arity: -3,
flags: READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_ZSET_READ_SLOW,
since: "7.0.0",
complexity: "O(N*M) worst case, N the smallest input and M the number of inputs",
summary: "How many members the intersection would have, without building it.",
group: "zset",
},
Spec {
name: "zrandmember",
arity: -2,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_SLOW,
since: "6.2.0",
complexity: "O(N) with N the number of members drawn",
summary: "Draw members at random, with or without replacement.",
group: "zset",
},
Spec {
name: "zscan",
arity: -3,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_READ_SLOW,
since: "2.8.0",
complexity: "O(1) per call, O(N) over a full walk",
summary: "Walk the members and their scores a batch at a time.",
group: "zset",
},
Spec {
name: "zpopmin",
arity: -2,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_FAST,
since: "5.0.0",
complexity: "O(log(N)*M) with M the number of members popped",
summary: "Take the lowest scoring members off and answer them.",
group: "zset",
},
Spec {
name: "zpopmax",
arity: -2,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ZSET_WRITE_FAST,
since: "5.0.0",
complexity: "O(log(N)*M) with M the number of members popped",
summary: "Take the highest scoring members off and answer them.",
group: "zset",
},
Spec {
name: "zmpop",
arity: -4,
flags: &["write", "movablekeys"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_ZSET_WRITE_SLOW,
since: "7.0.0",
complexity: "O(K) + O(M*log(N)) with K the keys named and M the count popped",
summary: "Pop from the first of several sorted sets that has anything in it.",
group: "zset",
},
Spec {
name: "bzpopmin",
arity: -3,
flags: &["write", "blocking", "fast"],
first_key: 1,
last_key: -2,
step: 1,
acl: AC_ZSET_BLOCKING_FAST,
since: "5.0.0",
complexity: "O(log(N)) with N the size of the sorted set that answers",
summary: "Take the lowest scoring member off the first sorted set that has one, waiting if none does.",
group: "zset",
},
Spec {
name: "bzpopmax",
arity: -3,
flags: &["write", "blocking", "fast"],
first_key: 1,
last_key: -2,
step: 1,
acl: AC_ZSET_BLOCKING_FAST,
since: "5.0.0",
complexity: "O(log(N)) with N the size of the sorted set that answers",
summary: "Take the highest scoring member off the first sorted set that has one, waiting if none does.",
group: "zset",
},
Spec {
name: "bzmpop",
arity: -5,
flags: &["write", "blocking", "movablekeys"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_ZSET_BLOCKING_SLOW,
since: "7.0.0",
complexity: "O(K) + O(M*log(N)) with K the keys named and M the count popped",
summary: "Pop from the first of several sorted sets that has anything, waiting if none does.",
group: "zset",
},
Spec {
name: "geoadd",
arity: -5,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GEO_WRITE,
since: "3.2.0",
complexity: "O(log(N)) per point added",
summary: "Add places to a geo key, which is a sorted set of position hashes.",
group: "geo",
},
Spec {
name: "geopos",
arity: -2,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GEO_READ,
since: "3.2.0",
complexity: "O(1) per member asked about",
summary: "Answer where each member is, as a longitude and a latitude.",
group: "geo",
},
Spec {
name: "geodist",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GEO_READ,
since: "3.2.0",
complexity: "O(1)",
summary: "Answer how far apart two members are, in the unit asked for.",
group: "geo",
},
Spec {
name: "geohash",
arity: -2,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GEO_READ,
since: "3.2.0",
complexity: "O(1) per member asked about",
summary: "Answer each member's position as a standard eleven character geohash.",
group: "geo",
},
Spec {
name: "geosearch",
arity: -7,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GEO_READ,
since: "6.2.0",
complexity: "O(N+log(M)) with N the members in the boxes searched",
summary: "Find the members inside a circle or a rectangle around a point.",
group: "geo",
},
Spec {
name: "geosearchstore",
arity: -8,
flags: WRITE_OOM,
first_key: 1,
last_key: 2,
step: 1,
acl: AC_GEO_WRITE,
since: "6.2.0",
complexity: "O(N+log(M)) with N the members in the boxes searched",
summary: "Run a search and write what it found into another key.",
group: "geo",
},
Spec {
name: "georadius",
arity: -6,
flags: WRITE_MOVABLE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GEO_WRITE,
since: "3.2.0",
complexity: "O(N+log(M)) with N the members in the boxes searched",
summary: "The older spelling of a circular search, which can also store.",
group: "geo",
},
Spec {
name: "georadius_ro",
arity: -6,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GEO_READ,
since: "3.2.10",
complexity: "O(N+log(M)) with N the members in the boxes searched",
summary: "GEORADIUS without the store options, so a replica can serve it.",
group: "geo",
},
Spec {
name: "georadiusbymember",
arity: -5,
flags: WRITE_MOVABLE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GEO_WRITE,
since: "3.2.0",
complexity: "O(N+log(M)) with N the members in the boxes searched",
summary: "The same search centred on a member rather than on a point.",
group: "geo",
},
Spec {
name: "georadiusbymember_ro",
arity: -5,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GEO_READ,
since: "3.2.10",
complexity: "O(N+log(M)) with N the members in the boxes searched",
summary: "GEORADIUSBYMEMBER without the store options.",
group: "geo",
},
Spec {
name: "g.nadd",
arity: -3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_WRITE_FAST,
since: "8.8.0",
complexity: "O(N) with N the fields written",
summary: "Write a node and its properties, creating it if it is new.",
group: "graph",
},
Spec {
name: "g.nget",
arity: 3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_READ_FAST,
since: "8.8.0",
complexity: "O(N) with N the fields on the node",
summary: "Every property on a node.",
group: "graph",
},
Spec {
name: "g.ndel",
arity: 3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_WRITE_FAST,
since: "8.8.0",
complexity: "O(E) with E the edges on the node",
summary: "Delete a node and every edge that touches it.",
group: "graph",
},
Spec {
name: "g.eadd",
arity: -5,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_WRITE_FAST,
since: "8.8.0",
complexity: "O(D) with D the outgoing degree under the label",
summary: "Write an edge and its properties, creating either end if it is new.",
group: "graph",
},
Spec {
name: "g.edel",
arity: 5,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_WRITE_FAST,
since: "8.8.0",
complexity: "O(D) with D the outgoing degree under the label",
summary: "Delete one edge between two nodes under a label.",
group: "graph",
},
Spec {
name: "g.out",
arity: -4,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_READ_FAST,
since: "8.8.0",
complexity: "O(N) with N the page asked for",
summary: "Outgoing neighbours under a label, a page at a time.",
group: "graph",
},
Spec {
name: "g.in",
arity: -4,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_READ_FAST,
since: "8.8.0",
complexity: "O(N) with N the page asked for",
summary: "Incoming neighbours under a label, a page at a time.",
group: "graph",
},
Spec {
name: "g.deg",
arity: -4,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_READ_FAST,
since: "8.8.0",
complexity: "O(1)",
summary: "How many edges a node has under a label.",
group: "graph",
},
Spec {
name: "g.neigh",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_READ_SLOW,
since: "8.8.0",
complexity: "O(V + E) over the ball the depth reaches",
summary: "Everything reachable within a depth, each node once.",
group: "graph",
},
Spec {
name: "g.path",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_GRAPH_READ_SLOW,
since: "8.8.0",
complexity: "O(b^(d/2)) with b the branching factor and d the distance",
summary: "A shortest path between two nodes, searched from both ends.",
group: "graph",
},
Spec {
name: "json.set",
arity: -4,
flags: JSON_WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Set the value at a path, creating the document at the root.",
group: "json",
},
Spec {
name: "json.mset",
arity: -4,
flags: JSON_WRITE_OOM,
first_key: 1,
last_key: -1,
step: 3,
acl: AC_JSON_WRITE,
since: "2.6.0",
complexity: "O(K*N) with K the keys and N the size of each document",
summary: "Set the value at a path in each of several documents.",
group: "json",
},
Spec {
name: "json.merge",
arity: -4,
flags: JSON_WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "2.6.0",
complexity: "O(N) with N the size of the document",
summary: "Apply an RFC 7386 merge patch at a path.",
group: "json",
},
Spec {
name: "json.get",
arity: -2,
flags: JSON_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(N) with N the size of what the paths matched",
summary: "The values one or more paths match, as JSON text.",
group: "json",
},
Spec {
name: "json.mget",
arity: -3,
flags: JSON_READ,
first_key: 1,
last_key: -2,
step: 1,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(K*N) with K the keys and N the size of each document",
summary: "One path against several documents, one answer per key.",
group: "json",
},
Spec {
name: "json.del",
arity: -2,
flags: JSON_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Remove what a path matched, or the key when it is the root.",
group: "json",
},
Spec {
name: "json.forget",
arity: -2,
flags: JSON_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "The same command as JSON.DEL, under its other name.",
group: "json",
},
Spec {
name: "json.type",
arity: -2,
flags: JSON_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "The JSON type of what a path matched.",
group: "json",
},
Spec {
name: "json.toggle",
arity: 3,
flags: JSON_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "2.0.0",
complexity: "O(N) with N the size of the document",
summary: "Flip every boolean a path matched.",
group: "json",
},
Spec {
name: "json.clear",
arity: -2,
flags: JSON_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "2.0.0",
complexity: "O(N) with N the size of the document",
summary: "Empty the containers and zero the numbers a path matched.",
group: "json",
},
Spec {
name: "json.arrlen",
arity: -2,
flags: JSON_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "How many elements are in the arrays a path matched.",
group: "json",
},
Spec {
name: "json.objlen",
arity: -2,
flags: JSON_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "How many members are in the objects a path matched.",
group: "json",
},
Spec {
name: "json.strlen",
arity: -2,
flags: JSON_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "How long the strings a path matched are, in bytes.",
group: "json",
},
Spec {
name: "json.objkeys",
arity: -2,
flags: JSON_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(N) with N the number of members",
summary: "The keys of the objects a path matched.",
group: "json",
},
Spec {
name: "json.arrappend",
arity: -3,
flags: JSON_WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Add values to the end of the arrays a path matched.",
group: "json",
},
Spec {
name: "json.arrinsert",
arity: -5,
flags: JSON_WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Put values into the arrays a path matched, at an index.",
group: "json",
},
Spec {
name: "json.arrtrim",
arity: 5,
flags: JSON_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Keep only a run of the arrays a path matched.",
group: "json",
},
Spec {
name: "json.arrpop",
arity: -2,
flags: JSON_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Take one element out of the arrays a path matched.",
group: "json",
},
Spec {
name: "json.arrindex",
arity: -4,
flags: JSON_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(N) with N the number of elements",
summary: "Where a value first sits in the arrays a path matched.",
group: "json",
},
Spec {
name: "json.numincrby",
arity: 4,
flags: JSON_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Add to every number a path matched.",
group: "json",
},
Spec {
name: "json.nummultby",
arity: 4,
flags: JSON_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Multiply every number a path matched.",
group: "json",
},
Spec {
name: "json.numpowby",
arity: 4,
flags: JSON_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Raise every number a path matched to a power.",
group: "json",
},
Spec {
name: "json.strappend",
arity: -3,
flags: JSON_WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the document",
summary: "Add to the end of every string a path matched.",
group: "json",
},
Spec {
name: "json.resp",
arity: -2,
flags: JSON_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(N) with N the size of what the path matched",
summary: "What a path matched, as RESP types rather than as JSON text.",
group: "json",
},
Spec {
name: "json.debug",
arity: -2,
flags: JSON_READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_JSON_READ,
since: "1.0.0",
complexity: "O(N) with N the size of what the path matched",
summary: "How much memory a document takes, and the help for that.",
group: "json",
},
Spec {
name: "VADD",
arity: -5,
flags: VECTOR_WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(P*D) with P the partitions probed and D the dimension",
summary: "Add a vector to a vector set under an element name.",
group: "vector",
},
Spec {
name: "VSIM",
arity: -4,
flags: VECTOR_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(P*D) with P the partitions probed and D the dimension",
summary: "The elements nearest a vector or nearest another element.",
group: "vector",
},
Spec {
name: "VREM",
arity: 3,
flags: VECTOR_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(1)",
summary: "Remove an element and its vector from a vector set.",
group: "vector",
},
Spec {
name: "VCARD",
arity: 2,
flags: VECTOR_READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(1)",
summary: "How many elements a vector set holds.",
group: "vector",
},
Spec {
name: "VDIM",
arity: 2,
flags: VECTOR_READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(1)",
summary: "How many dimensions the vectors in a vector set have.",
group: "vector",
},
Spec {
name: "VEMB",
arity: -3,
flags: VECTOR_READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(D) with D the dimension",
summary: "The vector an element went in with.",
group: "vector",
},
Spec {
name: "VINFO",
arity: 2,
flags: VECTOR_READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(N) with N the elements, for the attribute count",
summary: "What a vector set is and how its index is tuned.",
group: "vector",
},
Spec {
name: "VISMEMBER",
arity: 3,
flags: VECTOR_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(1)",
summary: "Whether an element is in a vector set.",
group: "vector",
},
Spec {
name: "VRANDMEMBER",
arity: -2,
flags: VECTOR_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(1) for one, O(N) for a positive count",
summary: "Random elements of a vector set.",
group: "vector",
},
Spec {
name: "VLINKS",
arity: -3,
flags: VECTOR_READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(P*D) with P the partitions probed and D the dimension",
summary: "The elements an element is stored next to.",
group: "vector",
},
Spec {
name: "VSETATTR",
arity: 4,
flags: VECTOR_WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(1)",
summary: "Set the attribute string on an element, or clear it.",
group: "vector",
},
Spec {
name: "VGETATTR",
arity: 3,
flags: VECTOR_READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.0.0",
complexity: "O(1)",
summary: "The attribute string on an element.",
group: "vector",
},
Spec {
name: "VRANGE",
arity: -4,
flags: VECTOR_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_NONE,
since: "8.4.0",
complexity: "O(N log N) with N the elements the range covers",
summary: "The elements of a vector set whose names fall in a range.",
group: "vector",
},
Spec {
name: "FT.CREATE",
arity: -5,
flags: SEARCH_WRITE_OOM,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(K) with K the fields declared, plus O(N) over the keyspace when the initial scan runs",
summary: "Create an index over the keys with a prefix, with the given schema.",
group: "search",
},
Spec {
name: "FT._CREATEIFNX",
arity: -5,
flags: SEARCH_WRITE_OOM,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(K) with K the fields declared, plus O(N) over the keyspace when the initial scan runs",
summary: "Create an index, and say nothing if one of that name is already there.",
group: "search",
},
Spec {
name: "FT.ALTER",
arity: -6,
flags: SEARCH_WRITE_OOM,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(N) over the keys the index follows, when the fields are backfilled",
summary: "Add fields to an index's schema.",
group: "search",
},
Spec {
name: "FT._ALTERIFNX",
arity: -6,
flags: SEARCH_WRITE_OOM,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(N) over the keys the index follows, when the fields are backfilled",
summary: "Add fields to a schema, and say nothing about the ones already there.",
group: "search",
},
Spec {
name: "FT.DROPINDEX",
arity: -2,
flags: SEARCH_WRITE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_DROP,
since: "2.0.0",
complexity: "O(1), or O(N) over the documents when DD is given",
summary: "Take an index away, and its documents with it when DD is given.",
group: "search",
},
Spec {
name: "FT._DROPINDEXIFX",
arity: -2,
flags: SEARCH_WRITE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_DROP,
since: "2.0.0",
complexity: "O(1), or O(N) over the documents when DD is given",
summary: "Take an index away, and say nothing when there is none of that name.",
group: "search",
},
Spec {
name: "FT.DROP",
arity: -1,
flags: SEARCH_WRITE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_DROP,
since: "1.0.0",
complexity: "O(1)",
summary: "Take an index away. Deprecated, and FT.DROPINDEX is the name to use.",
group: "search",
},
Spec {
name: "FT._DROPIFX",
arity: -1,
flags: SEARCH_WRITE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_WRITE,
since: "1.0.0",
complexity: "O(1)",
summary: "Take an index away and say nothing when there is none. Deprecated.",
group: "search",
},
Spec {
name: "FT.INFO",
arity: 2,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(1)",
summary: "Everything the server knows about one index.",
group: "search",
},
Spec {
name: "FT._LIST",
arity: -1,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_LIST,
since: "2.0.0",
complexity: "O(N) with N the indexes on the server",
summary: "Every index on the server, by name.",
group: "search",
},
Spec {
name: "FT.CONFIG",
arity: -2,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_ADMIN,
since: "1.0.0",
complexity: "O(1)",
summary: "Read, write or describe the search module's settings.",
group: "search",
},
Spec {
name: "_FT.DEBUG",
arity: -2,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_DEBUG,
since: "1.0.0",
complexity: "O(N) with N the size of whatever is being dumped.",
summary: "Read an index's own structures back.",
group: "search",
},
Spec {
name: "FT.ALIASADD",
arity: 3,
flags: SEARCH_WRITE_OOM,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(1)",
summary: "Point another name at an index.",
group: "search",
},
Spec {
name: "FT._ALIASADDIFNX",
arity: 3,
flags: SEARCH_WRITE_OOM,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(1)",
summary: "Point another name at an index, and say nothing if it is taken.",
group: "search",
},
Spec {
name: "FT.ALIASDEL",
arity: 2,
flags: SEARCH_WRITE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(1)",
summary: "Take an alias away.",
group: "search",
},
Spec {
name: "FT._ALIASDELIFX",
arity: 2,
flags: SEARCH_WRITE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(1)",
summary: "Take an alias away, and say nothing when there is none.",
group: "search",
},
Spec {
name: "FT.ALIASUPDATE",
arity: 3,
flags: SEARCH_WRITE_OOM,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(1)",
summary: "Move an alias to another index, adding it when it was not there.",
group: "search",
},
Spec {
name: "FT.ALIASLIST",
arity: 2,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "8.10.0",
complexity: "O(N) with N the aliases pointing at the index",
summary: "The aliases pointing at one index.",
group: "search",
},
Spec {
name: "FT.SEARCH",
arity: -3,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(N) with N the documents the query matches",
summary: "The documents a query answers, with their fields.",
group: "search",
},
Spec {
name: "FT.AGGREGATE",
arity: -3,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.1.0",
complexity: "O(N) with N the documents the query matches",
summary: "The properties a query answers, run through a pipeline.",
group: "search",
},
Spec {
name: "FT.HYBRID",
arity: -7,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "8.4.0",
complexity: "O(N) with N the documents either branch matches",
summary: "A text query and a vector query over one index, folded into one ranking.",
group: "search",
},
Spec {
name: "FT.PROFILE",
arity: -5,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_READ,
since: "2.2.0",
complexity: "O(N) with N the documents the query matches",
summary: "A search or an aggregation with the working shown.",
group: "search",
},
Spec {
name: "FT.CURSOR",
arity: -2,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.1.0",
complexity: "O(1)",
summary: "The next chunk of an answer a cursor was left open on.",
group: "search",
},
Spec {
name: "FT.EXPLAIN",
arity: -3,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(1)",
summary: "The tree a query parses into, as text.",
group: "search",
},
Spec {
name: "FT.EXPLAINCLI",
arity: -3,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.0.0",
complexity: "O(1)",
summary: "The tree a query parses into, one line per reply element.",
group: "search",
},
Spec {
name: "FT.TAGVALS",
arity: 3,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_TAGS,
since: "1.0.0",
complexity: "O(N)",
summary: "Every distinct value a tag field holds.",
group: "search",
},
Spec {
name: "FT.DICTADD",
arity: -3,
flags: SEARCH_WRITE_OOM,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.4.0",
complexity: "O(1)",
summary: "Put terms into a dictionary, making it if it is not there.",
group: "search",
},
Spec {
name: "FT.DICTDEL",
arity: -3,
flags: SEARCH_WRITE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.4.0",
complexity: "O(1)",
summary: "Take terms back out of a dictionary.",
group: "search",
},
Spec {
name: "FT.DICTDUMP",
arity: 2,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.4.0",
complexity: "O(N)",
summary: "Every term in a dictionary.",
group: "search",
},
Spec {
name: "FT.SYNUPDATE",
arity: -4,
flags: SEARCH_WRITE_OOM,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.2.0",
complexity: "O(1)",
summary: "Put terms in a synonym group.",
group: "search",
},
Spec {
name: "FT.SYNDUMP",
arity: 2,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.2.0",
complexity: "O(1)",
summary: "Every term an index treats as a synonym, and the groups it is in.",
group: "search",
},
Spec {
name: "FT.SPELLCHECK",
arity: -3,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH,
since: "1.4.0",
complexity: "O(1)",
summary: "Suggestions for the words in a query the index does not hold.",
group: "search",
},
Spec {
name: "FT.ADD",
arity: -1,
flags: SEARCH_WRITE_OOM,
first_key: 2,
last_key: 2,
step: 1,
acl: AC_SEARCH_WRITE,
since: "1.0.0",
complexity: "O(N) with N the tokens in the document",
summary: "Write a hash and record what the index should think it is worth.",
group: "search",
},
Spec {
name: "FT.SAFEADD",
arity: -1,
flags: SEARCH_WRITE_OOM,
first_key: 2,
last_key: 2,
step: 1,
acl: AC_SEARCH_WRITE,
since: "1.0.0",
complexity: "O(N) with N the tokens in the document",
summary: "The same write, under the name a cluster client used to send.",
group: "search",
},
Spec {
name: "FT.GET",
arity: -1,
flags: SEARCH_READ,
first_key: 2,
last_key: 2,
step: 1,
acl: AC_SEARCH_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "The hash under a key, when the index is holding it.",
group: "search",
},
Spec {
name: "FT.MGET",
arity: -1,
flags: SEARCH_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SEARCH_READ,
since: "1.0.0",
complexity: "O(N) with N the keys asked about",
summary: "The same, for as many keys as were named.",
group: "search",
},
Spec {
name: "FT.DEL",
arity: -1,
flags: SEARCH_WRITE,
first_key: 2,
last_key: 2,
step: 1,
acl: AC_SEARCH_WRITE,
since: "1.0.0",
complexity: "O(1)",
summary: "Delete a key, with an index name in front of it.",
group: "search",
},
Spec {
name: "FT.SUGADD",
arity: -4,
flags: SEARCH_WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SEARCH_WRITE,
since: "1.0.0",
complexity: "O(1)",
summary: "Put a suggestion in a dictionary, or change the one that is there.",
group: "search",
},
Spec {
name: "FT.SUGGET",
arity: -3,
flags: SEARCH_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SEARCH_READ,
since: "1.0.0",
complexity: "O(N) with N the suggestions the prefix reaches",
summary: "The best suggestions starting with a prefix.",
group: "search",
},
Spec {
name: "FT.SUGDEL",
arity: 3,
flags: SEARCH_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SEARCH_WRITE,
since: "1.0.0",
complexity: "O(1)",
summary: "Take a suggestion out of a dictionary.",
group: "search",
},
Spec {
name: "FT.SUGLEN",
arity: 2,
flags: SEARCH_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SEARCH_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "How many suggestions a dictionary holds.",
group: "search",
},
Spec {
name: "bf.reserve",
arity: -4,
flags: BLOOM_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Make an empty filter with a given capacity and error rate.",
group: "bloom",
},
Spec {
name: "bf.add",
arity: 3,
flags: BLOOM_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_WRITE,
since: "1.0.0",
complexity: "O(K) with K the number of hash functions",
summary: "Add an item, making the filter if the key is free.",
group: "bloom",
},
Spec {
name: "bf.madd",
arity: -3,
flags: BLOOM_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_WRITE,
since: "1.0.0",
complexity: "O(N * K) with N the number of items",
summary: "Add several items, making the filter if the key is free.",
group: "bloom",
},
Spec {
name: "bf.insert",
arity: -4,
flags: BLOOM_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_WRITE,
since: "1.0.0",
complexity: "O(N * K) with N the number of items",
summary: "Add several items to a filter described in the same command.",
group: "bloom",
},
Spec {
name: "bf.exists",
arity: 3,
flags: BLOOM_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_READ,
since: "1.0.0",
complexity: "O(K) with K the number of hash functions",
summary: "Whether an item is probably in the filter.",
group: "bloom",
},
Spec {
name: "bf.mexists",
arity: -3,
flags: BLOOM_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_READ,
since: "1.0.0",
complexity: "O(N * K) with N the number of items",
summary: "Whether each of several items is probably in the filter.",
group: "bloom",
},
Spec {
name: "bf.scandump",
arity: 3,
flags: BLOOM_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_READ,
since: "1.0.0",
complexity: "O(N) with N the size of the chunk",
summary: "One chunk of the filter, to be replayed into BF.LOADCHUNK.",
group: "bloom",
},
Spec {
name: "bf.loadchunk",
arity: 4,
flags: BLOOM_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the chunk",
summary: "Put back a chunk that BF.SCANDUMP handed out.",
group: "bloom",
},
Spec {
name: "bf.info",
arity: -2,
flags: BLOOM_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_READ_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "The shape of the filter, or one field of it.",
group: "bloom",
},
Spec {
name: "bf.card",
arity: 2,
flags: BLOOM_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_READ_FAST,
since: "2.4.4",
complexity: "O(1)",
summary: "How many items were added to the filter.",
group: "bloom",
},
Spec {
name: "bf.debug",
arity: 2,
flags: BLOOM_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_BLOOM_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "The chain and a line for each of its links.",
group: "bloom",
},
Spec {
name: "cf.reserve",
arity: -3,
flags: CUCKOO_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Make an empty filter with a given capacity.",
group: "cuckoo",
},
Spec {
name: "cf.add",
arity: 3,
flags: CUCKOO_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_WRITE,
since: "1.0.0",
complexity: "O(1) amortised, O(N) when the chain has to grow",
summary: "Add an item, making the filter if the key is free.",
group: "cuckoo",
},
Spec {
name: "cf.addnx",
arity: 3,
flags: CUCKOO_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_WRITE,
since: "1.0.0",
complexity: "O(1) amortised, O(N) when the chain has to grow",
summary: "Add an item unless the filter already has it.",
group: "cuckoo",
},
Spec {
name: "cf.insert",
arity: -4,
flags: CUCKOO_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_WRITE,
since: "1.0.0",
complexity: "O(N) with N the number of items",
summary: "Add several items to a filter described in the same command.",
group: "cuckoo",
},
Spec {
name: "cf.insertnx",
arity: -4,
flags: CUCKOO_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_WRITE,
since: "1.0.0",
complexity: "O(N) with N the number of items",
summary: "Add several items the filter does not already have.",
group: "cuckoo",
},
Spec {
name: "cf.exists",
arity: 3,
flags: CUCKOO_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "Whether an item is probably in the filter.",
group: "cuckoo",
},
Spec {
name: "cf.mexists",
arity: -3,
flags: CUCKOO_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_READ,
since: "1.0.0",
complexity: "O(N) with N the number of items",
summary: "Whether each of several items is probably in the filter.",
group: "cuckoo",
},
Spec {
name: "cf.count",
arity: 3,
flags: CUCKOO_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "How many copies of an item the filter thinks it has.",
group: "cuckoo",
},
Spec {
name: "cf.del",
arity: 3,
flags: CUCKOO_DELETE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_WRITE,
since: "1.0.0",
complexity: "O(1)",
summary: "Take one copy of an item out of the filter.",
group: "cuckoo",
},
Spec {
name: "cf.scandump",
arity: 3,
flags: CUCKOO_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_READ,
since: "1.0.0",
complexity: "O(N) with N the size of the chunk",
summary: "One chunk of the filter, to be replayed into CF.LOADCHUNK.",
group: "cuckoo",
},
Spec {
name: "cf.loadchunk",
arity: 4,
flags: CUCKOO_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_WRITE,
since: "1.0.0",
complexity: "O(N) with N the size of the chunk",
summary: "Put back a chunk that CF.SCANDUMP handed out.",
group: "cuckoo",
},
Spec {
name: "cf.info",
arity: 2,
flags: CUCKOO_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_READ_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "The shape of the chain.",
group: "cuckoo",
},
Spec {
name: "cf.debug",
arity: 2,
flags: CUCKOO_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "The chain's geometry on one line.",
group: "cuckoo",
},
Spec {
name: "cf.compact",
arity: -1,
flags: CUCKOO_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CUCKOO_READ,
since: "1.0.0",
complexity: "O(N) with N the number of items in the newer filters",
summary: "Pull the newer filters down into the older ones.",
group: "cuckoo",
},
Spec {
name: "cms.initbydim",
arity: 4,
flags: CMS_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CMS_WRITE_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "Make an empty sketch of a given width and depth.",
group: "cms",
},
Spec {
name: "cms.initbyprob",
arity: 4,
flags: CMS_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CMS_WRITE_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "Make an empty sketch wide enough for a stated tolerance.",
group: "cms",
},
Spec {
name: "cms.incrby",
arity: -4,
flags: CMS_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CMS_WRITE,
since: "2.0.0",
complexity: "O(N) with N the number of items",
summary: "Add to the count of one or more items.",
group: "cms",
},
Spec {
name: "cms.query",
arity: -3,
flags: CMS_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CMS_READ,
since: "2.0.0",
complexity: "O(N) with N the number of items",
summary: "How many times the sketch has seen each item.",
group: "cms",
},
Spec {
name: "cms.merge",
arity: -4,
flags: CMS_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CMS_WRITE,
since: "2.0.0",
complexity: "O(N * M) with N the sources and M the counters in one",
summary: "Replace a sketch with the weighted sum of others.",
group: "cms",
},
Spec {
name: "cms.info",
arity: 2,
flags: CMS_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_CMS_READ_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "The width, the depth and everything ever added.",
group: "cms",
},
Spec {
name: "topk.reserve",
arity: -3,
flags: TOPK_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TOPK_WRITE_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "Make an empty sketch that keeps the k commonest items.",
group: "topk",
},
Spec {
name: "topk.add",
arity: -3,
flags: TOPK_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TOPK_WRITE,
since: "2.0.0",
complexity: "O(N * K) with N the items and K the depth",
summary: "Count one occurrence of each item.",
group: "topk",
},
Spec {
name: "topk.incrby",
arity: -4,
flags: TOPK_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TOPK_WRITE,
since: "2.0.0",
complexity: "O(N * K) with N the items and K the depth",
summary: "Count a stated number of occurrences of each item.",
group: "topk",
},
Spec {
name: "topk.query",
arity: -3,
flags: TOPK_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TOPK_READ,
since: "2.0.0",
complexity: "O(N * K) with N the items and K the kept count",
summary: "Whether each item is one of the ones being kept.",
group: "topk",
},
Spec {
name: "topk.count",
arity: -3,
flags: TOPK_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TOPK_READ,
since: "2.0.0",
complexity: "O(N * K) with N the items and K the depth",
summary: "How many times the sketch thinks it has seen each item.",
group: "topk",
},
Spec {
name: "topk.list",
arity: -2,
flags: TOPK_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TOPK_READ,
since: "2.0.0",
complexity: "O(K log K) with K the kept count",
summary: "The kept items, heaviest first.",
group: "topk",
},
Spec {
name: "topk.info",
arity: 2,
flags: TOPK_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TOPK_READ_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "The four numbers the sketch was made with.",
group: "topk",
},
Spec {
name: "tdigest.create",
arity: -2,
flags: TDIGEST_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_WRITE_FAST,
since: "2.4.0",
complexity: "O(1)",
summary: "Make an empty digest of a stated compression.",
group: "tdigest",
},
Spec {
name: "tdigest.reset",
arity: 2,
flags: TDIGEST_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_WRITE_FAST,
since: "2.4.0",
complexity: "O(1)",
summary: "Throw away every sample and keep the shape.",
group: "tdigest",
},
Spec {
name: "tdigest.add",
arity: -3,
flags: TDIGEST_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_WRITE,
since: "2.4.0",
complexity: "O(N) with N the number of samples",
summary: "Add samples of weight one each.",
group: "tdigest",
},
Spec {
name: "tdigest.merge",
arity: -4,
flags: TDIGEST_MERGE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_WRITE,
since: "2.4.0",
complexity: "O(N) with N the number of centroids in the inputs",
summary: "Fold digests together into one.",
group: "tdigest",
},
Spec {
name: "tdigest.min",
arity: 2,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ_FAST,
since: "2.4.0",
complexity: "O(1)",
summary: "The smallest sample ever added.",
group: "tdigest",
},
Spec {
name: "tdigest.max",
arity: 2,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ_FAST,
since: "2.4.0",
complexity: "O(1)",
summary: "The largest sample ever added.",
group: "tdigest",
},
Spec {
name: "tdigest.quantile",
arity: -3,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ_FAST,
since: "2.4.0",
complexity: "O(N) with N the number of centroids",
summary: "The value each fraction of the samples falls under.",
group: "tdigest",
},
Spec {
name: "tdigest.cdf",
arity: -3,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ_FAST,
since: "2.4.0",
complexity: "O(N) with N the number of centroids",
summary: "The fraction of the samples at or below each value.",
group: "tdigest",
},
Spec {
name: "tdigest.trimmed_mean",
arity: 4,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ,
since: "2.4.0",
complexity: "O(N) with N the number of centroids",
summary: "The mean of what is left once both tails are cut.",
group: "tdigest",
},
Spec {
name: "tdigest.rank",
arity: -3,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ_FAST,
since: "2.4.0",
complexity: "O(N) with N the number of centroids",
summary: "How many samples each value is above.",
group: "tdigest",
},
Spec {
name: "tdigest.revrank",
arity: -3,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ_FAST,
since: "2.4.0",
complexity: "O(N) with N the number of centroids",
summary: "How many samples each value is below.",
group: "tdigest",
},
Spec {
name: "tdigest.byrank",
arity: -3,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ_FAST,
since: "2.4.0",
complexity: "O(N) with N the number of centroids",
summary: "The value at each rank counting up from the smallest.",
group: "tdigest",
},
Spec {
name: "tdigest.byrevrank",
arity: -3,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ_FAST,
since: "2.4.0",
complexity: "O(N) with N the number of centroids",
summary: "The value at each rank counting down from the largest.",
group: "tdigest",
},
Spec {
name: "tdigest.info",
arity: 2,
flags: TDIGEST_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TDIGEST_READ_FAST,
since: "2.4.0",
complexity: "O(1)",
summary: "The nine numbers the digest keeps about itself.",
group: "tdigest",
},
Spec {
name: "ts.create",
arity: -2,
flags: TS_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Make an empty series and say how it should behave.",
group: "ts",
},
Spec {
name: "ts.alter",
arity: -2,
flags: TS_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_WRITE,
since: "1.0.0",
complexity: "O(N) with N the labels being set",
summary: "Change how a series behaves, leaving what was not named alone.",
group: "ts",
},
Spec {
name: "ts.add",
arity: -4,
flags: TS_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_WRITE,
since: "1.0.0",
complexity: "O(M) with M the samples in the chunk a backfill lands in",
summary: "Put a sample in, making the series if it is not there.",
group: "ts",
},
Spec {
name: "ts.madd",
arity: -4,
flags: TS_WRITE,
first_key: 1,
last_key: -1,
step: 3,
acl: AC_TS_WRITE,
since: "1.0.0",
complexity: "O(N * M) with N the samples given",
summary: "Put a sample in each of several series.",
group: "ts",
},
Spec {
name: "ts.incrby",
arity: -3,
flags: TS_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_WRITE,
since: "1.0.0",
complexity: "O(M) with M the samples in the last chunk",
summary: "Add to the newest value and store the answer.",
group: "ts",
},
Spec {
name: "ts.decrby",
arity: -3,
flags: TS_WRITE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_WRITE,
since: "1.0.0",
complexity: "O(M) with M the samples in the last chunk",
summary: "Take away from the newest value and store the answer.",
group: "ts",
},
Spec {
name: "ts.del",
arity: 4,
flags: TS_DELETE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_WRITE,
since: "1.6.0",
complexity: "O(N) with N the samples in the span",
summary: "Take out every sample between two timestamps.",
group: "ts",
},
Spec {
name: "ts.get",
arity: -2,
flags: TS_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_READ_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "The newest sample in a series.",
group: "ts",
},
Spec {
name: "ts.info",
arity: -2,
flags: TS_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_READ_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "The fourteen things a series says about itself.",
group: "ts",
},
Spec {
name: "ts.range",
arity: -4,
flags: TS_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_READ,
since: "1.0.0",
complexity: "O(n/m+k) with n the samples, m the chunk size and k the samples in the span",
summary: "The samples in a span, oldest first, in buckets if asked for.",
group: "ts",
},
Spec {
name: "ts.revrange",
arity: -4,
flags: TS_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_READ,
since: "1.4.0",
complexity: "O(n/m+k) with n the samples, m the chunk size and k the samples in the span",
summary: "The same span, newest first.",
group: "ts",
},
Spec {
name: "ts.nrange",
arity: -5,
flags: TS_READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TS_READ,
since: "8.10.0",
complexity: "O(n/m+k) with n the samples, m the chunk size and k the samples in the span",
summary: "The same span out of several series, lined up on the timestamps.",
group: "ts",
},
Spec {
name: "ts.nrevrange",
arity: -5,
flags: TS_READ_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TS_READ,
since: "8.10.0",
complexity: "O(n/m+k) with n the samples, m the chunk size and k the samples in the span",
summary: "The same rows, newest first.",
group: "ts",
},
Spec {
name: "ts.read",
arity: -3,
flags: TS_READ,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_TS_READ,
since: "8.10.0",
complexity: "O(n/m+k) with n the samples, m the chunk size and k the samples answered",
summary: "Every sample from a timestamp to the end of the series.",
group: "ts",
},
Spec {
name: "ts.queryindex",
arity: -2,
flags: TS_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TS_READ,
since: "1.0.0",
complexity: "O(n) with n the series in the keyspace",
summary: "The series a filter list takes, by key name.",
group: "ts",
},
Spec {
name: "ts.querylabels",
arity: -2,
flags: TS_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TS_READ,
since: "8.10.0",
complexity: "O(n) with n the series in the keyspace",
summary: "The label names in use, or the values one of them takes.",
group: "ts",
},
Spec {
name: "ts.mget",
arity: -3,
flags: TS_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TS_READ,
since: "1.0.0",
complexity: "O(n) with n the series in the keyspace",
summary: "The newest sample of every series a filter list takes.",
group: "ts",
},
Spec {
name: "ts.mrange",
arity: -4,
flags: TS_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TS_READ,
since: "1.0.0",
complexity: "O(n) with n the series in the keyspace",
summary: "A span out of every series a filter list takes, oldest first.",
group: "ts",
},
Spec {
name: "ts.mrevrange",
arity: -4,
flags: TS_READ,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TS_READ,
since: "1.4.0",
complexity: "O(n) with n the series in the keyspace",
summary: "The same spans, newest first.",
group: "ts",
},
Spec {
name: "ts.createrule",
arity: -5,
flags: TS_RULE,
first_key: 1,
last_key: 2,
step: 1,
acl: AC_TS_WRITE,
since: "1.0.0",
complexity: "O(1)",
summary: "Fold one series into another as it is written to.",
group: "ts",
},
Spec {
name: "ts.deleterule",
arity: 3,
flags: TS_DELETE,
first_key: 1,
last_key: 2,
step: 1,
acl: AC_TS_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Stop folding one series into another.",
group: "ts",
},
Spec {
name: "arset",
arity: -4,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_WRITE_FAST,
since: "8.8.0",
complexity: "O(N) with N the number of values",
summary: "Write values into consecutive positions from an index.",
group: "array",
},
Spec {
name: "armset",
arity: -4,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_WRITE_FAST,
since: "8.8.0",
complexity: "O(N) with N the number of pairs",
summary: "Write index and value pairs, which need not be neighbours.",
group: "array",
},
Spec {
name: "arget",
arity: 3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_FAST,
since: "8.8.0",
complexity: "O(1)",
summary: "The value at one index, or a null if nothing is there.",
group: "array",
},
Spec {
name: "armget",
arity: -3,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_FAST,
since: "8.8.0",
complexity: "O(N) with N the number of indices",
summary: "The values at the indices named, in the order named.",
group: "array",
},
Spec {
name: "argetrange",
arity: 4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_SLOW,
since: "8.8.0",
complexity: "O(N) with N the length of the range",
summary: "One reply per position between two indices, holes included.",
group: "array",
},
Spec {
name: "arlen",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_FAST,
since: "8.8.0",
complexity: "O(1)",
summary: "The highest populated index plus one.",
group: "array",
},
Spec {
name: "arcount",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_FAST,
since: "8.8.0",
complexity: "O(1)",
summary: "How many indices hold something.",
group: "array",
},
Spec {
name: "ardel",
arity: -3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_WRITE_FAST,
since: "8.8.0",
complexity: "O(N) with N the number of indices",
summary: "Empty the indices named and say how many held something.",
group: "array",
},
Spec {
name: "ardelrange",
arity: -4,
flags: WRITE_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_WRITE_SLOW,
since: "8.8.0",
complexity: "O(N) with N the elements touched, not the span asked for",
summary: "Empty one or more ranges of indices.",
group: "array",
},
Spec {
name: "arinsert",
arity: -3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_WRITE_FAST,
since: "8.8.0",
complexity: "O(N) with N the number of values",
summary: "Append values at the insert cursor.",
group: "array",
},
Spec {
name: "arring",
arity: -4,
flags: WRITE_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_WRITE_SLOW,
since: "8.8.0",
complexity: "O(N) with N the values, plus the ring size when it changes",
summary: "Append values into a ring of the given size.",
group: "array",
},
Spec {
name: "arnext",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_FAST,
since: "8.8.0",
complexity: "O(1)",
summary: "The index the next append would write to.",
group: "array",
},
Spec {
name: "arseek",
arity: 3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_WRITE_FAST,
since: "8.8.0",
complexity: "O(1)",
summary: "Point the insert cursor at an index.",
group: "array",
},
Spec {
name: "arlastitems",
arity: -3,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_SLOW,
since: "8.8.0",
complexity: "O(N) with N the count asked for",
summary: "The newest positions from the insert cursor, holes included.",
group: "array",
},
Spec {
name: "arscan",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_SLOW,
since: "8.8.0",
complexity: "O(N) with N the elements found, not the span asked for",
summary: "Index and value pairs for what a range holds, skipping holes.",
group: "array",
},
Spec {
name: "argrep",
arity: -6,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_SLOW,
since: "8.8.0",
complexity: "O(P * C) with P the positions visited and C the cost of the predicates on one element",
summary: "The indexes in a range whose elements answer a set of textual predicates.",
group: "array",
},
Spec {
name: "arop",
arity: -5,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_SLOW,
since: "8.8.0",
complexity: "O(N) with N the elements found, not the span asked for",
summary: "One number out of a range, added up or compared or counted.",
group: "array",
},
Spec {
name: "arinfo",
arity: -2,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_ARRAY_READ_SLOW,
since: "8.8.0",
complexity: "O(1), or O(N) with N the slices when FULL is given",
summary: "The shape of the array, and what its slices look like.",
group: "array",
},
Spec {
name: "xadd",
arity: -5,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_FAST,
since: "5.0.0",
complexity: "O(1) for the append, plus what a trim removes.",
summary: "Append an entry and answer with the ID it got.",
group: "stream",
},
Spec {
name: "xlen",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_READ_FAST,
since: "5.0.0",
complexity: "O(1)",
summary: "How many entries the stream holds.",
group: "stream",
},
Spec {
name: "xdel",
arity: -3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_FAST,
since: "5.0.0",
complexity: "O(1) per ID.",
summary: "Remove entries by ID and say how many were there.",
group: "stream",
},
Spec {
name: "xdelex",
arity: -5,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_FAST,
since: "8.2.0",
complexity: "O(1) per ID.",
summary: "Remove entries by ID, saying what to do about the groups.",
group: "stream",
},
Spec {
name: "xackdel",
arity: -6,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_FAST,
since: "8.2.0",
complexity: "O(1) per ID.",
summary: "Acknowledge entries for a group and remove them.",
group: "stream",
},
Spec {
name: "xnack",
arity: -7,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_FAST,
since: "8.8.0",
complexity: "O(1) per ID.",
summary: "Give entries back to the group for somebody else to claim.",
group: "stream",
},
Spec {
name: "xtrim",
arity: -4,
flags: WRITE_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_SLOW,
since: "5.0.0",
complexity: "O(N) in the entries removed.",
summary: "Cut the stream down to a length or a minimum ID.",
group: "stream",
},
Spec {
name: "xrange",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_READ_SLOW,
since: "5.0.0",
complexity: "O(N) in the entries returned.",
summary: "The entries between two IDs, oldest first.",
group: "stream",
},
Spec {
name: "xrevrange",
arity: -4,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_READ_SLOW,
since: "5.0.0",
complexity: "O(N) in the entries returned.",
summary: "The entries between two IDs, newest first.",
group: "stream",
},
Spec {
name: "xread",
arity: -4,
flags: READ_BLOCKING_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_STREAM_BLOCKING_READ,
since: "5.0.0",
complexity: "O(N) in the entries returned.",
summary: "Read from one or more streams, waiting if asked to.",
group: "stream",
},
Spec {
name: "xreadgroup",
arity: -7,
flags: WRITE_BLOCKING_MOVABLE,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_STREAM_BLOCKING_WRITE,
since: "5.0.0",
complexity: "O(N) in the entries returned.",
summary: "Read as part of a consumer group, waiting if asked to.",
group: "stream",
},
Spec {
name: "xack",
arity: -4,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_FAST,
since: "5.0.0",
complexity: "O(1) per ID.",
summary: "Drop entries from a group's pending list.",
group: "stream",
},
Spec {
name: "xsetid",
arity: -3,
flags: WRITE_FAST_OOM,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_FAST,
since: "5.0.0",
complexity: "O(1)",
summary: "Set the last ID, the entries added and the max deleted ID.",
group: "stream",
},
Spec {
name: "xgroup",
arity: -2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_STREAM_CONTAINER,
since: "5.0.0",
complexity: "O(1) for all subcommands except DESTROY, which frees the group's pending list.",
summary: "Make, move and unmake consumer groups.",
group: "stream",
},
Spec {
name: "xinfo",
arity: -2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_STREAM_CONTAINER,
since: "5.0.0",
complexity: "O(1), or O(N) with N the entries and pending entries shown when FULL is given.",
summary: "What a stream, its groups and its consumers look like.",
group: "stream",
},
Spec {
name: "xpending",
arity: -3,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_READ_SLOW,
since: "5.0.0",
complexity: "O(1) for the summary, O(N) in the entries returned for the list.",
summary: "What a group has handed out and not had acknowledged.",
group: "stream",
},
Spec {
name: "xclaim",
arity: -6,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_FAST,
since: "5.0.0",
complexity: "O(1) per ID.",
summary: "Move named pending entries to another consumer.",
group: "stream",
},
Spec {
name: "xautoclaim",
arity: -6,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_STREAM_WRITE_FAST,
since: "6.2.0",
complexity: "O(1) per entry claimed, plus what it skips getting there.",
summary: "Sweep a group's pending list and take what has gone idle.",
group: "stream",
},
Spec {
name: "del",
arity: -2,
flags: &["write"],
first_key: 1,
last_key: -1,
step: 1,
acl: AC_KEY_WRITE_SLOW,
since: "1.0.0",
complexity: "O(N) in the number of keys.",
summary: "Delete keys and say how many were there.",
group: "keyspace",
},
Spec {
name: "unlink",
arity: -2,
flags: &["write", "fast"],
first_key: 1,
last_key: -1,
step: 1,
acl: AC_KEY_WRITE_FAST,
since: "4.0.0",
complexity: "O(1) per key, since the freeing is not on this thread.",
summary: "Delete keys and free them out of the way of the reply.",
group: "keyspace",
},
Spec {
name: "exists",
arity: -2,
flags: READ_FAST,
first_key: 1,
last_key: -1,
step: 1,
acl: AC_KEY_READ,
since: "1.0.0",
complexity: "O(N) in the number of keys.",
summary: "Count how many of these keys are there, naming one twice counting twice.",
group: "keyspace",
},
Spec {
name: "type",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "What kind of value is under a key, or none.",
group: "keyspace",
},
Spec {
name: "touch",
arity: -2,
flags: READ_FAST,
first_key: 1,
last_key: -1,
step: 1,
acl: AC_KEY_READ,
since: "3.2.1",
complexity: "O(N) in the number of keys.",
summary: "Count how many of these keys are there, and move them up the eviction order.",
group: "keyspace",
},
Spec {
name: "scan",
arity: -2,
flags: &["readonly"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_KEY_READ_SLOW,
since: "2.8.0",
complexity: "O(1) a call, O(N) for a whole iteration",
summary: "Walk part of the keyspace and say where to carry on from.",
group: "keyspace",
},
Spec {
name: "keys",
arity: 2,
flags: &["readonly"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_KEY_READ_ALL,
since: "1.0.0",
complexity: "O(N) in the number of keys.",
summary: "Every key matching a pattern, in one reply.",
group: "keyspace",
},
Spec {
name: "randomkey",
arity: 1,
flags: &["readonly"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_KEY_READ_SLOW,
since: "1.0.0",
complexity: "O(1)",
summary: "One key from the database, chosen at random.",
group: "keyspace",
},
Spec {
name: "rename",
arity: 3,
flags: &["write"],
first_key: 1,
last_key: 2,
step: 1,
acl: AC_KEY_WRITE_SLOW,
since: "1.0.0",
complexity: "O(1)",
summary: "Move a key to another name, over whatever was there.",
group: "keyspace",
},
Spec {
name: "renamenx",
arity: 3,
flags: WRITE_FAST,
first_key: 1,
last_key: 2,
step: 1,
acl: AC_KEY_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Move a key to another name, but only if that name is free.",
group: "keyspace",
},
Spec {
name: "copy",
arity: -3,
flags: &["write", "denyoom"],
first_key: 1,
last_key: 2,
step: 1,
acl: AC_KEY_WRITE_SLOW,
since: "6.2.0",
complexity: "O(N) in the size of the value.",
summary: "Copy a value to another key, in this database or another one.",
group: "keyspace",
},
Spec {
name: "move",
arity: 3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Move a key to another database, if it is not already there.",
group: "keyspace",
},
Spec {
name: "wait",
arity: 3,
flags: &["blocking"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_WAIT,
since: "3.0.0",
complexity: "O(1)",
summary: "Wait for this connection's writes to reach a number of replicas.",
group: "keyspace",
},
Spec {
name: "waitaof",
arity: 4,
flags: &["blocking"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_WAIT,
since: "7.2.0",
complexity: "O(1)",
summary: "Wait for this connection's writes to reach the append only files.",
group: "keyspace",
},
Spec {
name: "dump",
arity: 2,
flags: READ_SLOW,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_READ_SLOW,
since: "2.6.0",
complexity: "O(1) to find the key, then O(N) in the size of the value.",
summary: "Serialize a value into a payload another server can load.",
group: "keyspace",
},
Spec {
name: "restore",
arity: -4,
flags: &["write", "denyoom"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_RESTORE,
since: "2.6.0",
complexity: "O(1) to find the key, then O(N) in the size of the payload.",
summary: "Create a key from a payload produced by DUMP.",
group: "keyspace",
},
Spec {
name: "migrate",
arity: -6,
flags: MIGRATE_FLAGS,
first_key: 3,
last_key: 3,
step: 1,
acl: AC_RESTORE,
since: "2.6.0",
complexity: "A DUMP and a DEL here, a RESTORE there, and the bytes in between.",
summary: "Move a key to another server.",
group: "keyspace",
},
Spec {
name: "sort",
arity: -2,
flags: WRITE_MOVABLE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SORT_WRITE,
since: "1.0.0",
complexity: "O(N+M*log(M)) with N elements and M returned.",
summary: "Sort a list, set or sorted set, optionally into another key.",
group: "keyspace",
},
Spec {
name: "sort_ro",
arity: -2,
flags: READ_MOVABLE,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_SORT_READ,
since: "7.0.0",
complexity: "O(N+M*log(M)) with N elements and M returned.",
summary: "Sort a list, set or sorted set, without the STORE option.",
group: "keyspace",
},
Spec {
name: "expire",
arity: -3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_WRITE_FAST,
since: "1.0.0",
complexity: "O(1)",
summary: "Put a deadline on a key, counted in seconds from now.",
group: "keyspace",
},
Spec {
name: "pexpire",
arity: -3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_WRITE_FAST,
since: "2.6.0",
complexity: "O(1)",
summary: "Put a deadline on a key, counted in milliseconds from now.",
group: "keyspace",
},
Spec {
name: "expireat",
arity: -3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_WRITE_FAST,
since: "1.2.0",
complexity: "O(1)",
summary: "Put a deadline on a key, as a unix time in seconds.",
group: "keyspace",
},
Spec {
name: "pexpireat",
arity: -3,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_WRITE_FAST,
since: "2.6.0",
complexity: "O(1)",
summary: "Put a deadline on a key, as a unix time in milliseconds.",
group: "keyspace",
},
Spec {
name: "persist",
arity: 2,
flags: WRITE_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_WRITE_FAST,
since: "2.2.0",
complexity: "O(1)",
summary: "Take a key's deadline off, so it stops being temporary.",
group: "keyspace",
},
Spec {
name: "ttl",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "How many seconds a key has left, -1 with no deadline, -2 if gone.",
group: "keyspace",
},
Spec {
name: "pttl",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_READ,
since: "2.6.0",
complexity: "O(1)",
summary: "How many milliseconds a key has left, -1 with no deadline, -2 if gone.",
group: "keyspace",
},
Spec {
name: "expiretime",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_READ,
since: "7.0.0",
complexity: "O(1)",
summary: "When a key falls due, as a unix time in seconds.",
group: "keyspace",
},
Spec {
name: "pexpiretime",
arity: 2,
flags: READ_FAST,
first_key: 1,
last_key: 1,
step: 1,
acl: AC_KEY_READ,
since: "7.0.0",
complexity: "O(1)",
summary: "When a key falls due, as a unix time in milliseconds.",
group: "keyspace",
},
Spec {
name: "object",
arity: -2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow"],
since: "2.2.3",
complexity: "O(1)",
summary: "Look at the machinery under a key rather than at its value.",
group: "keyspace",
},
Spec {
name: "eval",
arity: -3,
flags: &[
"noscript",
"stale",
"skip_monitor",
"no_mandatory_keys",
"movablekeys",
"script_runner",
],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow", "@scripting"],
since: "2.6.0",
complexity: "Whatever the script does.",
summary: "Run a Lua script sent with the command.",
group: "scripting",
},
Spec {
name: "evalsha",
arity: -3,
flags: &[
"noscript",
"stale",
"skip_monitor",
"no_mandatory_keys",
"movablekeys",
"script_runner",
],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow", "@scripting"],
since: "2.6.0",
complexity: "Whatever the script does.",
summary: "Run a Lua script the cache already holds.",
group: "scripting",
},
Spec {
name: "eval_ro",
arity: -3,
flags: &[
"readonly",
"noscript",
"stale",
"skip_monitor",
"no_mandatory_keys",
"movablekeys",
"script_runner",
],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow", "@scripting"],
since: "7.0.0",
complexity: "Whatever the script does.",
summary: "Run a Lua script that is not allowed to write.",
group: "scripting",
},
Spec {
name: "evalsha_ro",
arity: -3,
flags: &[
"readonly",
"noscript",
"stale",
"skip_monitor",
"no_mandatory_keys",
"movablekeys",
"script_runner",
],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow", "@scripting"],
since: "7.0.0",
complexity: "Whatever the script does.",
summary: "Run a cached Lua script that is not allowed to write.",
group: "scripting",
},
Spec {
name: "fcall",
arity: -3,
flags: &[
"noscript",
"stale",
"skip_monitor",
"no_mandatory_keys",
"movablekeys",
"script_runner",
],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow", "@scripting"],
since: "7.0.0",
complexity: "Whatever the function does.",
summary: "Run a function out of a loaded library.",
group: "scripting",
},
Spec {
name: "fcall_ro",
arity: -3,
flags: &[
"readonly",
"noscript",
"stale",
"skip_monitor",
"no_mandatory_keys",
"movablekeys",
"script_runner",
],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow", "@scripting"],
since: "7.0.0",
complexity: "Whatever the function does.",
summary: "Run a function that was registered no-writes.",
group: "scripting",
},
Spec {
name: "script",
arity: -2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow"],
since: "2.6.0",
complexity: "O(1) for the subcommands that are here.",
summary: "The cache EVALSHA runs scripts out of.",
group: "scripting",
},
Spec {
name: "function",
arity: -2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow"],
since: "7.0.0",
complexity: "O(1) for the subcommands that are here.",
summary: "The libraries FCALL runs functions out of.",
group: "scripting",
},
Spec {
name: "ping",
arity: -1,
flags: &["fast"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_CONN,
since: "1.0.0",
complexity: "O(1)",
summary: "Ask whether the server is answering.",
group: "connection",
},
Spec {
name: "echo",
arity: 2,
flags: &["loading", "stale", "fast"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_CONN,
since: "1.0.0",
complexity: "O(1)",
summary: "Send a string back unchanged.",
group: "connection",
},
Spec {
name: "hello",
arity: -1,
flags: &[
"noscript",
"loading",
"stale",
"fast",
"no_auth",
"allow_busy",
],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_CONN,
since: "6.0.0",
complexity: "O(1)",
summary: "Agree on a protocol version and describe the server.",
group: "connection",
},
Spec {
name: "select",
arity: 2,
flags: &["loading", "stale", "fast"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_CONN,
since: "1.0.0",
complexity: "O(1)",
summary: "Choose which database this connection works in.",
group: "connection",
},
Spec {
name: "reset",
arity: 1,
flags: &[
"noscript",
"loading",
"stale",
"fast",
"no_auth",
"allow_busy",
],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_CONN,
since: "6.2.0",
complexity: "O(1)",
summary: "Put the connection back the way it was opened.",
group: "connection",
},
Spec {
name: "quit",
arity: -1,
flags: &[
"noscript",
"loading",
"stale",
"fast",
"no_auth",
"allow_busy",
],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_CONN,
since: "1.0.0",
complexity: "O(1)",
summary: "Close the connection after the replies already queued.",
group: "connection",
},
Spec {
name: "multi",
arity: 1,
flags: &["noscript", "loading", "stale", "fast", "allow_busy"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TX_FAST,
since: "2.0.0",
complexity: "O(1)",
summary: "Start holding commands instead of running them.",
group: "transactions",
},
Spec {
name: "exec",
arity: 1,
flags: &["noscript", "loading", "stale", "skip_slowlog"],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow", "@transaction"],
since: "1.2.0",
complexity: "Whatever the queued commands cost.",
summary: "Run everything held since MULTI.",
group: "transactions",
},
Spec {
name: "discard",
arity: 1,
flags: &["noscript", "loading", "stale", "fast", "allow_busy"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TX_FAST,
since: "2.0.0",
complexity: "O(N) in the number of commands held.",
summary: "Throw away everything held since MULTI.",
group: "transactions",
},
Spec {
name: "watch",
arity: -2,
flags: &["noscript", "loading", "stale", "fast", "allow_busy"],
first_key: 1,
last_key: -1,
step: 1,
acl: AC_TX_FAST,
since: "2.2.0",
complexity: "O(1) a key.",
summary: "Fail the next EXEC if any of these keys changes.",
group: "transactions",
},
Spec {
name: "unwatch",
arity: 1,
flags: &["noscript", "loading", "stale", "fast", "allow_busy"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_TX_FAST,
since: "2.2.0",
complexity: "O(N) in the number of keys watched.",
summary: "Stop watching everything this connection was watching.",
group: "transactions",
},
Spec {
name: "subscribe",
arity: -2,
flags: &["denyoom", "pubsub", "noscript", "loading", "stale"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_PUBSUB_SLOW,
since: "2.0.0",
complexity: "O(N) in the number of channels named.",
summary: "Listen on these channels.",
group: "pubsub",
},
Spec {
name: "unsubscribe",
arity: -1,
flags: &["pubsub", "noscript", "loading", "stale"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_PUBSUB_SLOW,
since: "2.0.0",
complexity: "O(N) in the number of channels named, or held if none are.",
summary: "Stop listening on these channels, or on all of them.",
group: "pubsub",
},
Spec {
name: "psubscribe",
arity: -2,
flags: &["denyoom", "pubsub", "noscript", "loading", "stale"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_PUBSUB_SLOW,
since: "2.0.0",
complexity: "O(N) in the number of patterns named.",
summary: "Listen on every channel matching these patterns.",
group: "pubsub",
},
Spec {
name: "punsubscribe",
arity: -1,
flags: &["pubsub", "noscript", "loading", "stale"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_PUBSUB_SLOW,
since: "2.0.0",
complexity: "O(N) in the number of patterns named, or held if none are.",
summary: "Stop listening on these patterns, or on all of them.",
group: "pubsub",
},
Spec {
name: "ssubscribe",
arity: -2,
flags: &["denyoom", "pubsub", "noscript", "loading", "stale"],
first_key: 1,
last_key: -1,
step: 1,
acl: AC_PUBSUB_SLOW,
since: "7.0.0",
complexity: "O(N) in the number of shard channels named.",
summary: "Listen on these shard channels.",
group: "pubsub",
},
Spec {
name: "sunsubscribe",
arity: -1,
flags: &["pubsub", "noscript", "loading", "stale"],
first_key: 1,
last_key: -1,
step: 1,
acl: AC_PUBSUB_SLOW,
since: "7.0.0",
complexity: "O(N) in the number of shard channels named, or held if none are.",
summary: "Stop listening on these shard channels, or on all of them.",
group: "pubsub",
},
Spec {
name: "publish",
arity: 3,
flags: &["pubsub", "loading", "stale", "fast"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_PUBSUB_FAST,
since: "2.0.0",
complexity: "O(N+M) with N the subscribers and M the patterns.",
summary: "Send a message to everybody listening on a channel.",
group: "pubsub",
},
Spec {
name: "spublish",
arity: 3,
flags: &["pubsub", "loading", "stale", "fast"],
first_key: 1,
last_key: 1,
step: 1,
acl: AC_PUBSUB_FAST,
since: "7.0.0",
complexity: "O(N) in the shard channel's subscribers.",
summary: "Send a message to everybody listening on a shard channel.",
group: "pubsub",
},
Spec {
name: "pubsub",
arity: -2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow"],
since: "2.8.0",
complexity: "O(N) in the number of channels or patterns on the server.",
summary: "What the server's subscriptions look like from outside.",
group: "pubsub",
},
Spec {
name: "command",
arity: -1,
flags: &["loading", "stale"],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow", "@connection"],
since: "2.8.13",
complexity: "O(N) with N the number of commands",
summary: "What this server can do, in the shape client libraries read.",
group: "server",
},
Spec {
name: "client",
arity: -2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow"],
since: "2.4.0",
complexity: "Depends on the subcommand.",
summary: "Ask about or change the connection the command arrived on.",
group: "connection",
},
Spec {
name: "config",
arity: -2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow"],
since: "2.0.0",
complexity: "Depends on the subcommand.",
summary: "Read and change the settings a running server exposes.",
group: "server",
},
Spec {
name: "backup",
arity: 2,
flags: &[],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow"],
since: "8.10.0",
complexity: "Depends on subcommand.",
summary: "A container for backup management commands.",
group: "server",
},
Spec {
name: "info",
arity: -1,
flags: &["loading", "stale"],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@slow", "@dangerous"],
since: "1.0.0",
complexity: "O(1)",
summary: "The server's own numbers, in sections.",
group: "server",
},
Spec {
name: "dbsize",
arity: 1,
flags: READ_FAST,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_KEY_READ,
since: "1.0.0",
complexity: "O(1)",
summary: "How many keys are in the database this connection is on.",
group: "server",
},
Spec {
name: "flushall",
arity: -1,
flags: &["write"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_KEY_FLUSH,
since: "1.0.0",
complexity: "O(N) in the number of keys in every database.",
summary: "Empty every database.",
group: "server",
},
Spec {
name: "flushdb",
arity: -1,
flags: &["write"],
first_key: 0,
last_key: 0,
step: 0,
acl: AC_KEY_FLUSH,
since: "1.0.0",
complexity: "O(N) in the number of keys in this database.",
summary: "Empty the database this connection is on.",
group: "server",
},
Spec {
name: "swapdb",
arity: 3,
flags: WRITE_FAST,
first_key: 0,
last_key: 0,
step: 0,
acl: AC_SWAPDB,
since: "4.0.0",
complexity: "O(N) in the number of clients watching or blocked on either.",
summary: "Swap two databases, so every client on one sees the other.",
group: "server",
},
Spec {
name: "time",
arity: 1,
flags: &["loading", "stale", "fast"],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@fast"],
since: "2.6.0",
complexity: "O(1)",
summary: "The server's clock, as seconds and microseconds.",
group: "server",
},
Spec {
name: "shutdown",
arity: -1,
flags: &[
"admin",
"noscript",
"loading",
"stale",
"no_multi",
"allow_busy",
],
first_key: 0,
last_key: 0,
step: 0,
acl: &["@admin", "@slow", "@dangerous"],
since: "1.0.0",
complexity: "O(1)",
summary: "Stop the server, without answering.",
group: "server",
},
];
const MIN_LEN: usize = 3;
const MAX_LEN: usize = 20;
const SLOTS: usize = 2048;
const FREE: u16 = u16::MAX;
const MIX: u64 = 0x71ee_9b00_ab8a_5fd7;
const fn key_of(name: &[u8]) -> Option<u32> {
if name.len() < MIN_LEN || name.len() > MAX_LEN {
return None;
}
let last = name.len() - 1;
let mid = name.len() / 2;
Some(
name.len() as u32
| ((name[0] | 0x20) as u32) << 8
| ((name[1] | 0x20) as u32) << 16
| (((name[last] | 0x20) ^ (name[last - 1] | 0x20) ^ (name[mid] | 0x20)) as u32) << 24,
)
}
const fn slot_of(key: u32) -> usize {
((key as u64).wrapping_mul(MIX) >> 53) as usize & (SLOTS - 1)
}
const INDEX: [u16; SLOTS] = index();
const fn index() -> [u16; SLOTS] {
let mut out = [FREE; SLOTS];
let mut i = 0;
while i < COMMANDS.len() {
let key = match key_of(COMMANDS[i].name.as_bytes()) {
Some(key) => key,
None => panic!("a command name is outside MIN_LEN..=MAX_LEN"),
};
let mut at = slot_of(key);
while out[at] != FREE {
at = (at + 1) & (SLOTS - 1);
}
out[at] = i as u16;
i += 1;
}
out
}
#[must_use]
pub fn lookup(name: &[u8]) -> Option<&'static Spec> {
at(lookup_index(name))
}
#[must_use]
pub fn lookup_index(name: &[u8]) -> u16 {
let Some(key) = key_of(name) else {
return FREE;
};
let mut at = slot_of(key);
loop {
let i = INDEX[at];
if i == FREE {
return FREE;
}
if COMMANDS[i as usize]
.name
.as_bytes()
.eq_ignore_ascii_case(name)
{
return i;
}
at = (at + 1) & (SLOTS - 1);
}
}
#[must_use]
pub fn at(i: u16) -> Option<&'static Spec> {
COMMANDS.get(i as usize)
}
#[must_use]
pub const fn count() -> usize {
COMMANDS.len()
}
#[must_use]
pub fn index_of(spec: &'static Spec) -> usize {
let front = COMMANDS.as_ptr().addr();
let here = std::ptr::from_ref(spec).addr();
(here - front) / size_of::<Spec>()
}
#[must_use]
pub fn name_at(at: usize) -> &'static str {
COMMANDS[at].name
}
#[must_use]
pub fn arity_ok(spec: &Spec, n: usize) -> bool {
let n = n as i32;
if spec.arity >= 0 {
n == spec.arity
} else {
n >= -spec.arity
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct KeySpan {
pub first: usize,
pub count: usize,
pub step: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum NoKeys {
Never,
BadCount,
}
pub(crate) fn key_span(spec: &Spec, args: Args<'_>, base: usize) -> Result<KeySpan, NoKeys> {
if let Some((rel, step, least, lenient)) = match spec.name {
"msetex" => Some((1, 2, 1, false)),
"ts.nrange" | "ts.nrevrange" => Some((1, 1, 1, false)),
"eval" | "eval_ro" | "evalsha" | "evalsha_ro" | "fcall" | "fcall_ro" => {
Some((2, 1, 0, true))
}
_ => None,
} {
let at = base + rel;
let found = parse_i64(args.get(at))
.filter(|&n| n >= least)
.and_then(|n| usize::try_from(n).ok())
.filter(|&n| at + 1 + step * n <= args.len());
let count = match found {
Some(n) => n,
None if lenient => 0,
None => return Err(NoKeys::BadCount),
};
return Ok(KeySpan {
first: at + 1,
count,
step,
});
}
if spec.first_key == 0 {
return Err(NoKeys::Never);
}
let argc = args.len() - base;
let last = if spec.last_key < 0 {
(argc as i64) + i64::from(spec.last_key)
} else {
i64::from(spec.last_key)
};
let step = i64::from(spec.step).max(1);
let first = i64::from(spec.first_key);
let count = if last < first {
0
} else {
((last - first) / step + 1) as usize
};
Ok(KeySpan {
first: base + first as usize,
count,
step: step as usize,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_name_is_spelled_the_way_it_was_registered_and_appears_once() {
let mut seen = std::collections::BTreeSet::new();
for c in COMMANDS {
let want = if c.group == "vector" || c.group == "search" {
c.name.to_uppercase()
} else {
c.name.to_lowercase()
};
assert_eq!(c.name, want, "{} is spelled wrong for its group", c.name);
assert!(seen.insert(c.name), "{} is in the table twice", c.name);
}
}
#[test]
fn a_spec_knows_where_it_is_in_the_table() {
assert_eq!(count(), COMMANDS.len());
for (want, spec) in COMMANDS.iter().enumerate() {
assert_eq!(index_of(spec), want, "{} is at the wrong index", spec.name);
}
assert_eq!(
index_of(lookup(b"get").unwrap()),
index_of(lookup(b"GET").unwrap())
);
}
#[test]
fn lookup_ignores_case_and_does_not_match_a_prefix() {
assert_eq!(lookup(b"GET").unwrap().name, "get");
assert_eq!(lookup(b"gEt").unwrap().name, "get");
assert!(lookup(b"ge").is_none());
assert!(lookup(b"gets").is_none());
}
#[test]
fn every_command_is_findable_by_its_own_name() {
for spec in COMMANDS {
let found = lookup(spec.name.as_bytes()).expect(spec.name);
assert_eq!(
index_of(found),
index_of(spec),
"{} found the wrong spec",
spec.name
);
assert_eq!(
lookup(spec.name.to_ascii_uppercase().as_bytes()).map(index_of),
Some(index_of(spec)),
"{} is not found in upper case",
spec.name,
);
}
}
#[test]
fn a_name_that_cannot_be_a_command_is_rejected_on_its_shape() {
assert!(lookup(b"").is_none());
assert!(key_of(b"").is_none());
assert!(key_of(&[b'g'; 256]).is_none());
assert!(lookup(&[b'g'; 256]).is_none());
assert!(lookup(b"9et").is_none());
}
#[test]
fn a_key_folds_the_case_and_nothing_else() {
assert_eq!(key_of(b"get"), key_of(b"GET"));
assert_eq!(key_of(b"get"), key_of(b"gEt"));
assert_ne!(key_of(b"get"), key_of(b"set"), "other first byte");
assert_ne!(key_of(b"get"), key_of(b"gxt"), "other second byte");
assert_ne!(key_of(b"get"), key_of(b"gex"), "other last byte");
assert_ne!(key_of(b"get"), key_of(b"gett"), "other length");
assert_ne!(key_of(b"abcde"), key_of(b"abxde"), "other middle byte");
assert_eq!(key_of(b"abcde"), key_of(b"ABCDE"), "middle byte folds too");
}
#[test]
fn no_command_is_more_than_two_slots_from_where_it_wants_to_be() {
let mut worst = 0;
let mut total = 0;
for spec in COMMANDS {
let key = key_of(spec.name.as_bytes()).expect(spec.name);
let home = slot_of(key);
let mut at = home;
let mut steps = 0;
while INDEX[at] as usize != index_of(spec) {
at = (at + 1) & (SLOTS - 1);
steps += 1;
assert!(steps < SLOTS, "{} is not in the index at all", spec.name);
}
worst = worst.max(steps);
total += steps;
}
assert!(worst <= 2, "worst probe is {worst} slots");
assert_eq!(
worst, 1,
"the multiplier stopped keeping every command close"
);
assert!(
total <= 24,
"{total} extra slots walked over the whole table"
);
}
#[test]
fn the_index_is_not_full() {
assert!(
COMMANDS.len() < SLOTS,
"the probe would never find an empty"
);
assert!(
COMMANDS.len() < FREE as usize,
"an index would collide with FREE"
);
let free = INDEX.iter().filter(|&&i| i == FREE).count();
assert_eq!(free, SLOTS - COMMANDS.len());
}
#[test]
fn arity_counts_the_command_name() {
let get = lookup(b"get").unwrap();
assert!(!arity_ok(get, 1));
assert!(arity_ok(get, 2));
assert!(!arity_ok(get, 3));
let set = lookup(b"set").unwrap();
assert!(!arity_ok(set, 2));
assert!(arity_ok(set, 3));
assert!(arity_ok(set, 9));
}
#[test]
fn the_pair_commands_step_two_keys_at_a_time() {
for name in [b"mset".as_slice(), b"msetnx"] {
let c = lookup(name).unwrap();
assert_eq!((c.first_key, c.last_key, c.step), (1, -1, 2));
}
let mget = lookup(b"mget").unwrap();
assert_eq!((mget.first_key, mget.last_key, mget.step), (1, -1, 1));
let msetex = lookup(b"msetex").unwrap();
assert_eq!((msetex.first_key, msetex.last_key, msetex.step), (0, 0, 0));
assert!(msetex.flags.contains(&"movablekeys"));
}
}