All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.redisson.client.protocol.RedisCommands Maven / Gradle / Ivy

Go to download

Easy Redis Java client and Real-Time Data Platform. Valkey compatible. Sync/Async/RxJava3/Reactive API. Client side caching. Over 50 Redis based Java objects and services: JCache API, Apache Tomcat, Hibernate, Spring, Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Scheduler, RPC

There is a newer version: 3.40.2
Show newest version
/**
 * Copyright (c) 2013-2024 Nikita Koksharov
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.redisson.client.protocol;

import org.redisson.api.*;
import org.redisson.api.search.index.IndexInfo;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.DoubleCodec;
import org.redisson.client.codec.StringCodec;
import org.redisson.client.handler.State;
import org.redisson.client.protocol.convertor.*;
import org.redisson.client.protocol.decoder.*;
import org.redisson.client.protocol.pubsub.PubSubStatusDecoder;
import org.redisson.cluster.ClusterNodeInfo;
import org.redisson.codec.CompositeCodec;
import org.redisson.misc.RedisURI;

import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

/**
 * 
 * @author Nikita Koksharov
 *
 */
public interface RedisCommands {

    RedisStrictCommand DEBUG = new RedisStrictCommand("DEBUG");
    
    RedisStrictCommand GEOADD = new RedisStrictCommand("GEOADD");
    RedisStrictCommand GEOADD_BOOLEAN = new RedisStrictCommand<>("GEOADD", new BooleanReplayConvertor());
    RedisCommand GEODIST = new RedisCommand("GEODIST", new DoubleReplayConvertor());
    RedisCommand> GEORADIUS_RO = new RedisCommand>("GEORADIUS_RO", new ObjectListReplayDecoder());
    RedisCommand> GEORADIUSBYMEMBER_RO = new RedisCommand>("GEORADIUSBYMEMBER_RO", new ObjectListReplayDecoder());
    RedisCommand> GEOSEARCH = new RedisCommand<>("GEOSEARCH", new ObjectListReplayDecoder<>());
    RedisCommand GEORADIUS_STORE = new RedisCommand("GEORADIUS", new Long2MultiDecoder());
    RedisCommand GEORADIUSBYMEMBER_STORE = new RedisCommand("GEORADIUSBYMEMBER", new Long2MultiDecoder());
    RedisCommand GEOSEARCHSTORE_STORE = new RedisCommand("GEOSEARCHSTORE", new Long2MultiDecoder());

    RedisStrictCommand KEYSLOT = new RedisStrictCommand("CLUSTER", "KEYSLOT", new IntegerReplayConvertor());
    RedisStrictCommand TYPE = new RedisStrictCommand("TYPE", new TypeConvertor());

    RedisStrictCommand BITFIELD_LONG = new RedisStrictCommand<>("BITFIELD", null,
                                                    new ListFirstObjectDecoder(), new LongReplayConvertor());
    RedisStrictCommand BITFIELD_INT = new RedisStrictCommand<>("BITFIELD", null,
                                                    new ListFirstObjectDecoder(), new IntegerReplayConvertor(0));
    RedisStrictCommand BITFIELD_BYTE = new RedisStrictCommand<>("BITFIELD", null,
                                                    new ListFirstObjectDecoder(), new ByteReplayConvertor());
    RedisStrictCommand BITFIELD_SHORT = new RedisStrictCommand<>("BITFIELD", null,
                                                    new ListFirstObjectDecoder(), new ShortReplayConvertor());
    RedisStrictCommand BITFIELD_VOID = new RedisStrictCommand<>("BITFIELD", new VoidReplayConvertor());

    RedisStrictCommand GETBIT = new RedisStrictCommand("GETBIT", new BooleanReplayConvertor());
    RedisStrictCommand BITS_SIZE = new RedisStrictCommand("STRLEN", new BitsSizeReplayConvertor());
    RedisStrictCommand STRLEN = new RedisStrictCommand("STRLEN");
    RedisStrictCommand BITCOUNT = new RedisStrictCommand("BITCOUNT");
    RedisStrictCommand BITPOS = new RedisStrictCommand("BITPOS", new IntegerReplayConvertor());
    RedisStrictCommand SETBIT_VOID = new RedisStrictCommand("SETBIT", new VoidReplayConvertor());
    RedisStrictCommand SETBIT = new RedisStrictCommand("SETBIT", new BooleanReplayConvertor());
    RedisStrictCommand BITOP = new RedisStrictCommand("BITOP", new VoidReplayConvertor());

    RedisStrictCommand WAIT = new RedisStrictCommand("WAIT", new IntegerReplayConvertor());
    RedisCommand> WAITAOF = new RedisCommand("WAITAOF", new ObjectListReplayDecoder(), new IntegerReplayConvertor());
    RedisStrictCommand CLIENT_REPLY = new RedisStrictCommand("CLIENT", "REPLY", new VoidReplayConvertor());
    RedisStrictCommand ASKING = new RedisStrictCommand("ASKING", new VoidReplayConvertor());
    RedisStrictCommand READONLY = new RedisStrictCommand("READONLY", new VoidReplayConvertor());

    RedisCommand> ZRANDMEMBER_ENTRIES = new RedisCommand<>("ZRANDMEMBER", new ScoredSortedSetRandomMapDecoder());
    RedisCommand> ZRANDMEMBER = new RedisCommand<>("ZRANDMEMBER", new ObjectSetReplayDecoder<>());
    RedisCommand ZRANDMEMBER_SINGLE = new RedisCommand<>("ZRANDMEMBER");
    RedisStrictCommand> ZDIFF = new RedisStrictCommand<>("ZDIFF", new ObjectListReplayDecoder<>());
    RedisCommand> ZUNION = new RedisCommand<>("ZUNION", new ObjectListReplayDecoder<>());
    RedisCommand> ZINTER = new RedisCommand<>("ZINTER", new ObjectListReplayDecoder<>());
    RedisStrictCommand ZINTERCARD_INT = new RedisStrictCommand<>("ZINTERCARD", new IntegerReplayConvertor());
    RedisStrictCommand ZDIFFSTORE_INT = new RedisStrictCommand("ZDIFFSTORE", new IntegerReplayConvertor());
    RedisStrictCommand ZUNIONSTORE_INT = new RedisStrictCommand("ZUNIONSTORE", new IntegerReplayConvertor());
    RedisStrictCommand ZINTERSTORE_INT = new RedisStrictCommand("ZINTERSTORE", new IntegerReplayConvertor());
    RedisCommand ZADD_BOOL = new RedisCommand("ZADD", new BooleanAmountReplayConvertor());
    RedisCommand ZADD_NX_BOOL = new RedisCommand("ZADD", new BooleanAmountReplayConvertor());
    RedisCommand ZADD_BOOL_RAW = new RedisCommand("ZADD", new BooleanAmountReplayConvertor());
    RedisCommand ZADD_RAW = new RedisCommand("ZADD");
    RedisStrictCommand ZADD_INT = new RedisStrictCommand("ZADD", new IntegerReplayConvertor());
    RedisCommand ZADD = new RedisCommand("ZADD");
    RedisStrictCommand ZREM_INT = new RedisStrictCommand<>("ZREM", new IntegerReplayConvertor());
    RedisStrictCommand ZREM_LONG = new RedisStrictCommand("ZREM");
    RedisCommand ZREM = new RedisCommand("ZREM", new BooleanAmountReplayConvertor());
    RedisStrictCommand ZCARD_INT = new RedisStrictCommand("ZCARD", new IntegerReplayConvertor());
    RedisStrictCommand ZCARD = new RedisStrictCommand("ZCARD");
    RedisStrictCommand ZCOUNT = new RedisStrictCommand("ZCOUNT", new IntegerReplayConvertor());
    RedisStrictCommand ZLEXCOUNT = new RedisStrictCommand("ZLEXCOUNT", new IntegerReplayConvertor());
    RedisCommand ZSCORE_CONTAINS = new RedisCommand("ZSCORE", new BooleanNotNullReplayConvertor());
    RedisStrictCommand ZSCORE = new RedisStrictCommand("ZSCORE", new DoubleReplayConvertor());
    RedisStrictCommand ZRANK = new RedisStrictCommand("ZRANK");
    RedisCommand ZRANK_INT = new RedisCommand("ZRANK", new IntegerReplayConvertor());
    RedisCommand> ZRANK_ENTRY = new RedisCommand<>("ZRANK", new RankedEntryDecoder());
    RedisStrictCommand ZREVRANK = new RedisStrictCommand("ZREVRANK");
    RedisCommand ZREVRANK_INT = new RedisCommand("ZREVRANK", new IntegerReplayConvertor());
    RedisCommand> ZREVRANK_ENTRY = new RedisCommand<>("ZREVRANK", new RankedEntryDecoder());
    RedisCommand ZRANGE_SINGLE = new RedisCommand("ZRANGE", new ListFirstObjectDecoder());
    RedisCommand ZRANGE_SINGLE_ENTRY = new RedisCommand<>("ZRANGE", new ListFirstObjectDecoder(new ScoredSortedSetReplayDecoder()));
    RedisCommand ZRANGE_SINGLE_ENTRY_V2 = new RedisCommand<>("ZRANGE",
        new ListMultiDecoder2<>(new ListFirstObjectDecoder(), new ScoredSortedSetReplayDecoderV2()));
    RedisStrictCommand ZRANGE_SINGLE_SCORE = new RedisStrictCommand("ZRANGE", new ObjectFirstScoreReplayDecoder());
    RedisCommand> ZRANGE = new RedisCommand>("ZRANGE", new ObjectListReplayDecoder());
    RedisCommand ZRANGESTORE = new RedisCommand<>("ZRANGESTORE", new IntegerReplayConvertor());
    RedisCommand> ZPOPMIN = new RedisCommand>("ZPOPMIN", new ObjectListReplayDecoder());
    RedisCommand> ZPOPMAX = new RedisCommand>("ZPOPMAX", new ObjectListReplayDecoder());

    RedisCommand> BZMPOP_ENTRIES = new RedisCommand<>("BZMPOP",
            new ListMultiDecoder2(
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()) {
                        @Override
                        public Object decode(List parts, State state) {
                            for (int i = 0; i < parts.size(); i+= 2) {
                                List> entries = (List>) parts.get(i + 1);
                                List map = new ArrayList<>();
                                for (List entry : entries) {
                                    map.add(new ScoredEntry((Double) entry.get(1), entry.get(0)));
                                }
                                return map;
                            }
                            return Collections.emptyList();
                        }
                    },
                    new CodecDecoder(),
                    new CodecDecoder() {
                        @Override
                        public Decoder getDecoder(Codec codec, int paramNum, State state, long size) {
                            if ((paramNum + 1) % 2 == 0) {
                                return DoubleCodec.INSTANCE.getValueDecoder();
                            }
                            return codec.getValueDecoder();
                        }
                    }));
    RedisCommand>> ZMPOP = new RedisCommand<>("ZMPOP",
            new ListMultiDecoder2(
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()) {
                        @Override
                        public Object decode(List parts, State state) {
                            Map> result = new HashMap<>();
                            for (int i = 0; i < parts.size(); i+= 2) {
                                List> entries = (List>) parts.get(i + 1);
                                Map map = new HashMap<>(entries.size());
                                for (List entry : entries) {
                                    map.put(entry.get(0), entry.get(1));
                                }
                                result.put((String) parts.get(i), map);
                            }
                            return result;
                        }
                    },
                    new CodecDecoder(),
                    new CodecDecoder() {
                        @Override
                        public Decoder getDecoder(Codec codec, int paramNum, State state, long size) {
                            if ((paramNum + 1) % 2 == 0) {
                                return DoubleCodec.INSTANCE.getValueDecoder();
                            }
                            return codec.getValueDecoder();
                        }
                    }));

    RedisCommand> ZMPOP_VALUES = new RedisCommand<>("ZMPOP", new ListMultiDecoder2(
            new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()) {
                @Override
                public Object decode(List parts, State state) {
                    if (parts.isEmpty()) {
                        return parts;
                    }
                    return parts.get(1);
                }
            },
            new CodecDecoder(),
            new ListFirstObjectDecoder() {
                @Override
                public Decoder getDecoder(Codec codec, int paramNum, State state, long size) {
                    if ((paramNum + 1) % 2 == 0) {
                        return DoubleCodec.INSTANCE.getValueDecoder();
                    }
                    return codec.getValueDecoder();
                }
            }));

    RedisStrictCommand ZREMRANGEBYRANK = new RedisStrictCommand("ZREMRANGEBYRANK", new IntegerReplayConvertor());
    RedisStrictCommand ZREMRANGEBYSCORE = new RedisStrictCommand("ZREMRANGEBYSCORE", new IntegerReplayConvertor());
    RedisStrictCommand ZREMRANGEBYLEX = new RedisStrictCommand("ZREMRANGEBYLEX", new IntegerReplayConvertor());
    RedisCommand> ZRANGEBYLEX = new RedisCommand>("ZRANGEBYLEX", new ObjectListReplayDecoder());
    RedisCommand> ZREVRANGEBYLEX = new RedisCommand>("ZREVRANGEBYLEX", new ObjectListReplayDecoder());
    RedisCommand> ZRANGEBYSCORE = new RedisCommand>("ZRANGEBYSCORE", new ObjectSetReplayDecoder());
    RedisCommand> ZRANGEBYSCORE_LIST = new RedisCommand>("ZRANGEBYSCORE", new ObjectListReplayDecoder());
    RedisCommand> ZREVRANGE = new RedisCommand>("ZREVRANGE", new ObjectListReplayDecoder());
    RedisCommand> ZREVRANGEBYSCORE = new RedisCommand>("ZREVRANGEBYSCORE", new ObjectSetReplayDecoder());
    RedisCommand>> ZREVRANGE_ENTRY = new RedisCommand("ZREVRANGE", new ScoredSortedSetReplayDecoder());
    RedisCommand>> ZREVRANGE_ENTRY_V2 = new RedisCommand("ZREVRANGE",
            new ListMultiDecoder2(new CodecDecoder(), new ScoredSortedSetReplayDecoderV2<>()));
    RedisCommand>> ZREVRANGEBYSCORE_ENTRY = new RedisCommand("ZREVRANGEBYSCORE", new ScoredSortedSetReplayDecoder());
    RedisCommand>> ZREVRANGEBYSCORE_ENTRY_V2 = new RedisCommand("ZREVRANGEBYSCORE",
            new ListMultiDecoder2(new CodecDecoder(), new ScoredSortedSetReplayDecoderV2<>()));
    RedisCommand>> ZRANGE_ENTRY = new RedisCommand("ZRANGE", new ScoredSortedSetReplayDecoder());
    RedisCommand>> ZRANGE_ENTRY_V2 = new RedisCommand("ZRANGE",
            new ListMultiDecoder2(new CodecDecoder(), new ScoredSortedSetReplayDecoderV2<>()));
    RedisCommand>> ZRANGEBYSCORE_ENTRY = new RedisCommand("ZRANGEBYSCORE", new ScoredSortedSetReplayDecoder());
    RedisCommand>> ZRANGEBYSCORE_ENTRY_V2 = new RedisCommand("ZRANGEBYSCORE",
            new ListMultiDecoder2(new CodecDecoder(), new ScoredSortedSetReplayDecoderV2<>()));
    RedisCommand> ZSCAN = new RedisCommand>("ZSCAN", new ListMultiDecoder2(new ScoredSortedSetScanReplayDecoder(), new ScoredSortedSetScanDecoder()));
    RedisCommand> ZSCAN_ENTRY = new RedisCommand>("ZSCAN", new ListMultiDecoder2(new ScoredEntryScanDecoder<>(), new ScoredSortedSetScanDecoder<>()));
    RedisStrictCommand ZINCRBY = new RedisStrictCommand("ZINCRBY", new DoubleNullSafeReplayConvertor());

    RedisCommand> SCAN = new RedisCommand>("SCAN", new ListMultiDecoder2(new ListScanResultReplayDecoder(), new ObjectListReplayDecoder()));
    RedisStrictCommand RANDOM_KEY = new RedisStrictCommand("RANDOMKEY");
    RedisCommand PING = new RedisCommand("PING");
    RedisStrictCommand PING_BOOL = new RedisStrictCommand("PING", new BooleanNotNullReplayConvertor());

    RedisStrictCommand SHUTDOWN = new RedisStrictCommand("SHUTDOWN", new VoidReplayConvertor());
    RedisStrictCommand UNWATCH = new RedisStrictCommand("UNWATCH", new VoidReplayConvertor());
    RedisStrictCommand WATCH = new RedisStrictCommand("WATCH", new VoidReplayConvertor());
    RedisStrictCommand MULTI = new RedisStrictCommand("MULTI", new VoidReplayConvertor());
    RedisStrictCommand DISCARD = new RedisStrictCommand("DISCARD", new VoidReplayConvertor());
    RedisCommand> EXEC = new RedisCommand>("EXEC", new ObjectListReplayDecoder());

    RedisCommand SADD_BOOL = new RedisCommand("SADD", new BooleanAmountReplayConvertor());
    RedisCommand SADD = new RedisCommand("SADD", new IntegerReplayConvertor());
    RedisCommand> SPOP = new RedisCommand>("SPOP", new ObjectSetReplayDecoder());
    RedisCommand SPOP_SINGLE = new RedisCommand("SPOP");
    RedisCommand SADD_SINGLE = new RedisCommand("SADD", new BooleanReplayConvertor());
    RedisCommand SREM = new RedisCommand<>("SREM", new IntegerReplayConvertor());
    RedisCommand SREM_SINGLE = new RedisCommand("SREM", new BooleanAmountReplayConvertor());
    RedisCommand SMOVE = new RedisCommand("SMOVE", new BooleanReplayConvertor());
    RedisCommand> SMEMBERS = new RedisCommand>("SMEMBERS", new ObjectSetReplayDecoder());
    RedisCommand> SRANDMEMBER = new RedisCommand>("SRANDMEMBER", new ObjectSetReplayDecoder());
    RedisCommand SRANDMEMBER_SINGLE = new RedisCommand("SRANDMEMBER");
    RedisCommand> SSCAN = new RedisCommand>("SSCAN", new ListMultiDecoder2(new ListScanResultReplayDecoder(), new ObjectListReplayDecoder()));
    RedisCommand> EVAL_SCAN = new RedisCommand>("EVAL", new ListMultiDecoder2(new ListScanResultReplayDecoder(), new ObjectListReplayDecoder()));
    RedisCommand SISMEMBER = new RedisCommand("SISMEMBER", new BooleanReplayConvertor());
    RedisStrictCommand SCARD_INT = new RedisStrictCommand("SCARD", new IntegerReplayConvertor());
    RedisStrictCommand SINTERCARD_INT = new RedisStrictCommand<>("SINTERCARD", new IntegerReplayConvertor());
    RedisStrictCommand SCARD = new RedisStrictCommand("SCARD");
    RedisStrictCommand SUNIONSTORE_INT = new RedisStrictCommand("SUNIONSTORE", new IntegerReplayConvertor());
    RedisStrictCommand SDIFFSTORE_INT = new RedisStrictCommand("SDIFFSTORE", new IntegerReplayConvertor());
    RedisStrictCommand SINTERSTORE_INT = new RedisStrictCommand("SINTERSTORE", new IntegerReplayConvertor());
    RedisStrictCommand SUNIONSTORE = new RedisStrictCommand("SUNIONSTORE");
    RedisStrictCommand SINTERSTORE = new RedisStrictCommand("SINTERSTORE");
    RedisStrictCommand SDIFFSTORE = new RedisStrictCommand("SDIFFSTORE");
    RedisCommand> SUNION = new RedisCommand>("SUNION", new ObjectSetReplayDecoder());
    RedisCommand> SDIFF = new RedisCommand>("SDIFF", new ObjectSetReplayDecoder());
    RedisCommand> SINTER = new RedisCommand>("SINTER", new ObjectSetReplayDecoder());
    RedisCommand> SMISMEMBER = new RedisCommand<>("SMISMEMBER", new ObjectListReplayDecoder());

    RedisStrictCommand LPOS = new RedisStrictCommand<>("LPOS");
    RedisCommand LSET = new RedisCommand("LSET", new VoidReplayConvertor());
    RedisCommand LPOP = new RedisCommand("LPOP");
    RedisCommand> LPOP_LIST = new RedisCommand<>("LPOP", new ObjectListReplayDecoder<>());
    RedisCommand LREM = new RedisCommand("LREM", new BooleanAmountReplayConvertor());
    RedisCommand LINDEX = new RedisCommand("LINDEX");
    RedisCommand LMOVE = new RedisCommand("LMOVE");
    RedisCommand LINSERT_INT = new RedisCommand("LINSERT", new IntegerReplayConvertor());
    RedisStrictCommand LLEN_INT = new RedisStrictCommand("LLEN", new IntegerReplayConvertor());
    RedisStrictCommand LTRIM = new RedisStrictCommand("LTRIM", new VoidReplayConvertor());

    RedisStrictCommand PEXPIRE = new RedisStrictCommand("PEXPIRE", new BooleanReplayConvertor());
    RedisStrictCommand PEXPIREAT = new RedisStrictCommand("PEXPIREAT", new BooleanReplayConvertor());
    RedisStrictCommand PERSIST = new RedisStrictCommand("PERSIST", new BooleanReplayConvertor());
    RedisStrictCommand PTTL = new RedisStrictCommand("PTTL");
    RedisStrictCommand PEXPIRETIME = new RedisStrictCommand<>("PEXPIRETIME");

    RedisCommand RPOPLPUSH = new RedisCommand("RPOPLPUSH");
    RedisCommand BRPOPLPUSH = new RedisCommand("BRPOPLPUSH", new CodecDecoder() {
        @Override
        public Object decode(List parts, State state) {
            if (parts.isEmpty()) {
                return null;
            }
            return super.decode(parts, state);
        }
    });
    RedisCommand> BLPOP = new RedisCommand>("BLPOP", new ObjectListReplayDecoder());
    RedisCommand> BRPOP = new RedisCommand>("BRPOP", new ObjectListReplayDecoder());
    RedisCommand>> BZMPOP = new RedisCommand<>("BZMPOP", ZMPOP.getReplayMultiDecoder());
    RedisCommand> BZMPOP_SINGLE_LIST = new RedisCommand("BZMPOP", ZMPOP_VALUES.getReplayMultiDecoder(), new EmptyListConvertor());
    RedisCommand BLPOP_VALUE = new RedisCommand("BLPOP", new ListObjectDecoder(1));
    RedisCommand BLMOVE = new RedisCommand("BLMOVE", new ListFirstObjectDecoder());
    RedisCommand BRPOP_VALUE = new RedisCommand("BRPOP", new ListObjectDecoder(1));
    RedisCommand BZPOPMIN_VALUE = new RedisCommand("BZPOPMIN", new ScoredSortedSetPolledObjectDecoder());
    RedisCommand BZPOPMAX_VALUE = new RedisCommand("BZPOPMAX", new ScoredSortedSetPolledObjectDecoder());

    RedisCommand>> BLPOP_NAME = new RedisCommand<>("BLPOP",
                    new ListObjectDecoder(0) {
                        @Override
                        public Object decode(List parts, State state) {
                            if (parts.isEmpty()) {
                                return null;
                            }
                            return new org.redisson.api.Entry<>(parts.get(0), parts.get(1));
                        }
                    });

    RedisCommand>> BLMPOP = new RedisCommand<>("BLMPOP",
            new ListMultiDecoder2(
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()) {
                        @Override
                        public Object decode(List parts, State state) {
                            if (parts.isEmpty()) {
                                return null;
                            }
                            return Collections.singletonMap(parts.get(0), parts.get(1));
                        }
                    },
                    new CodecDecoder(),
                    new CodecDecoder() {
                        @Override
                        public Decoder getDecoder(Codec codec, int paramNum, State state, long size) {
                            if ((paramNum + 1) % 2 == 0) {
                                return DoubleCodec.INSTANCE.getValueDecoder();
                            }
                            return codec.getValueDecoder();
                        }
                    }));

    Set BLOCKING_COMMAND_NAMES = new HashSet(
            Arrays.asList(BRPOPLPUSH.getName(), BZPOPMIN_VALUE.getName(), BZPOPMAX_VALUE.getName(),
                    BLPOP.getName(), BRPOP.getName(), BLMOVE.getName(), BZMPOP_SINGLE_LIST.getName(), BLMPOP.getName()));

    RedisCommand PFADD = new RedisCommand("PFADD", new BooleanReplayConvertor());
    RedisStrictCommand PFCOUNT = new RedisStrictCommand("PFCOUNT");
    RedisStrictCommand PFMERGE = new RedisStrictCommand("PFMERGE", new VoidReplayConvertor());

    RedisCommand> SORT_LIST = new RedisCommand>("SORT", new ObjectListReplayDecoder());
    RedisCommand> SORT_SET = new RedisCommand>("SORT", new ObjectSetReplayDecoder());
    RedisCommand SORT_TO = new RedisCommand("SORT", new IntegerReplayConvertor());
    
    RedisCommand RPOP = new RedisCommand("RPOP");
    RedisCommand> RPOP_LIST = new RedisCommand<>("RPOP", new ObjectListReplayDecoder<>());
    RedisCommand LPUSH = new RedisCommand("LPUSH", new IntegerReplayConvertor());
    RedisCommand LPUSHX = new RedisCommand("LPUSHX", new IntegerReplayConvertor());
    RedisCommand LPUSH_BOOLEAN = new RedisCommand("LPUSH", new TrueReplayConvertor());
    RedisStrictCommand LPUSH_VOID = new RedisStrictCommand("LPUSH", new VoidReplayConvertor());
    RedisCommand> LRANGE = new RedisCommand>("LRANGE", new ObjectListReplayDecoder());
    RedisCommand> LRANGE_SET = new RedisCommand>("LRANGE", new ObjectSetReplayDecoder());
    RedisCommand RPUSH = new RedisCommand("RPUSH", new IntegerReplayConvertor());
    RedisCommand RPUSHX = new RedisCommand("RPUSHX", new IntegerReplayConvertor());
    RedisCommand RPUSH_BOOLEAN = new RedisCommand("RPUSH", new TrueReplayConvertor());
    RedisCommand RPUSH_VOID = new RedisCommand("RPUSH", new VoidReplayConvertor());

    RedisStrictCommand FUNCTION_DELETE = new RedisStrictCommand<>("FUNCTION", "DELETE", new VoidReplayConvertor());
    RedisStrictCommand FUNCTION_FLUSH = new RedisStrictCommand<>("FUNCTION", "FLUSH", new VoidReplayConvertor());
    RedisStrictCommand FUNCTION_KILL = new RedisStrictCommand<>("FUNCTION", "KILL", new VoidReplayConvertor());
    RedisStrictCommand FUNCTION_RESTORE = new RedisStrictCommand<>("FUNCTION", "RESTORE", new VoidReplayConvertor());
    RedisStrictCommand FUNCTION_LOAD = new RedisStrictCommand<>("FUNCTION", "LOAD", new VoidReplayConvertor());
    RedisStrictCommand FUNCTION_DUMP = new RedisStrictCommand<>("FUNCTION", "DUMP");
    RedisStrictCommand FUNCTION_STATS = new RedisStrictCommand<>("FUNCTION", "STATS",
            new ListMultiDecoder2(
                    new CodecDecoder() {
                        @Override
                        public Object decode(List parts, State state) {
                            FunctionStats.RunningFunction runningFunction = (FunctionStats.RunningFunction) parts.get(1);
                            Map engines = (Map) parts.get(3);
                            return new FunctionStats(runningFunction, engines);
                        }
                    },
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()) {
                        @Override
                        public Object decode(List parts, State state) {
                            if (parts.size() == 2) {
                                Map result = new HashMap<>();
                                List objects = (List) parts.get(1);
                                Long libraries = (Long) objects.get(1);
                                Long functions = (Long) objects.get(3);
                                String engine = (String) parts.get(0);
                                result.put(engine, new FunctionStats.Engine(libraries, functions));
                                return result;
                            }
                            String name = (String) parts.get(1);
                            List command = (List) parts.get(3);
                            Long duration = (Long) parts.get(5);
                            return new FunctionStats.RunningFunction(name, command, Duration.ofMillis(duration));
                        }
                    },
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder())));

    RedisStrictCommand FUNCTION_LIST = new RedisStrictCommand<>("FUNCTION", "LIST",
            new ListMultiDecoder2(
                    new CodecDecoder(),
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()) {
                        @Override
                        public Object decode(List parts, State state) {
                            String name = (String) parts.get(1);
                            String engine = (String) parts.get(3);
                            String code = null;
                            if (parts.size() > 6) {
                                code = (String) parts.get(6);
                            }
                            List functions = (List) parts.get(5);
                            return new FunctionLibrary(name, engine, code, functions);
                        }
                    },
                    new CodecDecoder(),
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()) {
                        @Override
                        public Object decode(List parts, State state) {
                            String functionName = (String) parts.get(1);
                            String functionDescription = (String) parts.get(3);
                            List functionFlags = ((List) parts.get(5)).stream()
                                    .map(s -> FunctionLibrary.Flag.valueOf(s.toUpperCase().replace("-", "_")))
                                    .collect(Collectors.toList());
                            return new FunctionLibrary.Function(functionName, functionDescription, functionFlags);
                        }
                    },
                    new CodecDecoder()));

    RedisStrictCommand FCALL_BOOLEAN_SAFE = new RedisStrictCommand("FCALL", new BooleanNullSafeReplayConvertor());
    RedisStrictCommand FCALL_LONG = new RedisStrictCommand("FCALL");
    RedisCommand> FCALL_LIST = new RedisCommand>("FCALL", new ObjectListReplayDecoder());
    RedisStrictCommand FCALL_STRING = new RedisStrictCommand("FCALL",
            new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()));
    RedisCommand FCALL_OBJECT = new RedisCommand("FCALL");
    RedisCommand FCALL_MAP_VALUE = new RedisCommand("FCALL", new MapValueDecoder());
    RedisCommand> FCALL_MAP_VALUE_LIST = new RedisCommand>("FCALL",
            new MapValueDecoder(new ObjectListReplayDecoder<>()));


    RedisStrictCommand SCRIPT_LOAD = new RedisStrictCommand("SCRIPT", "LOAD", new ObjectDecoder(new StringDataDecoder()));
    RedisStrictCommand SCRIPT_KILL = new RedisStrictCommand("SCRIPT", "KILL", new BooleanReplayConvertor());
    RedisStrictCommand SCRIPT_FLUSH = new RedisStrictCommand("SCRIPT", "FLUSH", new BooleanReplayConvertor());
    RedisStrictCommand> SCRIPT_EXISTS = new RedisStrictCommand>("SCRIPT", "EXISTS", new ObjectListReplayDecoder(), new BooleanReplayConvertor());

    RedisStrictCommand EVAL_BOOLEAN_AMOUNT = new RedisStrictCommand("EVAL", new BooleanAmountReplayConvertor());
    RedisStrictCommand EVAL_BOOLEAN = new RedisStrictCommand("EVAL", new BooleanReplayConvertor());
    RedisStrictCommand EVAL_BOOLEAN_SAFE = new RedisStrictCommand("EVAL", new BooleanNullSafeReplayConvertor());
    RedisStrictCommand EVAL_NULL_BOOLEAN = new RedisStrictCommand("EVAL", new BooleanNullReplayConvertor());
    RedisStrictCommand EVAL_STRING = new RedisStrictCommand("EVAL",
            new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()));
    RedisStrictCommand EVAL_INTEGER = new RedisStrictCommand("EVAL", new IntegerReplayConvertor());
    RedisStrictCommand EVAL_DOUBLE = new RedisStrictCommand("EVAL", new DoubleNullSafeReplayConvertor());
    RedisStrictCommand EVAL_LONG = new RedisStrictCommand("EVAL");
    RedisStrictCommand EVAL_LONG_SAFE = new RedisStrictCommand("EVAL", new LongReplayConvertor());
    RedisStrictCommand EVAL_VOID = new RedisStrictCommand("EVAL", new VoidReplayConvertor());
    RedisCommand EVAL_FIRST_LIST = new RedisCommand("EVAL", new ListFirstObjectDecoder());
    RedisCommand EVAL_FIRST_LIST_ENTRY = new RedisCommand("EVAL", new ListFirstObjectDecoder(new ScoredSortedSetReplayDecoder()));
    RedisCommand> EVAL_LIST = new RedisCommand>("EVAL", new ObjectListReplayDecoder());
    RedisCommand> EVAL_LIST_ENTRY = new RedisCommand<>("EVAL", new ScoredSortedSetReplayDecoder());
    RedisCommand> EVAL_LIST_REVERSE = new RedisCommand>("EVAL", new ObjectListReplayDecoder<>(true));
    RedisCommand> EVAL_INT_LIST = new RedisCommand("EVAL", new ObjectListReplayDecoder(), new IntegerReplayConvertor());

    RedisCommand> EVAL_LONG_LIST = new RedisCommand("EVAL", new ObjectListReplayDecoder());
    RedisCommand> EVAL_SET = new RedisCommand>("EVAL", new ObjectSetReplayDecoder());
    RedisCommand EVAL_OBJECT = new RedisCommand("EVAL");
    RedisCommand EVAL_MAP_VALUE = new RedisCommand("EVAL", new MapValueDecoder());
    RedisCommand>> EVAL_MAP_ENTRY = new RedisCommand>>("EVAL",
            new ObjectMapEntryReplayDecoder());
    RedisCommand> EVAL_MAP = new RedisCommand>("EVAL",
            new ObjectMapReplayDecoder());
    RedisCommand> EVAL_MAP_VALUE_LIST = new RedisCommand>("EVAL",
            new MapValueDecoder(new ObjectListReplayDecoder<>()));
    RedisCommand> EVAL_MAP_VALUE_SET = new RedisCommand>("EVAL",
            new MapValueDecoder(new ObjectSetReplayDecoder<>()));
    RedisCommand> EVAL_MAP_KEY_SET = new RedisCommand>("EVAL",
            new MapKeyDecoder(new ObjectSetReplayDecoder<>()));

    RedisStrictCommand INCR = new RedisStrictCommand("INCR");
    RedisStrictCommand INCRBY = new RedisStrictCommand("INCRBY");
    RedisStrictCommand INCRBYFLOAT = new RedisStrictCommand("INCRBYFLOAT", new DoubleNullSafeReplayConvertor());
    RedisStrictCommand DECR = new RedisStrictCommand("DECR");


    RedisStrictCommand> HELLO = new RedisStrictCommand<>("HELLO", new StringMapReplayDecoder());
    RedisStrictCommand AUTH = new RedisStrictCommand("AUTH", new VoidReplayConvertor());
    RedisStrictCommand SELECT = new RedisStrictCommand("SELECT", new VoidReplayConvertor());

    RedisStrictCommand CLIENT_ID = new RedisStrictCommand<>("CLIENT", "ID");

    RedisStrictCommand CLIENT_TRACKING = new RedisStrictCommand("CLIENT", "TRACKING", new VoidReplayConvertor());

    RedisStrictCommand CLIENT_SETNAME = new RedisStrictCommand("CLIENT", "SETNAME", new VoidReplayConvertor());
    RedisStrictCommand CLIENT_GETNAME = new RedisStrictCommand("CLIENT", "GETNAME", new ObjectDecoder(new StringDataDecoder()));
    RedisStrictCommand FLUSHDB = new RedisStrictCommand("FLUSHDB", new VoidReplayConvertor());
    RedisStrictCommand SWAPDB = new RedisStrictCommand("SWAPDB", new VoidReplayConvertor());
    RedisStrictCommand FLUSHALL = new RedisStrictCommand("FLUSHALL", new VoidReplayConvertor());

    RedisStrictCommand SAVE = new RedisStrictCommand("SAVE", new VoidReplayConvertor());
    RedisStrictCommand LASTSAVE = new RedisStrictCommand("LASTSAVE");
    RedisStrictCommand LASTSAVE_INSTANT = new RedisStrictCommand<>("LASTSAVE", new InstantReplyConvertor());
    RedisStrictCommand BGSAVE = new RedisStrictCommand("BGSAVE", new VoidReplayConvertor());
    RedisStrictCommand BGREWRITEAOF = new RedisStrictCommand("BGREWRITEAOF", new VoidReplayConvertor());
    
    RedisStrictCommand FLUSHDB_ASYNC = new RedisStrictCommand("FLUSHDB", "ASYNC", new VoidReplayConvertor());
    RedisStrictCommand FLUSHALL_ASYNC = new RedisStrictCommand("FLUSHALL", "ASYNC", new VoidReplayConvertor());

    RedisStrictCommand> KEYS = new RedisStrictCommand>("KEYS", new StringListReplayDecoder());
    RedisCommand> MGET = new RedisCommand>("MGET", new ObjectListReplayDecoder());
    RedisStrictCommand MSET = new RedisStrictCommand("MSET", new VoidReplayConvertor());
    RedisStrictCommand MSETNX = new RedisStrictCommand("MSETNX", new BooleanReplayConvertor());

    RedisCommand HPERSIST = new RedisCommand("HPERSIST", new ListFirstObjectDecoder(), new Convertor() {
        @Override
        public Boolean convert(Object obj) {
            Long val = (Long) obj;
            if (val == -2) {
                return null;
            }

            return val == 1;
        }
    });
    RedisCommand HPTTL = new RedisCommand("HPTTL", new ListFirstObjectDecoder(), new LongReplayConvertor());
    RedisStrictCommand HSETNX = new RedisStrictCommand("HSETNX", new BooleanReplayConvertor());
    RedisStrictCommand HSET = new RedisStrictCommand("HSET", new BooleanReplayConvertor());
    RedisStrictCommand HSET_VOID = new RedisStrictCommand("HSET", new VoidReplayConvertor());
    RedisCommand> HSCAN =
            new RedisCommand>("HSCAN",
                        new ListMultiDecoder2(new MapScanResultReplayDecoder(),
                                new ObjectMapReplayDecoder()));
    RedisCommand> HRANDFIELD = new RedisCommand<>("HRANDFIELD",
                        new ObjectMapReplayDecoder(), new EmptyMapConvertor());

    RedisCommand> HRANDFIELD_V2 = new RedisCommand("HRANDFIELD",
                        new ListMultiDecoder2<>(new MapMergeDecoder(), new ObjectMapReplayDecoder()), new EmptyMapConvertor());
    RedisCommand> HRANDFIELD_KEYS = new RedisCommand<>("HRANDFIELD",
                        new MapKeyDecoder(new ObjectSetReplayDecoder<>()), new EmptySetConvertor());
    RedisCommand> HGETALL = new RedisCommand>("HGETALL",
                        new ObjectMapReplayDecoder());
    RedisCommand>> HGETALL_ENTRY = new RedisCommand>>("HGETALL",
                        new ObjectMapEntryReplayDecoder());
    RedisCommand> HVALS = new RedisCommand>("HVALS",
                        new MapValueDecoder(new ObjectListReplayDecoder<>()));
    RedisCommand HEXISTS = new RedisCommand("HEXISTS", new BooleanReplayConvertor());
    RedisStrictCommand HLEN = new RedisStrictCommand("HLEN", new IntegerReplayConvertor());
    RedisCommand HSTRLEN = new RedisCommand("HSTRLEN", new IntegerReplayConvertor());
    RedisStrictCommand HLEN_LONG = new RedisStrictCommand("HLEN");
    RedisCommand> HKEYS = new RedisCommand>("HKEYS",
                        new MapKeyDecoder(new ObjectSetReplayDecoder()));
    RedisCommand> HMGET = new RedisCommand>("HMGET", new ObjectListReplayDecoder());
    RedisCommand HMSET = new RedisCommand("HMSET", new VoidReplayConvertor());
    RedisCommand HGET = new RedisCommand("HGET", new MapValueDecoder());
    RedisCommand HDEL = new RedisStrictCommand("HDEL");

    RedisStrictCommand DEL = new RedisStrictCommand("DEL");
    RedisStrictCommand DBSIZE = new RedisStrictCommand("DBSIZE");
    RedisStrictCommand DEL_BOOL = new RedisStrictCommand("DEL", new BooleanNullSafeReplayConvertor());
    RedisStrictCommand DEL_OBJECTS = new RedisStrictCommand("DEL", new BooleanAmountReplayConvertor());
    RedisStrictCommand DEL_VOID = new RedisStrictCommand("DEL", new VoidReplayConvertor());
    
    RedisStrictCommand UNLINK = new RedisStrictCommand("UNLINK");
    RedisStrictCommand UNLINK_BOOL = new RedisStrictCommand("UNLINK", new BooleanNullSafeReplayConvertor());

    RedisCommand DUMP = new RedisCommand("DUMP");
    RedisStrictCommand RESTORE = new RedisStrictCommand("RESTORE", new VoidReplayConvertor());
    
    RedisCommand GET = new RedisCommand("GET");
    RedisCommand GETEX = new RedisCommand("GETEX");
    RedisCommand GETRANGE = new RedisCommand("GETRANGE");
    RedisCommand SETRANGE = new RedisCommand("SETRANGE");
    RedisStrictCommand GET_LONG = new RedisStrictCommand("GET", new LongReplayConvertor());
    RedisStrictCommand GET_INTEGER = new RedisStrictCommand("GET", new IntegerReplayConvertor(0));
    RedisStrictCommand GET_DOUBLE = new RedisStrictCommand("GET", new DoubleNullSafeReplayConvertor());
    RedisCommand GETSET = new RedisCommand("GETSET");
    RedisCommand LCS = new RedisCommand<>("LCS");
    RedisCommand GETSET_LONG = new RedisCommand<>("GETSET", new LongReplayConvertor());
    RedisCommand GETSET_DOUBLE = new RedisCommand<>("GETSET", new DoubleReplayConvertor(0D));
    RedisCommand SET = new RedisCommand("SET", new VoidReplayConvertor());
    RedisCommand APPEND = new RedisCommand("APPEND", new VoidReplayConvertor());
    RedisCommand SET_BOOLEAN = new RedisCommand("SET", new BooleanNotNullReplayConvertor());
    RedisCommand SETNX = new RedisCommand("SETNX", new BooleanReplayConvertor());
    RedisCommand PSETEX = new RedisCommand("PSETEX", new VoidReplayConvertor());

    RedisCommand>> XRANGE = new RedisCommand<>("XRANGE",
            new ListMultiDecoder2(
                    new ObjectMapReplayDecoder2(),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new StreamObjectMapReplayDecoder()));

    RedisCommand>> XREVRANGE =
                new RedisCommand<>("XREVRANGE", XRANGE.getReplayMultiDecoder());
    
    RedisCommand>>> XREAD = new RedisCommand<>("XREAD",
            new ListMultiDecoder2(
                    new StreamResultDecoder(false),
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new StreamObjectMapReplayDecoder()));
            
    RedisCommand>>> XREAD_BLOCKING = new RedisCommand<>("XREAD", XREAD.getReplayMultiDecoder());

    RedisCommand>>> XREAD_V2 = new RedisCommand<>("XREAD",
            new ListMultiDecoder2(
                    new StreamResultDecoderV2(false),
                    new CodecDecoder(),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new StreamObjectMapReplayDecoder()), new EmptyMapConvertor());

    RedisCommand>>> XREAD_BLOCKING_V2 = new RedisCommand<>("XREAD", XREAD_V2.getReplayMultiDecoder());

    RedisCommand>> XREAD_SINGLE_V2 = new RedisCommand<>("XREAD",
            new ListMultiDecoder2(
                    new StreamResultDecoderV2(true),
                    new CodecDecoder(),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new StreamObjectMapReplayDecoder()), new EmptyMapConvertor());
    
    RedisCommand>> XREAD_BLOCKING_SINGLE_V2 =
                new RedisCommand<>("XREAD", XREAD_SINGLE_V2.getReplayMultiDecoder());

    RedisCommand>> XREAD_SINGLE = new RedisCommand<>("XREAD",
            new ListMultiDecoder2(
                    new StreamResultDecoder(true),
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new StreamObjectMapReplayDecoder()));

    RedisCommand>> XREAD_BLOCKING_SINGLE =
                new RedisCommand<>("XREAD", XREAD_SINGLE.getReplayMultiDecoder());

    RedisCommand>>> XREADGROUP_V2 =
            new RedisCommand<>("XREADGROUP", XREAD_V2.getReplayMultiDecoder());

    RedisCommand>>> XREADGROUP_BLOCKING_V2 =
                new RedisCommand<>("XREADGROUP", XREADGROUP_V2.getReplayMultiDecoder());

    RedisCommand>>> XREADGROUP =
            new RedisCommand<>("XREADGROUP", XREAD.getReplayMultiDecoder());

    RedisCommand>>> XREADGROUP_BLOCKING =
                new RedisCommand<>("XREADGROUP", XREADGROUP.getReplayMultiDecoder());

    RedisCommand>> XREADGROUP_SINGLE = new RedisCommand<>("XREADGROUP",
            new ListMultiDecoder2(
                    new StreamResultDecoder(true),
                    new ObjectDecoder(StringCodec.INSTANCE.getValueDecoder()),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new StreamObjectMapReplayDecoder()));

    RedisCommand>> XREADGROUP_SINGLE_V2 = new RedisCommand<>("XREADGROUP",
            new ListMultiDecoder2(
                    new StreamResultDecoderV2(true),
                    new CodecDecoder(),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new StreamObjectMapReplayDecoder()));

    RedisCommand> XINFO_GROUPS = new RedisCommand<>("XINFO", "GROUPS",
            new ListMultiDecoder2(new ObjectListReplayDecoder(), new StreamGroupInfoDecoder()));

    RedisCommand> XINFO_CONSUMERS = new RedisCommand<>("XINFO", "CONSUMERS",
            new ListMultiDecoder2(new ObjectListReplayDecoder(), new StreamConsumerInfoDecoder()));

    RedisCommand XCLAIM_IDS = new RedisCommand<>("XCLAIM", new ObjectDecoder(new StreamIdDecoder()));
    
    RedisCommand>> XCLAIM = new RedisCommand<>("XCLAIM",
            new ListMultiDecoder2(
                    new ObjectMapReplayDecoder2(),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new StreamObjectMapReplayDecoder()));

    RedisCommand XAUTOCLAIM_IDS = new RedisCommand<>("XAUTOCLAIM",
            new ListMultiDecoder2(new FastAutoClaimDecoder(), new ObjectListReplayDecoder(false, new StreamIdDecoder())));

    RedisCommand>> XAUTOCLAIM = new RedisCommand<>("XAUTOCLAIM",
            new ListMultiDecoder2(
                    new AutoClaimDecoder(),
                    new AutoClaimMapReplayDecoder(),
                    new ObjectDecoder(new StreamIdDecoder()),
                    new StreamObjectMapReplayDecoder()));

    RedisCommand>> XREADGROUP_BLOCKING_SINGLE = new RedisCommand<>("XREADGROUP",
            XREADGROUP_SINGLE.getReplayMultiDecoder());

    RedisCommand>> XREADGROUP_BLOCKING_SINGLE_V2 = new RedisCommand<>("XREADGROUP",
            XREADGROUP_SINGLE_V2.getReplayMultiDecoder());

    Set BLOCKING_COMMANDS = new HashSet<>(Arrays.asList(
            XREAD_BLOCKING_SINGLE, XREAD_BLOCKING, XREADGROUP_BLOCKING_SINGLE, XREADGROUP_BLOCKING,
            XREAD_BLOCKING_SINGLE_V2, XREAD_BLOCKING_V2, XREADGROUP_BLOCKING_SINGLE_V2, XREADGROUP_BLOCKING_V2));
    
    RedisStrictCommand XADD = new RedisStrictCommand("XADD", new StreamIdConvertor());
    RedisStrictCommand XGROUP = new RedisStrictCommand("XGROUP", new VoidReplayConvertor());
    RedisStrictCommand XGROUP_LONG = new RedisStrictCommand("XGROUP");
    RedisStrictCommand XADD_VOID = new RedisStrictCommand("XADD", new VoidReplayConvertor());
    RedisStrictCommand XLEN = new RedisStrictCommand("XLEN");
    RedisStrictCommand XACK = new RedisStrictCommand("XACK");
    RedisStrictCommand XDEL = new RedisStrictCommand("XDEL");
    RedisStrictCommand XTRIM = new RedisStrictCommand("XTRIM");
    RedisCommand XPENDING = new RedisCommand("XPENDING",
            new ListMultiDecoder2(new PendingResultDecoder(), new ObjectListReplayDecoder(), new ObjectListReplayDecoder()),
            new EmptyListConvertor());
    RedisCommand XPENDING_ENTRIES = new RedisCommand("XPENDING", 
            new PendingEntryDecoder());
    
    RedisStrictCommand TOUCH_LONG = new RedisStrictCommand("TOUCH", new LongReplayConvertor());
    RedisStrictCommand TOUCH = new RedisStrictCommand("TOUCH", new BooleanReplayConvertor());
    RedisStrictCommand EXISTS_LONG = new RedisStrictCommand("EXISTS", new LongReplayConvertor());
    RedisStrictCommand EXISTS = new RedisStrictCommand("EXISTS", new BooleanAmountReplayConvertor());
    RedisStrictCommand NOT_EXISTS = new RedisStrictCommand("EXISTS", new BooleanNumberReplayConvertor(1L));

    RedisStrictCommand OBJECT_IDLETIME = new RedisStrictCommand("OBJECT", "IDLETIME", new LongReplayConvertor());
    RedisStrictCommand MEMORY_USAGE = new RedisStrictCommand("MEMORY", "USAGE", new LongReplayConvertor());
    RedisStrictCommand> MEMORY_STATS = new RedisStrictCommand<>("MEMORY", "STATS", new StringMapReplayDecoder());
    RedisStrictCommand RENAMENX = new RedisStrictCommand("RENAMENX", new BooleanReplayConvertor());
    RedisStrictCommand RENAME = new RedisStrictCommand("RENAME", new VoidReplayConvertor());
    RedisStrictCommand MOVE = new RedisStrictCommand("MOVE", new BooleanReplayConvertor());
    RedisStrictCommand COPY = new RedisStrictCommand("COPY", new BooleanReplayConvertor());
    RedisStrictCommand MIGRATE = new RedisStrictCommand("MIGRATE", new VoidReplayConvertor());
    RedisStrictCommand QUIT = new RedisStrictCommand("QUIT", new VoidReplayConvertor());

    RedisStrictCommand PUBLISH = new RedisStrictCommand("PUBLISH");

    RedisStrictCommand SPUBLISH = new RedisStrictCommand("SPUBLISH");
    RedisCommand PUBSUB_NUMSUB = new RedisCommand<>("PUBSUB", "NUMSUB", new ListObjectDecoder<>(1));
    RedisCommand> PUBSUB_CHANNELS = new RedisStrictCommand<>("PUBSUB", "CHANNELS", new StringListReplayDecoder());
    RedisCommand> PUBSUB_SHARDCHANNELS = new RedisStrictCommand<>("PUBSUB", "SHARDCHANNELS", new StringListReplayDecoder());
    RedisCommand PUBSUB_SHARDNUMSUB = new RedisCommand<>("PUBSUB", "SHARDNUMSUB", new ListObjectDecoder<>(1));

    RedisCommand SSUBSCRIBE = new RedisCommand<>("SSUBSCRIBE", new PubSubStatusDecoder());
    RedisCommand SUBSCRIBE = new RedisCommand<>("SUBSCRIBE", new PubSubStatusDecoder());
    RedisCommand UNSUBSCRIBE = new RedisCommand<>("UNSUBSCRIBE", new PubSubStatusDecoder());
    RedisCommand SUNSUBSCRIBE = new RedisCommand<>("SUNSUBSCRIBE", new PubSubStatusDecoder());
    RedisCommand PSUBSCRIBE = new RedisCommand<>("PSUBSCRIBE", new PubSubStatusDecoder());
    RedisCommand PUNSUBSCRIBE = new RedisCommand<>("PUNSUBSCRIBE", new PubSubStatusDecoder());

    Set PUBSUB_COMMANDS = Collections.unmodifiableSet(new HashSet<>(
            Arrays.asList(PSUBSCRIBE.getName(), SUBSCRIBE.getName(), PUNSUBSCRIBE.getName(),
                    UNSUBSCRIBE.getName(), SSUBSCRIBE.getName(), SUNSUBSCRIBE.getName())));

    Set SCAN_COMMANDS = new HashSet(
            Arrays.asList(HSCAN.getName(), SCAN.getName(), ZSCAN.getName(), SSCAN.getName()));

    RedisStrictCommand> CLUSTER_NODES = new RedisStrictCommand>("CLUSTER", "NODES",
            new ObjectDecoder(new ClusterNodesDecoder(false)));
    RedisStrictCommand> CLUSTER_NODES_SSL = new RedisStrictCommand>("CLUSTER", "NODES",
            new ObjectDecoder(new ClusterNodesDecoder(true)));
    RedisStrictCommand TIME_LONG = new RedisStrictCommand("TIME", new TimeLongObjectDecoder());
    RedisStrictCommand