1#[derive(Debug, Clone, Copy)]
18pub struct Spec {
19 pub name: &'static str,
22 pub arity: i32,
25 pub flags: &'static [&'static str],
27 pub first_key: i32,
29 pub last_key: i32,
31 pub step: i32,
33 pub acl: &'static [&'static str],
35 pub since: &'static str,
37 pub complexity: &'static str,
39 pub summary: &'static str,
41 pub group: &'static str,
43}
44
45const READ_FAST: &[&str] = &["readonly", "fast"];
47const WRITE_FAST_OOM: &[&str] = &["write", "denyoom", "fast"];
49const WRITE_OOM: &[&str] = &["write", "denyoom"];
51const AC_READ_FAST: &[&str] = &["@read", "@string", "@fast"];
53const AC_READ_SLOW: &[&str] = &["@read", "@string", "@slow"];
55const AC_WRITE_FAST: &[&str] = &["@write", "@string", "@fast"];
57const AC_WRITE_SLOW: &[&str] = &["@write", "@string", "@slow"];
59const WRITE_FAST: &[&str] = &["write", "fast"];
61const AC_SET_READ_FAST: &[&str] = &["@read", "@set", "@fast"];
63const AC_SET_READ_SLOW: &[&str] = &["@read", "@set", "@slow"];
65const AC_SET_WRITE_FAST: &[&str] = &["@write", "@set", "@fast"];
67const AC_SET_WRITE_SLOW: &[&str] = &["@write", "@set", "@slow"];
70const AC_HASH_READ_FAST: &[&str] = &["@read", "@hash", "@fast"];
72const AC_HASH_READ_SLOW: &[&str] = &["@read", "@hash", "@slow"];
74const AC_HASH_WRITE_FAST: &[&str] = &["@write", "@hash", "@fast"];
76const READ_SLOW: &[&str] = &["readonly"];
78const WRITE_SLOW: &[&str] = &["write"];
81const AC_LIST_READ_FAST: &[&str] = &["@read", "@list", "@fast"];
83const AC_LIST_READ_SLOW: &[&str] = &["@read", "@list", "@slow"];
85const AC_LIST_WRITE_FAST: &[&str] = &["@write", "@list", "@fast"];
88const AC_LIST_WRITE_SLOW: &[&str] = &["@write", "@list", "@slow"];
90const AC_LIST_WRITE_BLOCKING: &[&str] = &["@write", "@list", "@slow", "@blocking"];
93const AC_ZSET_READ_FAST: &[&str] = &["@read", "@sortedset", "@fast"];
95const AC_ZSET_READ_SLOW: &[&str] = &["@read", "@sortedset", "@slow"];
97const AC_ZSET_WRITE_FAST: &[&str] = &["@write", "@sortedset", "@fast"];
99const AC_ZSET_WRITE_SLOW: &[&str] = &["@write", "@sortedset", "@slow"];
102const AC_ZSET_BLOCKING_FAST: &[&str] = &["@write", "@sortedset", "@fast", "@blocking"];
105const AC_ZSET_BLOCKING_SLOW: &[&str] = &["@write", "@sortedset", "@slow", "@blocking"];
107const AC_ARRAY_READ_FAST: &[&str] = &["@read", "@array", "@fast"];
110const AC_ARRAY_READ_SLOW: &[&str] = &["@read", "@array", "@slow"];
113const AC_ARRAY_WRITE_FAST: &[&str] = &["@write", "@array", "@fast"];
115const AC_ARRAY_WRITE_SLOW: &[&str] = &["@write", "@array", "@slow"];
118const READ_MOVABLE: &[&str] = &["readonly", "movablekeys"];
121const WRITE_MOVABLE: &[&str] = &["write", "denyoom", "movablekeys"];
123const AC_CONN: &[&str] = &["@fast", "@connection"];
125const AC_KEY_READ: &[&str] = &["@keyspace", "@read", "@fast"];
127const AC_KEY_READ_SLOW: &[&str] = &["@keyspace", "@read", "@slow"];
129const AC_KEY_READ_ALL: &[&str] = &["@keyspace", "@read", "@slow", "@dangerous"];
132const AC_KEY_WRITE_SLOW: &[&str] = &["@keyspace", "@write", "@slow"];
137const AC_KEY_WRITE_FAST: &[&str] = &["@keyspace", "@write", "@fast"];
140const AC_KEY_FLUSH: &[&str] = &["@keyspace", "@write", "@slow", "@dangerous"];
142
143pub static COMMANDS: &[Spec] = &[
145 Spec {
147 name: "set",
148 arity: -3,
149 flags: WRITE_OOM,
150 first_key: 1,
151 last_key: 1,
152 step: 1,
153 acl: AC_WRITE_SLOW,
154 since: "1.0.0",
155 complexity: "O(1)",
156 summary: "Set a key to a string value, whatever it held before.",
157 group: "string",
158 },
159 Spec {
160 name: "get",
161 arity: 2,
162 flags: READ_FAST,
163 first_key: 1,
164 last_key: 1,
165 step: 1,
166 acl: AC_READ_FAST,
167 since: "1.0.0",
168 complexity: "O(1)",
169 summary: "The string value of a key.",
170 group: "string",
171 },
172 Spec {
173 name: "getset",
174 arity: 3,
175 flags: WRITE_FAST_OOM,
176 first_key: 1,
177 last_key: 1,
178 step: 1,
179 acl: AC_WRITE_FAST,
180 since: "1.0.0",
181 complexity: "O(1)",
182 summary: "Set a key and hand back what it held.",
183 group: "string",
184 },
185 Spec {
186 name: "getdel",
187 arity: 2,
188 flags: &["write", "fast"],
189 first_key: 1,
190 last_key: 1,
191 step: 1,
192 acl: AC_WRITE_FAST,
193 since: "6.2.0",
194 complexity: "O(1)",
195 summary: "Read a key and delete it in the same step.",
196 group: "string",
197 },
198 Spec {
199 name: "getex",
200 arity: -2,
201 flags: &["write", "fast"],
202 first_key: 1,
203 last_key: 1,
204 step: 1,
205 acl: AC_WRITE_FAST,
206 since: "6.2.0",
207 complexity: "O(1)",
208 summary: "Read a key and change its deadline in the same step.",
209 group: "string",
210 },
211 Spec {
212 name: "setnx",
213 arity: 3,
214 flags: WRITE_FAST_OOM,
215 first_key: 1,
216 last_key: 1,
217 step: 1,
218 acl: AC_WRITE_FAST,
219 since: "1.0.0",
220 complexity: "O(1)",
221 summary: "Set a key only if it is not there.",
222 group: "string",
223 },
224 Spec {
225 name: "setex",
226 arity: 4,
227 flags: WRITE_OOM,
228 first_key: 1,
229 last_key: 1,
230 step: 1,
231 acl: AC_WRITE_SLOW,
232 since: "2.0.0",
233 complexity: "O(1)",
234 summary: "Set a key and give it a deadline in seconds.",
235 group: "string",
236 },
237 Spec {
238 name: "psetex",
239 arity: 4,
240 flags: WRITE_OOM,
241 first_key: 1,
242 last_key: 1,
243 step: 1,
244 acl: AC_WRITE_SLOW,
245 since: "2.6.0",
246 complexity: "O(1)",
247 summary: "Set a key and give it a deadline in milliseconds.",
248 group: "string",
249 },
250 Spec {
251 name: "mset",
252 arity: -3,
253 flags: WRITE_OOM,
254 first_key: 1,
255 last_key: -1,
256 step: 2,
257 acl: AC_WRITE_SLOW,
258 since: "1.0.1",
259 complexity: "O(N) with N the number of keys",
260 summary: "Set several keys, all of them or none.",
261 group: "string",
262 },
263 Spec {
264 name: "msetnx",
265 arity: -3,
266 flags: WRITE_OOM,
267 first_key: 1,
268 last_key: -1,
269 step: 2,
270 acl: AC_WRITE_SLOW,
271 since: "1.0.1",
272 complexity: "O(N) with N the number of keys",
273 summary: "Set several keys only if none of them are there.",
274 group: "string",
275 },
276 Spec {
277 name: "mget",
278 arity: -2,
279 flags: READ_FAST,
280 first_key: 1,
281 last_key: -1,
282 step: 1,
283 acl: AC_READ_FAST,
284 since: "1.0.0",
285 complexity: "O(N) with N the number of keys",
286 summary: "The values of several keys, in the order asked for.",
287 group: "string",
288 },
289 Spec {
290 name: "append",
291 arity: 3,
292 flags: WRITE_FAST_OOM,
293 first_key: 1,
294 last_key: 1,
295 step: 1,
296 acl: AC_WRITE_FAST,
297 since: "2.0.0",
298 complexity: "O(M) with M the length of the value being appended",
299 summary: "Add to the end of a string, creating it if it is not there.",
300 group: "string",
301 },
302 Spec {
303 name: "strlen",
304 arity: 2,
305 flags: READ_FAST,
306 first_key: 1,
307 last_key: 1,
308 step: 1,
309 acl: AC_READ_FAST,
310 since: "2.2.0",
311 complexity: "O(1)",
312 summary: "How long a string value is, without reading it.",
313 group: "string",
314 },
315 Spec {
316 name: "setrange",
317 arity: 4,
318 flags: WRITE_OOM,
319 first_key: 1,
320 last_key: 1,
321 step: 1,
322 acl: AC_WRITE_SLOW,
323 since: "2.2.0",
324 complexity: "O(M) with M the length of the replacement",
325 summary: "Overwrite part of a string at an offset, zero filling the gap.",
326 group: "string",
327 },
328 Spec {
329 name: "getrange",
330 arity: 4,
331 flags: &["readonly"],
332 first_key: 1,
333 last_key: 1,
334 step: 1,
335 acl: AC_READ_SLOW,
336 since: "2.4.0",
337 complexity: "O(N) with N the length of the answer",
338 summary: "Part of a string, by an inclusive range that may count backwards.",
339 group: "string",
340 },
341 Spec {
342 name: "substr",
343 arity: 4,
344 flags: &["readonly"],
345 first_key: 1,
346 last_key: 1,
347 step: 1,
348 acl: AC_READ_SLOW,
349 since: "1.0.0",
350 complexity: "O(N) with N the length of the answer",
351 summary: "GETRANGE under the name it had before 2.4.",
352 group: "string",
353 },
354 Spec {
355 name: "incr",
356 arity: 2,
357 flags: WRITE_FAST_OOM,
358 first_key: 1,
359 last_key: 1,
360 step: 1,
361 acl: AC_WRITE_FAST,
362 since: "1.0.0",
363 complexity: "O(1)",
364 summary: "Add one, starting from zero if the key is not there.",
365 group: "string",
366 },
367 Spec {
368 name: "decr",
369 arity: 2,
370 flags: WRITE_FAST_OOM,
371 first_key: 1,
372 last_key: 1,
373 step: 1,
374 acl: AC_WRITE_FAST,
375 since: "1.0.0",
376 complexity: "O(1)",
377 summary: "Take one away, starting from zero if the key is not there.",
378 group: "string",
379 },
380 Spec {
381 name: "incrby",
382 arity: 3,
383 flags: WRITE_FAST_OOM,
384 first_key: 1,
385 last_key: 1,
386 step: 1,
387 acl: AC_WRITE_FAST,
388 since: "1.0.0",
389 complexity: "O(1)",
390 summary: "Add a number, starting from zero if the key is not there.",
391 group: "string",
392 },
393 Spec {
394 name: "decrby",
395 arity: 3,
396 flags: WRITE_FAST_OOM,
397 first_key: 1,
398 last_key: 1,
399 step: 1,
400 acl: AC_WRITE_FAST,
401 since: "1.0.0",
402 complexity: "O(1)",
403 summary: "Take a number away, starting from zero if the key is not there.",
404 group: "string",
405 },
406 Spec {
407 name: "incrbyfloat",
408 arity: 3,
409 flags: WRITE_FAST_OOM,
410 first_key: 1,
411 last_key: 1,
412 step: 1,
413 acl: AC_WRITE_FAST,
414 since: "2.6.0",
415 complexity: "O(1)",
416 summary: "Add a float, starting from zero if the key is not there.",
417 group: "string",
418 },
419 Spec {
420 name: "lcs",
421 arity: -3,
422 flags: &["readonly"],
423 first_key: 1,
424 last_key: 2,
425 step: 1,
426 acl: AC_READ_SLOW,
427 since: "7.0.0",
428 complexity: "O(N*M) with N and M the lengths of the two values",
429 summary: "The longest subsequence two string values have in common.",
430 group: "string",
431 },
432 Spec {
433 name: "msetex",
434 arity: -4,
435 flags: &["write", "denyoom", "movablekeys"],
436 first_key: 0,
437 last_key: 0,
438 step: 0,
439 acl: AC_WRITE_SLOW,
440 since: "8.4.0",
441 complexity: "O(N) with N the number of keys",
442 summary: "Set several keys with one deadline and one condition over all of them.",
443 group: "string",
444 },
445 Spec {
446 name: "delex",
447 arity: -2,
448 flags: &["write", "fast"],
449 first_key: 1,
450 last_key: 1,
451 step: 1,
452 acl: AC_WRITE_FAST,
453 since: "8.4.0",
454 complexity: "O(1) by value, O(N) by digest",
455 summary: "Delete a key only if it still holds what the caller thinks.",
456 group: "string",
457 },
458 Spec {
459 name: "digest",
460 arity: 2,
461 flags: READ_FAST,
462 first_key: 1,
463 last_key: 1,
464 step: 1,
465 acl: AC_READ_FAST,
466 since: "8.4.0",
467 complexity: "O(N) with N the length of the value",
468 summary: "The XXH3 of a string value, as sixteen hex characters.",
469 group: "string",
470 },
471 Spec {
472 name: "increx",
473 arity: -2,
474 flags: WRITE_FAST_OOM,
475 first_key: 1,
476 last_key: 1,
477 step: 1,
478 acl: AC_WRITE_FAST,
479 since: "8.8.0",
480 complexity: "O(1)",
481 summary: "Count, with a bound, a saturation policy and a deadline.",
482 group: "string",
483 },
484 Spec {
486 name: "sadd",
487 arity: -3,
488 flags: WRITE_FAST_OOM,
489 first_key: 1,
490 last_key: 1,
491 step: 1,
492 acl: AC_SET_WRITE_FAST,
493 since: "1.0.0",
494 complexity: "O(N) with N the number of members being added",
495 summary: "Add members to a set, creating it if it is not there.",
496 group: "set",
497 },
498 Spec {
499 name: "srem",
500 arity: -3,
501 flags: WRITE_FAST,
502 first_key: 1,
503 last_key: 1,
504 step: 1,
505 acl: AC_SET_WRITE_FAST,
506 since: "1.0.0",
507 complexity: "O(N) with N the number of members being removed",
508 summary: "Take members out of a set, deleting the key if none are left.",
509 group: "set",
510 },
511 Spec {
512 name: "scard",
513 arity: 2,
514 flags: READ_FAST,
515 first_key: 1,
516 last_key: 1,
517 step: 1,
518 acl: AC_SET_READ_FAST,
519 since: "1.0.0",
520 complexity: "O(1)",
521 summary: "How many members a set has.",
522 group: "set",
523 },
524 Spec {
525 name: "sismember",
526 arity: 3,
527 flags: READ_FAST,
528 first_key: 1,
529 last_key: 1,
530 step: 1,
531 acl: AC_SET_READ_FAST,
532 since: "1.0.0",
533 complexity: "O(1)",
534 summary: "Whether a member is in a set.",
535 group: "set",
536 },
537 Spec {
538 name: "smismember",
539 arity: -3,
540 flags: READ_FAST,
541 first_key: 1,
542 last_key: 1,
543 step: 1,
544 acl: AC_SET_READ_FAST,
545 since: "6.2.0",
546 complexity: "O(N) with N the number of members being asked about",
547 summary: "Whether each of several members is in a set, in the order asked.",
548 group: "set",
549 },
550 Spec {
551 name: "smembers",
552 arity: 2,
553 flags: &["readonly"],
554 first_key: 1,
555 last_key: 1,
556 step: 1,
557 acl: AC_SET_READ_SLOW,
558 since: "1.0.0",
559 complexity: "O(N) with N the size of the set",
560 summary: "Every member of a set.",
561 group: "set",
562 },
563 Spec {
564 name: "spop",
565 arity: -2,
566 flags: WRITE_FAST,
567 first_key: 1,
568 last_key: 1,
569 step: 1,
570 acl: AC_SET_WRITE_FAST,
571 since: "1.0.0",
572 complexity: "O(1) without a count, O(N) with one",
573 summary: "Take members out of a set at random and hand them back.",
574 group: "set",
575 },
576 Spec {
577 name: "srandmember",
578 arity: -2,
579 flags: &["readonly"],
580 first_key: 1,
581 last_key: 1,
582 step: 1,
583 acl: AC_SET_READ_SLOW,
584 since: "1.0.0",
585 complexity: "O(1) without a count, O(N) with one",
586 summary: "Members of a set at random, leaving the set as it was.",
587 group: "set",
588 },
589 Spec {
590 name: "smove",
591 arity: 4,
592 flags: WRITE_FAST,
593 first_key: 1,
594 last_key: 2,
595 step: 1,
596 acl: AC_SET_WRITE_FAST,
597 since: "1.0.0",
598 complexity: "O(1)",
599 summary: "Move one member from one set to another.",
600 group: "set",
601 },
602 Spec {
603 name: "sscan",
604 arity: -3,
605 flags: &["readonly"],
606 first_key: 1,
607 last_key: 1,
608 step: 1,
609 acl: AC_SET_READ_SLOW,
610 since: "2.8.0",
611 complexity: "O(1) a call, O(N) for a whole iteration",
612 summary: "Walk part of a set and say where to carry on from.",
613 group: "set",
614 },
615 Spec {
616 name: "sinter",
617 arity: -2,
618 flags: &["readonly"],
619 first_key: 1,
620 last_key: -1,
621 step: 1,
622 acl: AC_SET_READ_SLOW,
623 since: "1.0.0",
624 complexity: "O(N*M) worst case, N the smallest set and M the number of sets",
625 summary: "The members every one of these sets has.",
626 group: "set",
627 },
628 Spec {
629 name: "sintercard",
630 arity: -3,
631 flags: READ_MOVABLE,
637 first_key: 0,
638 last_key: 0,
639 step: 0,
640 acl: AC_SET_READ_SLOW,
641 since: "7.0.0",
642 complexity: "O(N*M) worst case, N the smallest set and M the number of sets",
643 summary: "How many members every one of these sets has, up to a limit.",
644 group: "set",
645 },
646 Spec {
647 name: "sinterstore",
648 arity: -3,
649 flags: WRITE_OOM,
650 first_key: 1,
651 last_key: -1,
652 step: 1,
653 acl: AC_SET_WRITE_SLOW,
654 since: "1.0.0",
655 complexity: "O(N*M) worst case, N the smallest set and M the number of sets",
656 summary: "Store the members every one of these sets has.",
657 group: "set",
658 },
659 Spec {
660 name: "sunion",
661 arity: -2,
662 flags: &["readonly"],
663 first_key: 1,
664 last_key: -1,
665 step: 1,
666 acl: AC_SET_READ_SLOW,
667 since: "1.0.0",
668 complexity: "O(N) in the total number of members",
669 summary: "The members any of these sets has, each once.",
670 group: "set",
671 },
672 Spec {
673 name: "sunionstore",
674 arity: -3,
675 flags: WRITE_OOM,
676 first_key: 1,
677 last_key: -1,
678 step: 1,
679 acl: AC_SET_WRITE_SLOW,
680 since: "1.0.0",
681 complexity: "O(N) in the total number of members",
682 summary: "Store the members any of these sets has.",
683 group: "set",
684 },
685 Spec {
686 name: "sdiff",
687 arity: -2,
688 flags: &["readonly"],
689 first_key: 1,
690 last_key: -1,
691 step: 1,
692 acl: AC_SET_READ_SLOW,
693 since: "1.0.0",
694 complexity: "O(N) in the total number of members",
695 summary: "The members of the first set that no later set has.",
696 group: "set",
697 },
698 Spec {
699 name: "sdiffstore",
700 arity: -3,
701 flags: WRITE_OOM,
702 first_key: 1,
703 last_key: -1,
704 step: 1,
705 acl: AC_SET_WRITE_SLOW,
706 since: "1.0.0",
707 complexity: "O(N) in the total number of members",
708 summary: "Store the members of the first set that no later set has.",
709 group: "set",
710 },
711 Spec {
713 name: "hset",
714 arity: -4,
715 flags: WRITE_FAST_OOM,
716 first_key: 1,
717 last_key: 1,
718 step: 1,
719 acl: AC_HASH_WRITE_FAST,
720 since: "2.0.0",
721 complexity: "O(N) with N the number of pairs being written",
722 summary: "Write fields into a hash, creating it if it is not there.",
723 group: "hash",
724 },
725 Spec {
726 name: "hsetnx",
727 arity: 4,
728 flags: WRITE_FAST_OOM,
729 first_key: 1,
730 last_key: 1,
731 step: 1,
732 acl: AC_HASH_WRITE_FAST,
733 since: "2.0.0",
734 complexity: "O(1)",
735 summary: "Write a field only if the hash does not have it already.",
736 group: "hash",
737 },
738 Spec {
741 name: "hmset",
742 arity: -4,
743 flags: WRITE_FAST_OOM,
744 first_key: 1,
745 last_key: 1,
746 step: 1,
747 acl: AC_HASH_WRITE_FAST,
748 since: "2.0.0",
749 complexity: "O(N) with N the number of pairs being written",
750 summary: "Write fields into a hash and answer OK. Use HSET.",
751 group: "hash",
752 },
753 Spec {
754 name: "hget",
755 arity: 3,
756 flags: READ_FAST,
757 first_key: 1,
758 last_key: 1,
759 step: 1,
760 acl: AC_HASH_READ_FAST,
761 since: "2.0.0",
762 complexity: "O(1)",
763 summary: "The value of one field of a hash.",
764 group: "hash",
765 },
766 Spec {
767 name: "hmget",
768 arity: -3,
769 flags: READ_FAST,
770 first_key: 1,
771 last_key: 1,
772 step: 1,
773 acl: AC_HASH_READ_FAST,
774 since: "2.0.0",
775 complexity: "O(N) with N the number of fields asked for",
776 summary: "The values of several fields, one reply entry each.",
777 group: "hash",
778 },
779 Spec {
780 name: "hdel",
781 arity: -3,
782 flags: WRITE_FAST,
783 first_key: 1,
784 last_key: 1,
785 step: 1,
786 acl: AC_HASH_WRITE_FAST,
787 since: "2.0.0",
788 complexity: "O(N) with N the number of fields being removed",
789 summary: "Take fields out of a hash, deleting the key if none are left.",
790 group: "hash",
791 },
792 Spec {
793 name: "hlen",
794 arity: 2,
795 flags: READ_FAST,
796 first_key: 1,
797 last_key: 1,
798 step: 1,
799 acl: AC_HASH_READ_FAST,
800 since: "2.0.0",
801 complexity: "O(1)",
802 summary: "How many fields a hash has.",
803 group: "hash",
804 },
805 Spec {
806 name: "hexists",
807 arity: 3,
808 flags: READ_FAST,
809 first_key: 1,
810 last_key: 1,
811 step: 1,
812 acl: AC_HASH_READ_FAST,
813 since: "2.0.0",
814 complexity: "O(1)",
815 summary: "Whether a hash has a field.",
816 group: "hash",
817 },
818 Spec {
819 name: "hstrlen",
820 arity: 3,
821 flags: READ_FAST,
822 first_key: 1,
823 last_key: 1,
824 step: 1,
825 acl: AC_HASH_READ_FAST,
826 since: "3.2.0",
827 complexity: "O(1)",
828 summary: "How many bytes a field's value is, without sending it.",
829 group: "hash",
830 },
831 Spec {
832 name: "hgetall",
833 arity: 2,
834 flags: &["readonly"],
835 first_key: 1,
836 last_key: 1,
837 step: 1,
838 acl: AC_HASH_READ_SLOW,
839 since: "2.0.0",
840 complexity: "O(N) in the size of the hash",
841 summary: "Every field and value, as a map on RESP3.",
842 group: "hash",
843 },
844 Spec {
845 name: "hkeys",
846 arity: 2,
847 flags: &["readonly"],
848 first_key: 1,
849 last_key: 1,
850 step: 1,
851 acl: AC_HASH_READ_SLOW,
852 since: "2.0.0",
853 complexity: "O(N) in the size of the hash",
854 summary: "Every field of a hash.",
855 group: "hash",
856 },
857 Spec {
858 name: "hvals",
859 arity: 2,
860 flags: &["readonly"],
861 first_key: 1,
862 last_key: 1,
863 step: 1,
864 acl: AC_HASH_READ_SLOW,
865 since: "2.0.0",
866 complexity: "O(N) in the size of the hash",
867 summary: "Every value of a hash.",
868 group: "hash",
869 },
870 Spec {
871 name: "hincrby",
872 arity: 4,
873 flags: WRITE_FAST_OOM,
874 first_key: 1,
875 last_key: 1,
876 step: 1,
877 acl: AC_HASH_WRITE_FAST,
878 since: "2.0.0",
879 complexity: "O(1)",
880 summary: "Add an integer to a field, treating a missing one as zero.",
881 group: "hash",
882 },
883 Spec {
884 name: "hincrbyfloat",
885 arity: 4,
886 flags: WRITE_FAST_OOM,
887 first_key: 1,
888 last_key: 1,
889 step: 1,
890 acl: AC_HASH_WRITE_FAST,
891 since: "2.6.0",
892 complexity: "O(1)",
893 summary: "Add a float to a field, treating a missing one as zero.",
894 group: "hash",
895 },
896 Spec {
897 name: "hrandfield",
898 arity: -2,
899 flags: &["readonly"],
900 first_key: 1,
901 last_key: 1,
902 step: 1,
903 acl: AC_HASH_READ_SLOW,
904 since: "6.2.0",
905 complexity: "O(1) without a count, O(N) with one",
906 summary: "Fields of a hash at random, leaving the hash as it was.",
907 group: "hash",
908 },
909 Spec {
910 name: "hscan",
911 arity: -3,
912 flags: &["readonly"],
913 first_key: 1,
914 last_key: 1,
915 step: 1,
916 acl: AC_HASH_READ_SLOW,
917 since: "2.8.0",
918 complexity: "O(1) a call, O(N) for a whole iteration",
919 summary: "Walk part of a hash and say where to carry on from.",
920 group: "hash",
921 },
922 Spec {
923 name: "hexpire",
924 arity: -6,
925 flags: WRITE_FAST,
926 first_key: 1,
927 last_key: 1,
928 step: 1,
929 acl: AC_HASH_WRITE_FAST,
930 since: "7.4.0",
931 complexity: "O(N) with N the number of fields named",
932 summary: "Put a deadline in seconds on hash fields.",
933 group: "hash",
934 },
935 Spec {
936 name: "hpexpire",
937 arity: -6,
938 flags: WRITE_FAST,
939 first_key: 1,
940 last_key: 1,
941 step: 1,
942 acl: AC_HASH_WRITE_FAST,
943 since: "7.4.0",
944 complexity: "O(N) with N the number of fields named",
945 summary: "Put a deadline in milliseconds on hash fields.",
946 group: "hash",
947 },
948 Spec {
949 name: "hexpireat",
950 arity: -6,
951 flags: WRITE_FAST,
952 first_key: 1,
953 last_key: 1,
954 step: 1,
955 acl: AC_HASH_WRITE_FAST,
956 since: "7.4.0",
957 complexity: "O(N) with N the number of fields named",
958 summary: "Put an absolute deadline in unix seconds on hash fields.",
959 group: "hash",
960 },
961 Spec {
962 name: "hpexpireat",
963 arity: -6,
964 flags: WRITE_FAST,
965 first_key: 1,
966 last_key: 1,
967 step: 1,
968 acl: AC_HASH_WRITE_FAST,
969 since: "7.4.0",
970 complexity: "O(N) with N the number of fields named",
971 summary: "Put an absolute deadline in unix milliseconds on hash fields.",
972 group: "hash",
973 },
974 Spec {
975 name: "httl",
976 arity: -5,
977 flags: READ_FAST,
978 first_key: 1,
979 last_key: 1,
980 step: 1,
981 acl: AC_HASH_READ_FAST,
982 since: "7.4.0",
983 complexity: "O(N) with N the number of fields named",
984 summary: "How long hash fields have left, in seconds.",
985 group: "hash",
986 },
987 Spec {
988 name: "hpttl",
989 arity: -5,
990 flags: READ_FAST,
991 first_key: 1,
992 last_key: 1,
993 step: 1,
994 acl: AC_HASH_READ_FAST,
995 since: "7.4.0",
996 complexity: "O(N) with N the number of fields named",
997 summary: "How long hash fields have left, in milliseconds.",
998 group: "hash",
999 },
1000 Spec {
1001 name: "hexpiretime",
1002 arity: -5,
1003 flags: READ_FAST,
1004 first_key: 1,
1005 last_key: 1,
1006 step: 1,
1007 acl: AC_HASH_READ_FAST,
1008 since: "7.4.0",
1009 complexity: "O(N) with N the number of fields named",
1010 summary: "When hash fields fall due, in unix seconds.",
1011 group: "hash",
1012 },
1013 Spec {
1014 name: "hpexpiretime",
1015 arity: -5,
1016 flags: READ_FAST,
1017 first_key: 1,
1018 last_key: 1,
1019 step: 1,
1020 acl: AC_HASH_READ_FAST,
1021 since: "7.4.0",
1022 complexity: "O(N) with N the number of fields named",
1023 summary: "When hash fields fall due, in unix milliseconds.",
1024 group: "hash",
1025 },
1026 Spec {
1027 name: "hpersist",
1028 arity: -5,
1029 flags: WRITE_FAST,
1030 first_key: 1,
1031 last_key: 1,
1032 step: 1,
1033 acl: AC_HASH_WRITE_FAST,
1034 since: "7.4.0",
1035 complexity: "O(N) with N the number of fields named",
1036 summary: "Take the deadlines off hash fields.",
1037 group: "hash",
1038 },
1039 Spec {
1040 name: "hgetdel",
1041 arity: -5,
1042 flags: WRITE_FAST,
1043 first_key: 1,
1044 last_key: 1,
1045 step: 1,
1046 acl: AC_HASH_WRITE_FAST,
1047 since: "8.0.0",
1048 complexity: "O(N) with N the number of fields named",
1049 summary: "Read hash fields and delete them.",
1050 group: "hash",
1051 },
1052 Spec {
1053 name: "hgetex",
1054 arity: -5,
1055 flags: WRITE_FAST,
1056 first_key: 1,
1057 last_key: 1,
1058 step: 1,
1059 acl: AC_HASH_WRITE_FAST,
1060 since: "8.0.0",
1061 complexity: "O(N) with N the number of fields named",
1062 summary: "Read hash fields and set their deadlines.",
1063 group: "hash",
1064 },
1065 Spec {
1066 name: "hsetex",
1067 arity: -6,
1068 flags: WRITE_FAST_OOM,
1069 first_key: 1,
1070 last_key: 1,
1071 step: 1,
1072 acl: AC_HASH_WRITE_FAST,
1073 since: "8.0.0",
1074 complexity: "O(N) with N the number of fields being set",
1075 summary: "Set hash fields and their deadlines together.",
1076 group: "hash",
1077 },
1078 Spec {
1080 name: "lpush",
1081 arity: -3,
1082 flags: WRITE_FAST_OOM,
1083 first_key: 1,
1084 last_key: 1,
1085 step: 1,
1086 acl: AC_LIST_WRITE_FAST,
1087 since: "1.0.0",
1088 complexity: "O(N) with N the number of elements pushed",
1089 summary: "Push elements onto the head of a list.",
1090 group: "list",
1091 },
1092 Spec {
1093 name: "rpush",
1094 arity: -3,
1095 flags: WRITE_FAST_OOM,
1096 first_key: 1,
1097 last_key: 1,
1098 step: 1,
1099 acl: AC_LIST_WRITE_FAST,
1100 since: "1.0.0",
1101 complexity: "O(N) with N the number of elements pushed",
1102 summary: "Push elements onto the tail of a list.",
1103 group: "list",
1104 },
1105 Spec {
1106 name: "lpushx",
1107 arity: -3,
1108 flags: WRITE_FAST_OOM,
1109 first_key: 1,
1110 last_key: 1,
1111 step: 1,
1112 acl: AC_LIST_WRITE_FAST,
1113 since: "2.2.0",
1114 complexity: "O(N) with N the number of elements pushed",
1115 summary: "Push elements onto the head of a list that already exists.",
1116 group: "list",
1117 },
1118 Spec {
1119 name: "rpushx",
1120 arity: -3,
1121 flags: WRITE_FAST_OOM,
1122 first_key: 1,
1123 last_key: 1,
1124 step: 1,
1125 acl: AC_LIST_WRITE_FAST,
1126 since: "2.2.0",
1127 complexity: "O(N) with N the number of elements pushed",
1128 summary: "Push elements onto the tail of a list that already exists.",
1129 group: "list",
1130 },
1131 Spec {
1132 name: "lpop",
1133 arity: -2,
1134 flags: WRITE_FAST,
1135 first_key: 1,
1136 last_key: 1,
1137 step: 1,
1138 acl: AC_LIST_WRITE_FAST,
1139 since: "1.0.0",
1140 complexity: "O(N) with N the count asked for",
1141 summary: "Take elements off the head of a list.",
1142 group: "list",
1143 },
1144 Spec {
1145 name: "rpop",
1146 arity: -2,
1147 flags: WRITE_FAST,
1148 first_key: 1,
1149 last_key: 1,
1150 step: 1,
1151 acl: AC_LIST_WRITE_FAST,
1152 since: "1.0.0",
1153 complexity: "O(N) with N the count asked for",
1154 summary: "Take elements off the tail of a list.",
1155 group: "list",
1156 },
1157 Spec {
1158 name: "llen",
1159 arity: 2,
1160 flags: READ_FAST,
1161 first_key: 1,
1162 last_key: 1,
1163 step: 1,
1164 acl: AC_LIST_READ_FAST,
1165 since: "1.0.0",
1166 complexity: "O(1)",
1167 summary: "How many elements a list holds.",
1168 group: "list",
1169 },
1170 Spec {
1171 name: "lrange",
1172 arity: 4,
1173 flags: READ_SLOW,
1174 first_key: 1,
1175 last_key: 1,
1176 step: 1,
1177 acl: AC_LIST_READ_SLOW,
1178 since: "1.0.0",
1179 complexity: "O(S+N) with S the offset of the first element and N the range",
1180 summary: "Read a range of a list, both ends included.",
1181 group: "list",
1182 },
1183 Spec {
1184 name: "lindex",
1185 arity: 3,
1186 flags: READ_SLOW,
1187 first_key: 1,
1188 last_key: 1,
1189 step: 1,
1190 acl: AC_LIST_READ_SLOW,
1191 since: "1.0.0",
1192 complexity: "O(N) with N the distance to the index from the nearer end",
1193 summary: "Read one element of a list by index.",
1194 group: "list",
1195 },
1196 Spec {
1197 name: "lset",
1198 arity: 4,
1199 flags: WRITE_OOM,
1200 first_key: 1,
1201 last_key: 1,
1202 step: 1,
1203 acl: AC_LIST_WRITE_SLOW,
1204 since: "1.0.0",
1205 complexity: "O(N) with N the distance to the index from the nearer end",
1206 summary: "Replace one element of a list by index.",
1207 group: "list",
1208 },
1209 Spec {
1210 name: "linsert",
1211 arity: 5,
1212 flags: WRITE_OOM,
1213 first_key: 1,
1214 last_key: 1,
1215 step: 1,
1216 acl: AC_LIST_WRITE_SLOW,
1217 since: "2.2.0",
1218 complexity: "O(N) with N the distance to the pivot from the head",
1219 summary: "Insert an element before or after another one.",
1220 group: "list",
1221 },
1222 Spec {
1223 name: "lrem",
1224 arity: 4,
1225 flags: WRITE_SLOW,
1226 first_key: 1,
1227 last_key: 1,
1228 step: 1,
1229 acl: AC_LIST_WRITE_SLOW,
1230 since: "1.0.0",
1231 complexity: "O(N) with N the length of the list",
1232 summary: "Remove elements equal to a value from a list.",
1233 group: "list",
1234 },
1235 Spec {
1236 name: "ltrim",
1237 arity: 4,
1238 flags: WRITE_SLOW,
1239 first_key: 1,
1240 last_key: 1,
1241 step: 1,
1242 acl: AC_LIST_WRITE_SLOW,
1243 since: "1.0.0",
1244 complexity: "O(N) with N the number of elements thrown away",
1245 summary: "Keep a range of a list and throw the rest away.",
1246 group: "list",
1247 },
1248 Spec {
1249 name: "lpos",
1250 arity: -3,
1251 flags: READ_SLOW,
1252 first_key: 1,
1253 last_key: 1,
1254 step: 1,
1255 acl: AC_LIST_READ_SLOW,
1256 since: "6.0.6",
1257 complexity: "O(N) with N the length of the list",
1258 summary: "Find where a value sits in a list.",
1259 group: "list",
1260 },
1261 Spec {
1262 name: "rpoplpush",
1263 arity: 3,
1264 flags: WRITE_OOM,
1265 first_key: 1,
1266 last_key: 2,
1267 step: 1,
1268 acl: AC_LIST_WRITE_SLOW,
1269 since: "1.2.0",
1270 complexity: "O(1)",
1271 summary: "Move an element from the tail of one list to the head of another.",
1272 group: "list",
1273 },
1274 Spec {
1275 name: "lmove",
1276 arity: 5,
1277 flags: WRITE_OOM,
1278 first_key: 1,
1279 last_key: 2,
1280 step: 1,
1281 acl: AC_LIST_WRITE_SLOW,
1282 since: "6.2.0",
1283 complexity: "O(1)",
1284 summary: "Move an element from either end of one list to either end of another.",
1285 group: "list",
1286 },
1287 Spec {
1292 name: "lmpop",
1293 arity: -4,
1294 flags: &["write", "movablekeys"],
1295 first_key: 0,
1296 last_key: 0,
1297 step: 0,
1298 acl: AC_LIST_WRITE_SLOW,
1299 since: "7.0.0",
1300 complexity: "O(N+M) with N the number of keys and M the count popped",
1301 summary: "Pop from the first of several lists that has anything in it.",
1302 group: "list",
1303 },
1304 Spec {
1312 name: "blpop",
1313 arity: -3,
1314 flags: &["write", "blocking"],
1315 first_key: 1,
1316 last_key: -2,
1317 step: 1,
1318 acl: AC_LIST_WRITE_BLOCKING,
1319 since: "2.0.0",
1320 complexity: "O(N) with N the number of keys named",
1321 summary: "Pop the head of the first list that has anything, waiting if none does.",
1322 group: "list",
1323 },
1324 Spec {
1325 name: "brpop",
1326 arity: -3,
1327 flags: &["write", "blocking"],
1328 first_key: 1,
1329 last_key: -2,
1330 step: 1,
1331 acl: AC_LIST_WRITE_BLOCKING,
1332 since: "2.0.0",
1333 complexity: "O(N) with N the number of keys named",
1334 summary: "Pop the tail of the first list that has anything, waiting if none does.",
1335 group: "list",
1336 },
1337 Spec {
1340 name: "blmove",
1341 arity: 6,
1342 flags: &["write", "denyoom", "blocking"],
1343 first_key: 1,
1344 last_key: 2,
1345 step: 1,
1346 acl: AC_LIST_WRITE_BLOCKING,
1347 since: "6.2.0",
1348 complexity: "O(1)",
1349 summary: "Move an element between two lists, waiting for one to arrive.",
1350 group: "list",
1351 },
1352 Spec {
1353 name: "brpoplpush",
1354 arity: 4,
1355 flags: &["write", "denyoom", "blocking"],
1356 first_key: 1,
1357 last_key: 2,
1358 step: 1,
1359 acl: AC_LIST_WRITE_BLOCKING,
1360 since: "2.2.0",
1361 complexity: "O(1)",
1362 summary: "Move a tail element to another list's head, waiting for one to arrive.",
1363 group: "list",
1364 },
1365 Spec {
1367 name: "blmpop",
1368 arity: -5,
1369 flags: &["write", "blocking", "movablekeys"],
1370 first_key: 0,
1371 last_key: 0,
1372 step: 0,
1373 acl: AC_LIST_WRITE_BLOCKING,
1374 since: "7.0.0",
1375 complexity: "O(N+M) with N the number of keys and M the count popped",
1376 summary: "Pop from the first of several lists that has anything, waiting if none does.",
1377 group: "list",
1378 },
1379 Spec {
1381 name: "zadd",
1382 arity: -4,
1383 flags: WRITE_FAST_OOM,
1384 first_key: 1,
1385 last_key: 1,
1386 step: 1,
1387 acl: AC_ZSET_WRITE_FAST,
1388 since: "1.2.0",
1389 complexity: "O(log(N)) for each member added",
1390 summary: "Add members with scores, or move the scores of members already there.",
1391 group: "zset",
1392 },
1393 Spec {
1394 name: "zincrby",
1395 arity: 4,
1396 flags: WRITE_FAST_OOM,
1397 first_key: 1,
1398 last_key: 1,
1399 step: 1,
1400 acl: AC_ZSET_WRITE_FAST,
1401 since: "1.2.0",
1402 complexity: "O(log(N))",
1403 summary: "Add to a member's score, creating the member at zero if it is not there.",
1404 group: "zset",
1405 },
1406 Spec {
1407 name: "zcard",
1408 arity: 2,
1409 flags: READ_FAST,
1410 first_key: 1,
1411 last_key: 1,
1412 step: 1,
1413 acl: AC_ZSET_READ_FAST,
1414 since: "1.2.0",
1415 complexity: "O(1)",
1416 summary: "How many members a sorted set has.",
1417 group: "zset",
1418 },
1419 Spec {
1420 name: "zscore",
1421 arity: 3,
1422 flags: READ_FAST,
1423 first_key: 1,
1424 last_key: 1,
1425 step: 1,
1426 acl: AC_ZSET_READ_FAST,
1427 since: "1.2.0",
1428 complexity: "O(1)",
1429 summary: "A member's score, or nothing if it is not there.",
1430 group: "zset",
1431 },
1432 Spec {
1433 name: "zmscore",
1434 arity: -3,
1435 flags: READ_FAST,
1436 first_key: 1,
1437 last_key: 1,
1438 step: 1,
1439 acl: AC_ZSET_READ_FAST,
1440 since: "6.2.0",
1441 complexity: "O(N) with N the number of members asked about",
1442 summary: "The scores of several members in one round trip.",
1443 group: "zset",
1444 },
1445 Spec {
1446 name: "zrem",
1447 arity: -3,
1448 flags: WRITE_FAST,
1449 first_key: 1,
1450 last_key: 1,
1451 step: 1,
1452 acl: AC_ZSET_WRITE_FAST,
1453 since: "1.2.0",
1454 complexity: "O(M*log(N)) with M the number of members removed",
1455 summary: "Remove members, deleting the key if the last one goes.",
1456 group: "zset",
1457 },
1458 Spec {
1459 name: "zrank",
1460 arity: -3,
1461 flags: READ_FAST,
1462 first_key: 1,
1463 last_key: 1,
1464 step: 1,
1465 acl: AC_ZSET_READ_FAST,
1466 since: "2.0.0",
1467 complexity: "O(log(N))",
1468 summary: "Where a member sits counting up from the lowest score.",
1469 group: "zset",
1470 },
1471 Spec {
1472 name: "zrevrank",
1473 arity: -3,
1474 flags: READ_FAST,
1475 first_key: 1,
1476 last_key: 1,
1477 step: 1,
1478 acl: AC_ZSET_READ_FAST,
1479 since: "2.0.0",
1480 complexity: "O(log(N))",
1481 summary: "Where a member sits counting down from the highest score.",
1482 group: "zset",
1483 },
1484 Spec {
1485 name: "zcount",
1486 arity: 4,
1487 flags: READ_FAST,
1488 first_key: 1,
1489 last_key: 1,
1490 step: 1,
1491 acl: AC_ZSET_READ_FAST,
1492 since: "2.0.0",
1493 complexity: "O(log(N))",
1494 summary: "How many members have scores between two bounds.",
1495 group: "zset",
1496 },
1497 Spec {
1498 name: "zlexcount",
1499 arity: 4,
1500 flags: READ_FAST,
1501 first_key: 1,
1502 last_key: 1,
1503 step: 1,
1504 acl: AC_ZSET_READ_FAST,
1505 since: "2.8.9",
1506 complexity: "O(log(N))",
1507 summary: "How many members fall between two members, by name.",
1508 group: "zset",
1509 },
1510 Spec {
1511 name: "zrange",
1512 arity: -4,
1513 flags: READ_SLOW,
1514 first_key: 1,
1515 last_key: 1,
1516 step: 1,
1517 acl: AC_ZSET_READ_SLOW,
1518 since: "1.2.0",
1519 complexity: "O(log(N)+M) with M the number of members answered",
1520 summary: "A window of members, by rank or by score or by name, either way round.",
1521 group: "zset",
1522 },
1523 Spec {
1524 name: "zrevrange",
1525 arity: -4,
1526 flags: READ_SLOW,
1527 first_key: 1,
1528 last_key: 1,
1529 step: 1,
1530 acl: AC_ZSET_READ_SLOW,
1531 since: "1.2.0",
1532 complexity: "O(log(N)+M) with M the number of members answered",
1533 summary: "A window by rank, counting down from the highest score.",
1534 group: "zset",
1535 },
1536 Spec {
1537 name: "zrangebyscore",
1538 arity: -4,
1539 flags: READ_SLOW,
1540 first_key: 1,
1541 last_key: 1,
1542 step: 1,
1543 acl: AC_ZSET_READ_SLOW,
1544 since: "1.0.5",
1545 complexity: "O(log(N)+M) with M the number of members answered",
1546 summary: "The members whose scores fall between two bounds.",
1547 group: "zset",
1548 },
1549 Spec {
1550 name: "zrevrangebyscore",
1551 arity: -4,
1552 flags: READ_SLOW,
1553 first_key: 1,
1554 last_key: 1,
1555 step: 1,
1556 acl: AC_ZSET_READ_SLOW,
1557 since: "2.2.0",
1558 complexity: "O(log(N)+M) with M the number of members answered",
1559 summary: "The same window as ZRANGEBYSCORE, highest score first and named high end first.",
1560 group: "zset",
1561 },
1562 Spec {
1563 name: "zrangebylex",
1564 arity: -4,
1565 flags: READ_SLOW,
1566 first_key: 1,
1567 last_key: 1,
1568 step: 1,
1569 acl: AC_ZSET_READ_SLOW,
1570 since: "2.8.9",
1571 complexity: "O(log(N)+M) with M the number of members answered",
1572 summary: "The members that fall between two names, for a set where every score is the same.",
1573 group: "zset",
1574 },
1575 Spec {
1576 name: "zrevrangebylex",
1577 arity: -4,
1578 flags: READ_SLOW,
1579 first_key: 1,
1580 last_key: 1,
1581 step: 1,
1582 acl: AC_ZSET_READ_SLOW,
1583 since: "2.8.9",
1584 complexity: "O(log(N)+M) with M the number of members answered",
1585 summary: "The same window as ZRANGEBYLEX, backwards and named high end first.",
1586 group: "zset",
1587 },
1588 Spec {
1589 name: "zrangestore",
1590 arity: -5,
1591 flags: WRITE_OOM,
1592 first_key: 1,
1593 last_key: 2,
1594 step: 1,
1595 acl: AC_ZSET_WRITE_SLOW,
1596 since: "6.2.0",
1597 complexity: "O(log(N)+M) with M the number of members stored",
1598 summary: "Write a window of one sorted set into another key.",
1599 group: "zset",
1600 },
1601 Spec {
1602 name: "zremrangebyrank",
1603 arity: 4,
1604 flags: WRITE_SLOW,
1605 first_key: 1,
1606 last_key: 1,
1607 step: 1,
1608 acl: AC_ZSET_WRITE_SLOW,
1609 since: "2.0.0",
1610 complexity: "O(log(N)+M) with M the number of members removed",
1611 summary: "Remove the members in a range of ranks.",
1612 group: "zset",
1613 },
1614 Spec {
1615 name: "zremrangebyscore",
1616 arity: 4,
1617 flags: WRITE_SLOW,
1618 first_key: 1,
1619 last_key: 1,
1620 step: 1,
1621 acl: AC_ZSET_WRITE_SLOW,
1622 since: "1.2.0",
1623 complexity: "O(log(N)+M) with M the number of members removed",
1624 summary: "Remove the members whose scores fall between two bounds.",
1625 group: "zset",
1626 },
1627 Spec {
1628 name: "zremrangebylex",
1629 arity: 4,
1630 flags: WRITE_SLOW,
1631 first_key: 1,
1632 last_key: 1,
1633 step: 1,
1634 acl: AC_ZSET_WRITE_SLOW,
1635 since: "2.8.9",
1636 complexity: "O(log(N)+M) with M the number of members removed",
1637 summary: "Remove the members that fall between two names.",
1638 group: "zset",
1639 },
1640 Spec {
1641 name: "zunion",
1642 arity: -3,
1643 flags: READ_MOVABLE,
1644 first_key: 0,
1645 last_key: 0,
1646 step: 0,
1647 acl: AC_ZSET_READ_SLOW,
1648 since: "6.2.0",
1649 complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
1650 summary: "Every member of these sorted sets, with the scores combined.",
1651 group: "zset",
1652 },
1653 Spec {
1654 name: "zinter",
1655 arity: -3,
1656 flags: READ_MOVABLE,
1657 first_key: 0,
1658 last_key: 0,
1659 step: 0,
1660 acl: AC_ZSET_READ_SLOW,
1661 since: "6.2.0",
1662 complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
1663 summary: "Only the members all of these sorted sets have, with the scores combined.",
1664 group: "zset",
1665 },
1666 Spec {
1667 name: "zdiff",
1668 arity: -3,
1669 flags: READ_MOVABLE,
1670 first_key: 0,
1671 last_key: 0,
1672 step: 0,
1673 acl: AC_ZSET_READ_SLOW,
1674 since: "6.2.0",
1675 complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
1676 summary: "The members of the first that none of the rest have.",
1677 group: "zset",
1678 },
1679 Spec {
1680 name: "zunionstore",
1681 arity: -4,
1682 flags: WRITE_MOVABLE,
1683 first_key: 1,
1684 last_key: 1,
1685 step: 1,
1686 acl: AC_ZSET_WRITE_SLOW,
1687 since: "2.0.0",
1688 complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
1689 summary: "Store the union in another key and say how big it is.",
1690 group: "zset",
1691 },
1692 Spec {
1693 name: "zinterstore",
1694 arity: -4,
1695 flags: WRITE_MOVABLE,
1696 first_key: 1,
1697 last_key: 1,
1698 step: 1,
1699 acl: AC_ZSET_WRITE_SLOW,
1700 since: "2.0.0",
1701 complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
1702 summary: "Store the intersection in another key and say how big it is.",
1703 group: "zset",
1704 },
1705 Spec {
1706 name: "zdiffstore",
1707 arity: -4,
1708 flags: WRITE_MOVABLE,
1709 first_key: 1,
1710 last_key: 1,
1711 step: 1,
1712 acl: AC_ZSET_WRITE_SLOW,
1713 since: "6.2.0",
1714 complexity: "O(N)+O(M*log(M)) with N the total number of members and M the number in the answer",
1715 summary: "Store the difference in another key and say how big it is.",
1716 group: "zset",
1717 },
1718 Spec {
1719 name: "zintercard",
1720 arity: -3,
1721 flags: READ_MOVABLE,
1722 first_key: 0,
1723 last_key: 0,
1724 step: 0,
1725 acl: AC_ZSET_READ_SLOW,
1726 since: "7.0.0",
1727 complexity: "O(N*M) worst case, N the smallest input and M the number of inputs",
1728 summary: "How many members the intersection would have, without building it.",
1729 group: "zset",
1730 },
1731 Spec {
1732 name: "zrandmember",
1733 arity: -2,
1734 flags: READ_SLOW,
1735 first_key: 1,
1736 last_key: 1,
1737 step: 1,
1738 acl: AC_ZSET_READ_SLOW,
1739 since: "6.2.0",
1740 complexity: "O(N) with N the number of members drawn",
1741 summary: "Draw members at random, with or without replacement.",
1742 group: "zset",
1743 },
1744 Spec {
1745 name: "zscan",
1746 arity: -3,
1747 flags: READ_SLOW,
1748 first_key: 1,
1749 last_key: 1,
1750 step: 1,
1751 acl: AC_ZSET_READ_SLOW,
1752 since: "2.8.0",
1753 complexity: "O(1) per call, O(N) over a full walk",
1754 summary: "Walk the members and their scores a batch at a time.",
1755 group: "zset",
1756 },
1757 Spec {
1760 name: "zpopmin",
1761 arity: -2,
1762 flags: WRITE_FAST,
1763 first_key: 1,
1764 last_key: 1,
1765 step: 1,
1766 acl: AC_ZSET_WRITE_FAST,
1767 since: "5.0.0",
1768 complexity: "O(log(N)*M) with M the number of members popped",
1769 summary: "Take the lowest scoring members off and answer them.",
1770 group: "zset",
1771 },
1772 Spec {
1773 name: "zpopmax",
1774 arity: -2,
1775 flags: WRITE_FAST,
1776 first_key: 1,
1777 last_key: 1,
1778 step: 1,
1779 acl: AC_ZSET_WRITE_FAST,
1780 since: "5.0.0",
1781 complexity: "O(log(N)*M) with M the number of members popped",
1782 summary: "Take the highest scoring members off and answer them.",
1783 group: "zset",
1784 },
1785 Spec {
1788 name: "zmpop",
1789 arity: -4,
1790 flags: &["write", "movablekeys"],
1791 first_key: 0,
1792 last_key: 0,
1793 step: 0,
1794 acl: AC_ZSET_WRITE_SLOW,
1795 since: "7.0.0",
1796 complexity: "O(K) + O(M*log(N)) with K the keys named and M the count popped",
1797 summary: "Pop from the first of several sorted sets that has anything in it.",
1798 group: "zset",
1799 },
1800 Spec {
1803 name: "bzpopmin",
1804 arity: -3,
1805 flags: &["write", "blocking", "fast"],
1806 first_key: 1,
1807 last_key: -2,
1808 step: 1,
1809 acl: AC_ZSET_BLOCKING_FAST,
1810 since: "5.0.0",
1811 complexity: "O(log(N)) with N the size of the sorted set that answers",
1812 summary: "Take the lowest scoring member off the first sorted set that has one, waiting if none does.",
1813 group: "zset",
1814 },
1815 Spec {
1816 name: "bzpopmax",
1817 arity: -3,
1818 flags: &["write", "blocking", "fast"],
1819 first_key: 1,
1820 last_key: -2,
1821 step: 1,
1822 acl: AC_ZSET_BLOCKING_FAST,
1823 since: "5.0.0",
1824 complexity: "O(log(N)) with N the size of the sorted set that answers",
1825 summary: "Take the highest scoring member off the first sorted set that has one, waiting if none does.",
1826 group: "zset",
1827 },
1828 Spec {
1829 name: "bzmpop",
1830 arity: -5,
1831 flags: &["write", "blocking", "movablekeys"],
1832 first_key: 0,
1833 last_key: 0,
1834 step: 0,
1835 acl: AC_ZSET_BLOCKING_SLOW,
1836 since: "7.0.0",
1837 complexity: "O(K) + O(M*log(N)) with K the keys named and M the count popped",
1838 summary: "Pop from the first of several sorted sets that has anything, waiting if none does.",
1839 group: "zset",
1840 },
1841 Spec {
1843 name: "arset",
1844 arity: -4,
1845 flags: WRITE_FAST_OOM,
1846 first_key: 1,
1847 last_key: 1,
1848 step: 1,
1849 acl: AC_ARRAY_WRITE_FAST,
1850 since: "8.8.0",
1851 complexity: "O(N) with N the number of values",
1852 summary: "Write values into consecutive positions from an index.",
1853 group: "array",
1854 },
1855 Spec {
1856 name: "armset",
1857 arity: -4,
1858 flags: WRITE_FAST_OOM,
1859 first_key: 1,
1860 last_key: 1,
1861 step: 1,
1862 acl: AC_ARRAY_WRITE_FAST,
1863 since: "8.8.0",
1864 complexity: "O(N) with N the number of pairs",
1865 summary: "Write index and value pairs, which need not be neighbours.",
1866 group: "array",
1867 },
1868 Spec {
1869 name: "arget",
1870 arity: 3,
1871 flags: READ_FAST,
1872 first_key: 1,
1873 last_key: 1,
1874 step: 1,
1875 acl: AC_ARRAY_READ_FAST,
1876 since: "8.8.0",
1877 complexity: "O(1)",
1878 summary: "The value at one index, or a null if nothing is there.",
1879 group: "array",
1880 },
1881 Spec {
1882 name: "armget",
1883 arity: -3,
1884 flags: READ_FAST,
1885 first_key: 1,
1886 last_key: 1,
1887 step: 1,
1888 acl: AC_ARRAY_READ_FAST,
1889 since: "8.8.0",
1890 complexity: "O(N) with N the number of indices",
1891 summary: "The values at the indices named, in the order named.",
1892 group: "array",
1893 },
1894 Spec {
1895 name: "argetrange",
1896 arity: 4,
1897 flags: READ_SLOW,
1898 first_key: 1,
1899 last_key: 1,
1900 step: 1,
1901 acl: AC_ARRAY_READ_SLOW,
1902 since: "8.8.0",
1903 complexity: "O(N) with N the length of the range",
1904 summary: "One reply per position between two indices, holes included.",
1905 group: "array",
1906 },
1907 Spec {
1908 name: "arlen",
1909 arity: 2,
1910 flags: READ_FAST,
1911 first_key: 1,
1912 last_key: 1,
1913 step: 1,
1914 acl: AC_ARRAY_READ_FAST,
1915 since: "8.8.0",
1916 complexity: "O(1)",
1917 summary: "The highest populated index plus one.",
1918 group: "array",
1919 },
1920 Spec {
1921 name: "arcount",
1922 arity: 2,
1923 flags: READ_FAST,
1924 first_key: 1,
1925 last_key: 1,
1926 step: 1,
1927 acl: AC_ARRAY_READ_FAST,
1928 since: "8.8.0",
1929 complexity: "O(1)",
1930 summary: "How many indices hold something.",
1931 group: "array",
1932 },
1933 Spec {
1934 name: "ardel",
1935 arity: -3,
1936 flags: WRITE_FAST,
1937 first_key: 1,
1938 last_key: 1,
1939 step: 1,
1940 acl: AC_ARRAY_WRITE_FAST,
1941 since: "8.8.0",
1942 complexity: "O(N) with N the number of indices",
1943 summary: "Empty the indices named and say how many held something.",
1944 group: "array",
1945 },
1946 Spec {
1947 name: "ardelrange",
1948 arity: -4,
1949 flags: WRITE_SLOW,
1950 first_key: 1,
1951 last_key: 1,
1952 step: 1,
1953 acl: AC_ARRAY_WRITE_SLOW,
1954 since: "8.8.0",
1955 complexity: "O(N) with N the elements touched, not the span asked for",
1956 summary: "Empty one or more ranges of indices.",
1957 group: "array",
1958 },
1959 Spec {
1960 name: "arinsert",
1961 arity: -3,
1962 flags: WRITE_FAST_OOM,
1963 first_key: 1,
1964 last_key: 1,
1965 step: 1,
1966 acl: AC_ARRAY_WRITE_FAST,
1967 since: "8.8.0",
1968 complexity: "O(N) with N the number of values",
1969 summary: "Append values at the insert cursor.",
1970 group: "array",
1971 },
1972 Spec {
1973 name: "arring",
1974 arity: -4,
1975 flags: WRITE_OOM,
1976 first_key: 1,
1977 last_key: 1,
1978 step: 1,
1979 acl: AC_ARRAY_WRITE_SLOW,
1980 since: "8.8.0",
1981 complexity: "O(N) with N the values, plus the ring size when it changes",
1982 summary: "Append values into a ring of the given size.",
1983 group: "array",
1984 },
1985 Spec {
1986 name: "arnext",
1987 arity: 2,
1988 flags: READ_FAST,
1989 first_key: 1,
1990 last_key: 1,
1991 step: 1,
1992 acl: AC_ARRAY_READ_FAST,
1993 since: "8.8.0",
1994 complexity: "O(1)",
1995 summary: "The index the next append would write to.",
1996 group: "array",
1997 },
1998 Spec {
1999 name: "arseek",
2000 arity: 3,
2001 flags: WRITE_FAST,
2002 first_key: 1,
2003 last_key: 1,
2004 step: 1,
2005 acl: AC_ARRAY_WRITE_FAST,
2006 since: "8.8.0",
2007 complexity: "O(1)",
2008 summary: "Point the insert cursor at an index.",
2009 group: "array",
2010 },
2011 Spec {
2012 name: "arlastitems",
2013 arity: -3,
2014 flags: READ_SLOW,
2015 first_key: 1,
2016 last_key: 1,
2017 step: 1,
2018 acl: AC_ARRAY_READ_SLOW,
2019 since: "8.8.0",
2020 complexity: "O(N) with N the count asked for",
2021 summary: "The newest positions from the insert cursor, holes included.",
2022 group: "array",
2023 },
2024 Spec {
2025 name: "arscan",
2026 arity: -4,
2027 flags: READ_SLOW,
2028 first_key: 1,
2029 last_key: 1,
2030 step: 1,
2031 acl: AC_ARRAY_READ_SLOW,
2032 since: "8.8.0",
2033 complexity: "O(N) with N the elements found, not the span asked for",
2034 summary: "Index and value pairs for what a range holds, skipping holes.",
2035 group: "array",
2036 },
2037 Spec {
2038 name: "arop",
2039 arity: -5,
2040 flags: READ_SLOW,
2041 first_key: 1,
2042 last_key: 1,
2043 step: 1,
2044 acl: AC_ARRAY_READ_SLOW,
2045 since: "8.8.0",
2046 complexity: "O(N) with N the elements found, not the span asked for",
2047 summary: "One number out of a range, added up or compared or counted.",
2048 group: "array",
2049 },
2050 Spec {
2051 name: "arinfo",
2052 arity: -2,
2053 flags: READ_SLOW,
2054 first_key: 1,
2055 last_key: 1,
2056 step: 1,
2057 acl: AC_ARRAY_READ_SLOW,
2058 since: "8.8.0",
2059 complexity: "O(1), or O(N) with N the slices when FULL is given",
2060 summary: "The shape of the array, and what its slices look like.",
2061 group: "array",
2062 },
2063 Spec {
2065 name: "del",
2066 arity: -2,
2067 flags: &["write"],
2068 first_key: 1,
2069 last_key: -1,
2070 step: 1,
2071 acl: AC_KEY_WRITE_SLOW,
2072 since: "1.0.0",
2073 complexity: "O(N) in the number of keys.",
2074 summary: "Delete keys and say how many were there.",
2075 group: "keyspace",
2076 },
2077 Spec {
2078 name: "unlink",
2079 arity: -2,
2080 flags: &["write", "fast"],
2081 first_key: 1,
2082 last_key: -1,
2083 step: 1,
2084 acl: AC_KEY_WRITE_FAST,
2085 since: "4.0.0",
2086 complexity: "O(1) per key, since the freeing is not on this thread.",
2087 summary: "Delete keys and free them out of the way of the reply.",
2088 group: "keyspace",
2089 },
2090 Spec {
2091 name: "exists",
2092 arity: -2,
2093 flags: READ_FAST,
2094 first_key: 1,
2095 last_key: -1,
2096 step: 1,
2097 acl: AC_KEY_READ,
2098 since: "1.0.0",
2099 complexity: "O(N) in the number of keys.",
2100 summary: "Count how many of these keys are there, naming one twice counting twice.",
2101 group: "keyspace",
2102 },
2103 Spec {
2104 name: "type",
2105 arity: 2,
2106 flags: READ_FAST,
2107 first_key: 1,
2108 last_key: 1,
2109 step: 1,
2110 acl: AC_KEY_READ,
2111 since: "1.0.0",
2112 complexity: "O(1)",
2113 summary: "What kind of value is under a key, or none.",
2114 group: "keyspace",
2115 },
2116 Spec {
2117 name: "touch",
2118 arity: -2,
2119 flags: READ_FAST,
2120 first_key: 1,
2121 last_key: -1,
2122 step: 1,
2123 acl: AC_KEY_READ,
2124 since: "3.2.1",
2125 complexity: "O(N) in the number of keys.",
2126 summary: "Count how many of these keys are there, and move them up the eviction order.",
2127 group: "keyspace",
2128 },
2129 Spec {
2133 name: "scan",
2134 arity: -2,
2135 flags: &["readonly"],
2136 first_key: 0,
2137 last_key: 0,
2138 step: 0,
2139 acl: AC_KEY_READ_SLOW,
2140 since: "2.8.0",
2141 complexity: "O(1) a call, O(N) for a whole iteration",
2142 summary: "Walk part of the keyspace and say where to carry on from.",
2143 group: "keyspace",
2144 },
2145 Spec {
2146 name: "keys",
2147 arity: 2,
2148 flags: &["readonly"],
2149 first_key: 0,
2150 last_key: 0,
2151 step: 0,
2152 acl: AC_KEY_READ_ALL,
2153 since: "1.0.0",
2154 complexity: "O(N) in the number of keys.",
2155 summary: "Every key matching a pattern, in one reply.",
2156 group: "keyspace",
2157 },
2158 Spec {
2159 name: "randomkey",
2160 arity: 1,
2161 flags: &["readonly"],
2162 first_key: 0,
2163 last_key: 0,
2164 step: 0,
2165 acl: AC_KEY_READ_SLOW,
2166 since: "1.0.0",
2167 complexity: "O(1)",
2168 summary: "One key from the database, chosen at random.",
2169 group: "keyspace",
2170 },
2171 Spec {
2174 name: "rename",
2175 arity: 3,
2176 flags: &["write"],
2177 first_key: 1,
2178 last_key: 2,
2179 step: 1,
2180 acl: AC_KEY_WRITE_SLOW,
2181 since: "1.0.0",
2182 complexity: "O(1)",
2183 summary: "Move a key to another name, over whatever was there.",
2184 group: "keyspace",
2185 },
2186 Spec {
2187 name: "renamenx",
2188 arity: 3,
2189 flags: WRITE_FAST,
2190 first_key: 1,
2191 last_key: 2,
2192 step: 1,
2193 acl: AC_KEY_WRITE_FAST,
2194 since: "1.0.0",
2195 complexity: "O(1)",
2196 summary: "Move a key to another name, but only if that name is free.",
2197 group: "keyspace",
2198 },
2199 Spec {
2202 name: "copy",
2203 arity: -3,
2204 flags: &["write", "denyoom"],
2205 first_key: 1,
2206 last_key: 2,
2207 step: 1,
2208 acl: AC_KEY_WRITE_SLOW,
2209 since: "6.2.0",
2210 complexity: "O(N) in the size of the value.",
2211 summary: "Copy a value to another key, in this database or another one.",
2212 group: "keyspace",
2213 },
2214 Spec {
2217 name: "expire",
2218 arity: -3,
2219 flags: WRITE_FAST,
2220 first_key: 1,
2221 last_key: 1,
2222 step: 1,
2223 acl: AC_KEY_WRITE_FAST,
2224 since: "1.0.0",
2225 complexity: "O(1)",
2226 summary: "Put a deadline on a key, counted in seconds from now.",
2227 group: "keyspace",
2228 },
2229 Spec {
2230 name: "pexpire",
2231 arity: -3,
2232 flags: WRITE_FAST,
2233 first_key: 1,
2234 last_key: 1,
2235 step: 1,
2236 acl: AC_KEY_WRITE_FAST,
2237 since: "2.6.0",
2238 complexity: "O(1)",
2239 summary: "Put a deadline on a key, counted in milliseconds from now.",
2240 group: "keyspace",
2241 },
2242 Spec {
2243 name: "expireat",
2244 arity: -3,
2245 flags: WRITE_FAST,
2246 first_key: 1,
2247 last_key: 1,
2248 step: 1,
2249 acl: AC_KEY_WRITE_FAST,
2250 since: "1.2.0",
2251 complexity: "O(1)",
2252 summary: "Put a deadline on a key, as a unix time in seconds.",
2253 group: "keyspace",
2254 },
2255 Spec {
2256 name: "pexpireat",
2257 arity: -3,
2258 flags: WRITE_FAST,
2259 first_key: 1,
2260 last_key: 1,
2261 step: 1,
2262 acl: AC_KEY_WRITE_FAST,
2263 since: "2.6.0",
2264 complexity: "O(1)",
2265 summary: "Put a deadline on a key, as a unix time in milliseconds.",
2266 group: "keyspace",
2267 },
2268 Spec {
2269 name: "persist",
2270 arity: 2,
2271 flags: WRITE_FAST,
2272 first_key: 1,
2273 last_key: 1,
2274 step: 1,
2275 acl: AC_KEY_WRITE_FAST,
2276 since: "2.2.0",
2277 complexity: "O(1)",
2278 summary: "Take a key's deadline off, so it stops being temporary.",
2279 group: "keyspace",
2280 },
2281 Spec {
2282 name: "ttl",
2283 arity: 2,
2284 flags: READ_FAST,
2285 first_key: 1,
2286 last_key: 1,
2287 step: 1,
2288 acl: AC_KEY_READ,
2289 since: "1.0.0",
2290 complexity: "O(1)",
2291 summary: "How many seconds a key has left, -1 with no deadline, -2 if gone.",
2292 group: "keyspace",
2293 },
2294 Spec {
2295 name: "pttl",
2296 arity: 2,
2297 flags: READ_FAST,
2298 first_key: 1,
2299 last_key: 1,
2300 step: 1,
2301 acl: AC_KEY_READ,
2302 since: "2.6.0",
2303 complexity: "O(1)",
2304 summary: "How many milliseconds a key has left, -1 with no deadline, -2 if gone.",
2305 group: "keyspace",
2306 },
2307 Spec {
2308 name: "expiretime",
2309 arity: 2,
2310 flags: READ_FAST,
2311 first_key: 1,
2312 last_key: 1,
2313 step: 1,
2314 acl: AC_KEY_READ,
2315 since: "7.0.0",
2316 complexity: "O(1)",
2317 summary: "When a key falls due, as a unix time in seconds.",
2318 group: "keyspace",
2319 },
2320 Spec {
2321 name: "pexpiretime",
2322 arity: 2,
2323 flags: READ_FAST,
2324 first_key: 1,
2325 last_key: 1,
2326 step: 1,
2327 acl: AC_KEY_READ,
2328 since: "7.0.0",
2329 complexity: "O(1)",
2330 summary: "When a key falls due, as a unix time in milliseconds.",
2331 group: "keyspace",
2332 },
2333 Spec {
2337 name: "object",
2338 arity: -2,
2339 flags: &[],
2340 first_key: 0,
2341 last_key: 0,
2342 step: 0,
2343 acl: &["@slow"],
2344 since: "2.2.3",
2345 complexity: "O(1)",
2346 summary: "Look at the machinery under a key rather than at its value.",
2347 group: "keyspace",
2348 },
2349 Spec {
2353 name: "script",
2354 arity: -2,
2355 flags: &[],
2356 first_key: 0,
2357 last_key: 0,
2358 step: 0,
2359 acl: &["@slow"],
2360 since: "2.6.0",
2361 complexity: "O(1) for the subcommands that are here.",
2362 summary: "The script cache, which is empty and stays empty until M6.",
2363 group: "scripting",
2364 },
2365 Spec {
2366 name: "function",
2367 arity: -2,
2368 flags: &[],
2369 first_key: 0,
2370 last_key: 0,
2371 step: 0,
2372 acl: &["@slow"],
2373 since: "7.0.0",
2374 complexity: "O(1) for the subcommands that are here.",
2375 summary: "The function libraries, of which there are none until M6.",
2376 group: "scripting",
2377 },
2378 Spec {
2380 name: "ping",
2381 arity: -1,
2382 flags: &["fast"],
2383 first_key: 0,
2384 last_key: 0,
2385 step: 0,
2386 acl: AC_CONN,
2387 since: "1.0.0",
2388 complexity: "O(1)",
2389 summary: "Ask whether the server is answering.",
2390 group: "connection",
2391 },
2392 Spec {
2393 name: "echo",
2394 arity: 2,
2395 flags: &["loading", "stale", "fast"],
2396 first_key: 0,
2397 last_key: 0,
2398 step: 0,
2399 acl: AC_CONN,
2400 since: "1.0.0",
2401 complexity: "O(1)",
2402 summary: "Send a string back unchanged.",
2403 group: "connection",
2404 },
2405 Spec {
2406 name: "hello",
2407 arity: -1,
2408 flags: &[
2409 "noscript",
2410 "loading",
2411 "stale",
2412 "fast",
2413 "no_auth",
2414 "allow_busy",
2415 ],
2416 first_key: 0,
2417 last_key: 0,
2418 step: 0,
2419 acl: AC_CONN,
2420 since: "6.0.0",
2421 complexity: "O(1)",
2422 summary: "Agree on a protocol version and describe the server.",
2423 group: "connection",
2424 },
2425 Spec {
2426 name: "select",
2427 arity: 2,
2428 flags: &["loading", "stale", "fast"],
2429 first_key: 0,
2430 last_key: 0,
2431 step: 0,
2432 acl: AC_CONN,
2433 since: "1.0.0",
2434 complexity: "O(1)",
2435 summary: "Choose which database this connection works in.",
2436 group: "connection",
2437 },
2438 Spec {
2439 name: "reset",
2440 arity: 1,
2441 flags: &[
2442 "noscript",
2443 "loading",
2444 "stale",
2445 "fast",
2446 "no_auth",
2447 "allow_busy",
2448 ],
2449 first_key: 0,
2450 last_key: 0,
2451 step: 0,
2452 acl: AC_CONN,
2453 since: "6.2.0",
2454 complexity: "O(1)",
2455 summary: "Put the connection back the way it was opened.",
2456 group: "connection",
2457 },
2458 Spec {
2459 name: "quit",
2460 arity: -1,
2461 flags: &[
2462 "noscript",
2463 "loading",
2464 "stale",
2465 "fast",
2466 "no_auth",
2467 "allow_busy",
2468 ],
2469 first_key: 0,
2470 last_key: 0,
2471 step: 0,
2472 acl: AC_CONN,
2473 since: "1.0.0",
2474 complexity: "O(1)",
2475 summary: "Close the connection after the replies already queued.",
2476 group: "connection",
2477 },
2478 Spec {
2484 name: "command",
2485 arity: -1,
2486 flags: &["loading", "stale"],
2487 first_key: 0,
2488 last_key: 0,
2489 step: 0,
2490 acl: &["@slow", "@connection"],
2491 since: "2.8.13",
2492 complexity: "O(N) with N the number of commands",
2493 summary: "What this server can do, in the shape client libraries read.",
2494 group: "server",
2495 },
2496 Spec {
2497 name: "config",
2498 arity: -2,
2499 flags: &[],
2500 first_key: 0,
2501 last_key: 0,
2502 step: 0,
2503 acl: &["@slow"],
2504 since: "2.0.0",
2505 complexity: "Depends on the subcommand.",
2506 summary: "Read and change the settings a running server exposes.",
2507 group: "server",
2508 },
2509 Spec {
2510 name: "info",
2511 arity: -1,
2512 flags: &["loading", "stale"],
2513 first_key: 0,
2514 last_key: 0,
2515 step: 0,
2516 acl: &["@slow", "@dangerous"],
2517 since: "1.0.0",
2518 complexity: "O(1)",
2519 summary: "The server's own numbers, in sections.",
2520 group: "server",
2521 },
2522 Spec {
2523 name: "dbsize",
2524 arity: 1,
2525 flags: READ_FAST,
2526 first_key: 0,
2527 last_key: 0,
2528 step: 0,
2529 acl: AC_KEY_READ,
2530 since: "1.0.0",
2531 complexity: "O(1)",
2532 summary: "How many keys are in the database this connection is on.",
2533 group: "server",
2534 },
2535 Spec {
2536 name: "flushall",
2537 arity: -1,
2538 flags: &["write"],
2539 first_key: 0,
2540 last_key: 0,
2541 step: 0,
2542 acl: AC_KEY_FLUSH,
2543 since: "1.0.0",
2544 complexity: "O(N) in the number of keys in every database.",
2545 summary: "Empty every database.",
2546 group: "server",
2547 },
2548 Spec {
2549 name: "flushdb",
2550 arity: -1,
2551 flags: &["write"],
2552 first_key: 0,
2553 last_key: 0,
2554 step: 0,
2555 acl: AC_KEY_FLUSH,
2556 since: "1.0.0",
2557 complexity: "O(N) in the number of keys in this database.",
2558 summary: "Empty the database this connection is on.",
2559 group: "server",
2560 },
2561 Spec {
2565 name: "time",
2566 arity: 1,
2567 flags: &["loading", "stale", "fast"],
2568 first_key: 0,
2569 last_key: 0,
2570 step: 0,
2571 acl: &["@fast"],
2572 since: "2.6.0",
2573 complexity: "O(1)",
2574 summary: "The server's clock, as seconds and microseconds.",
2575 group: "server",
2576 },
2577];
2578
2579#[must_use]
2588pub fn lookup(name: &[u8]) -> Option<&'static Spec> {
2589 COMMANDS
2590 .iter()
2591 .find(|c| c.name.len() == name.len() && c.name.as_bytes().eq_ignore_ascii_case(name))
2592}
2593
2594#[must_use]
2596pub fn arity_ok(spec: &Spec, n: usize) -> bool {
2597 let n = n as i32;
2598 if spec.arity >= 0 {
2599 n == spec.arity
2600 } else {
2601 n >= -spec.arity
2602 }
2603}
2604
2605#[cfg(test)]
2606mod tests {
2607 use super::*;
2608
2609 #[test]
2610 fn every_name_is_lower_case_and_appears_once() {
2611 let mut seen = std::collections::BTreeSet::new();
2612 for c in COMMANDS {
2613 assert_eq!(
2614 c.name,
2615 c.name.to_lowercase(),
2616 "{} is not lower case",
2617 c.name
2618 );
2619 assert!(seen.insert(c.name), "{} is in the table twice", c.name);
2620 }
2621 }
2622
2623 #[test]
2624 fn lookup_ignores_case_and_does_not_match_a_prefix() {
2625 assert_eq!(lookup(b"GET").unwrap().name, "get");
2626 assert_eq!(lookup(b"gEt").unwrap().name, "get");
2627 assert!(lookup(b"ge").is_none());
2628 assert!(lookup(b"gets").is_none());
2629 }
2630
2631 #[test]
2632 fn arity_counts_the_command_name() {
2633 let get = lookup(b"get").unwrap();
2634 assert!(!arity_ok(get, 1));
2635 assert!(arity_ok(get, 2));
2636 assert!(!arity_ok(get, 3));
2637
2638 let set = lookup(b"set").unwrap();
2640 assert!(!arity_ok(set, 2));
2641 assert!(arity_ok(set, 3));
2642 assert!(arity_ok(set, 9));
2643 }
2644
2645 #[test]
2648 fn the_pair_commands_step_two_keys_at_a_time() {
2649 for name in [b"mset".as_slice(), b"msetnx"] {
2650 let c = lookup(name).unwrap();
2651 assert_eq!((c.first_key, c.last_key, c.step), (1, -1, 2));
2652 }
2653 let mget = lookup(b"mget").unwrap();
2654 assert_eq!((mget.first_key, mget.last_key, mget.step), (1, -1, 1));
2655 let msetex = lookup(b"msetex").unwrap();
2658 assert_eq!((msetex.first_key, msetex.last_key, msetex.step), (0, 0, 0));
2659 assert!(msetex.flags.contains(&"movablekeys"));
2660 }
2661}