1 /*
2  * Hunt - A redis client library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11  
12 module hunt.redis.BinaryRedisCluster;
13 
14 import hunt.redis.RedisSlotBasedConnectionHandler;
15 import hunt.redis.commands.BinaryRedisClusterCommands;
16 import hunt.redis.commands.RedisClusterBinaryScriptingCommands;
17 import hunt.redis.commands.MultiKeyBinaryRedisClusterCommands;
18 import hunt.redis.HostAndPort;
19 import hunt.redis.Redis;
20 import hunt.redis.RedisClusterCommand;
21 import hunt.redis.RedisPool;
22 import hunt.redis.Protocol;
23 import hunt.redis.RedisClusterConnectionHandler;
24 import hunt.redis.params.GeoRadiusParam;
25 import hunt.redis.params.SetParams;
26 import hunt.redis.params.ZAddParams;
27 import hunt.redis.params.ZIncrByParams;
28 import hunt.redis.util.RedisClusterHashTagUtil;
29 import hunt.redis.util.KeyMergeUtil;
30 import hunt.redis.util.SafeEncoder;
31 
32 import hunt.util.Common;
33 import hunt.collection.Collection;
34 import hunt.collection.List;
35 import hunt.collection.Map;
36 import hunt.collection.Set;
37 import hunt.pool.impl.GenericObjectPoolConfig;
38 
39 import hunt.Long;
40 
41 private template ClusterBinaryCommandTemplate(string name, R, string[] args) {
42     import std.format;
43 
44     enum string statementBlock = q{
45         scope RedisClusterCommand!(%2$s) command = 
46                 new class(connectionHandler, maxAttempts) RedisClusterCommand!(%2$s) {
47 
48             this(RedisClusterConnectionHandler connectionHandler, int maxAttempts) {
49                 super(connectionHandler, maxAttempts);
50             }
51 
52             override %2$s execute(Redis connection) {
53                 return connection.%1$s(%3$-(%s, %));
54             }
55         };
56 
57         return command.runBinary(%4$s);
58     }.format(name, R.stringof, args, args[0]);
59 
60     // pragma(msg, statementBlock);
61     alias ClusterBinaryCommandTemplate = statementBlock;
62 }
63 
64 
65 /**
66  * 
67  */
68 class BinaryRedisCluster : BinaryRedisClusterCommands, MultiKeyBinaryRedisClusterCommands, 
69         RedisClusterBinaryScriptingCommands, Closeable {
70 
71     enum int HASHSLOTS = 16384;
72     protected enum int DEFAULT_TIMEOUT = 2000;
73     protected enum int DEFAULT_MAX_ATTEMPTS = 5;
74 
75     protected int maxAttempts;
76 
77     protected RedisClusterConnectionHandler connectionHandler;
78 
79     this(Set!(HostAndPort) nodes, int timeout) {
80         this(nodes, timeout, DEFAULT_MAX_ATTEMPTS, new GenericObjectPoolConfig());
81     }
82 
83     this(Set!(HostAndPort) nodes) {
84         this(nodes, DEFAULT_TIMEOUT);
85     }
86 
87     this(Set!(HostAndPort) redisClusterNode, int timeout, int maxAttempts,
88         GenericObjectPoolConfig poolConfig) {
89         this.connectionHandler = new RedisSlotBasedConnectionHandler(redisClusterNode, poolConfig,
90             timeout);
91         this.maxAttempts = maxAttempts;
92     }
93 
94     this(Set!(HostAndPort) redisClusterNode, int connectionTimeout,
95                                 int soTimeout, int maxAttempts, GenericObjectPoolConfig poolConfig) {
96         this.connectionHandler = new RedisSlotBasedConnectionHandler(redisClusterNode, poolConfig,
97             connectionTimeout, soTimeout);
98         this.maxAttempts = maxAttempts;
99     }
100 
101     this(Set!(HostAndPort) redisClusterNode, int connectionTimeout, int soTimeout, int maxAttempts, 
102             string password, GenericObjectPoolConfig poolConfig) {
103         this.connectionHandler = new RedisSlotBasedConnectionHandler(redisClusterNode, poolConfig,
104                 connectionTimeout, soTimeout, password);
105         this.maxAttempts = maxAttempts;
106     }
107 
108     this(Set!(HostAndPort) redisClusterNode, int connectionTimeout, int soTimeout, int maxAttempts, 
109             string password, string clientName, GenericObjectPoolConfig poolConfig) {
110         this.connectionHandler = new RedisSlotBasedConnectionHandler(redisClusterNode, poolConfig,
111                 connectionTimeout, soTimeout, password, clientName);
112         this.maxAttempts = maxAttempts;
113     }
114 
115     // this(Set!(HostAndPort) redisClusterNode, int connectionTimeout, int soTimeout, int maxAttempts, 
116     //         string password, string clientName, GenericObjectPoolConfig poolConfig, bool ssl) {
117     //     this(redisClusterNode, connectionTimeout, soTimeout, maxAttempts, password, clientName, poolConfig, ssl, null, null, null, null);
118     // }
119 
120     // this(Set!(HostAndPort) redisClusterNode, int connectionTimeout, int soTimeout, int maxAttempts, 
121     //         string password, string clientName, GenericObjectPoolConfig poolConfig,
122     //         bool ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters, 
123     //         HostnameVerifier hostnameVerifier, RedisClusterHostAndPortMap hostAndPortMap) {
124     //     this.connectionHandler = new RedisSlotBasedConnectionHandler(redisClusterNode, poolConfig,
125     //         connectionTimeout, soTimeout, password, clientName, ssl, sslSocketFactory, 
126     //         sslParameters, hostnameVerifier, hostAndPortMap);
127     //     this.maxAttempts = maxAttempts;
128     // }
129 
130     override
131     void close() {
132         if (connectionHandler !is null) {
133         connectionHandler.close();
134         }
135     }
136 
137     Map!(string, RedisPool) getClusterNodes() {
138         return connectionHandler.getNodes();
139     }
140 
141     Redis getConnectionFromSlot(int slot) {
142         return  this.connectionHandler.getConnectionFromSlot(slot);
143     }
144 
145     override
146     string set(const(ubyte)[] key, const(ubyte)[] value) {
147         mixin(ClusterBinaryCommandTemplate!("set", string, [key.stringof, value.stringof]));
148     }
149 
150     override
151     string set(const(ubyte)[] key, const(ubyte)[] value, SetParams params) {
152         mixin(ClusterBinaryCommandTemplate!("set", string, [key.stringof, value.stringof, params.stringof]));
153     }
154 
155     override
156     const(ubyte)[] get(const(ubyte)[] key) {
157         mixin(ClusterBinaryCommandTemplate!("get", const(ubyte)[], [key.stringof]));
158     }
159 
160     override
161     Long exists(const(ubyte)[][] keys...) {
162         mixin(ClusterBinaryCommandTemplate!("exists", Long, [keys.stringof]));
163     }
164 
165     override
166     bool exists(const(ubyte)[] key) {
167         mixin(ClusterBinaryCommandTemplate!("exists", bool, [key.stringof]));
168     }
169 
170     override
171     Long persist(const(ubyte)[] key) {
172         mixin(ClusterBinaryCommandTemplate!("persist", Long, [key.stringof]));
173     }
174 
175     override
176     string type(const(ubyte)[] key) {
177         mixin(ClusterBinaryCommandTemplate!("type", string, [key.stringof]));
178     }
179 
180     override
181     const(ubyte)[] dump(const(ubyte)[] key) {
182         mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
183     }
184 
185     // override
186     // string restore(const(ubyte)[] key, int ttl, const(ubyte)[] serializedValue) {
187     //     // return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
188     //     // override
189     //     // string execute(Redis connection) {
190     //     //     return connection.restore(key, ttl, serializedValue);
191     //     // }
192     //     // }.runBinary(key);
193 
194     //     mixin(ClusterBinaryCommandTemplate!("restore", string, 
195     //         [key.stringof, ttl.stringof, serializedValue.stringof]));
196     // }
197 
198     // override
199     // long expire(const(ubyte)[] key, int seconds) {
200     //     // return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
201     //     // override
202     //     // long execute(Redis connection) {
203     //     //     return connection.expire(key, seconds);
204     //     // }
205     //     // }.runBinary(key);
206     //     mixin(ClusterBinaryCommandTemplate!("expire", Long, [key.stringof]));
207     // }
208 
209     // override
210     // long pexpire(const(ubyte)[] key, long milliseconds) {
211     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
212     //     override
213     //     Long execute(Redis connection) {
214     //         return connection.pexpire(key, milliseconds);
215     //     }
216     //     }.runBinary(key);
217     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
218     // }
219 
220     // override
221     // long expireAt(const(ubyte)[] key, long unixTime) {
222     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
223     //     override
224     //     Long execute(Redis connection) {
225     //         return connection.expireAt(key, unixTime);
226     //     }
227     //     }.runBinary(key);
228     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
229     // }
230 
231     // override
232     // long pexpireAt(const(ubyte)[] key, long millisecondsTimestamp) {
233     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
234     //     override
235     //     Long execute(Redis connection) {
236     //         return connection.pexpireAt(key, millisecondsTimestamp);
237     //     }
238     //     }.runBinary(key);
239     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
240     // }
241 
242     // override
243     // long ttl(const(ubyte)[] key) {
244     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
245     //     override
246     //     Long execute(Redis connection) {
247     //         return connection.ttl(key);
248     //     }
249     //     }.runBinary(key);
250     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
251     // }
252 
253     // override
254     // long pttl(const(ubyte)[] key) {
255     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
256     //     override
257     //     Long execute(Redis connection) {
258     //         return connection.pttl(key);
259     //     }
260     //     }.runBinary(key);
261     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
262     // }
263 
264     // override
265     // long touch(const(ubyte)[] key) {
266     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
267     //     override
268     //     Long execute(Redis connection) {
269     //         return connection.touch(key);
270     //     }
271     //     }.runBinary(key);
272     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
273     // }
274 
275     // override
276     // long touch(const(ubyte)[][] keys...) {
277     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
278     //     override
279     //     Long execute(Redis connection) {
280     //         return connection.touch(keys);
281     //     }
282     //     }.runBinary(keys.length, keys);
283     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [keys.stringof]));
284     // }
285 
286     // override
287     // Boolean setbit(const(ubyte)[] key, long offset, bool value) {
288     //     return new RedisClusterCommand!(Boolean)(connectionHandler, maxAttempts) {
289     //     override
290     //     Boolean execute(Redis connection) {
291     //         return connection.setbit(key, offset, value);
292     //     }
293     //     }.runBinary(key);
294     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
295     // }
296 
297     // override
298     // Boolean setbit(const(ubyte)[] key, long offset, const(ubyte)[] value) {
299     //     return new RedisClusterCommand!(Boolean)(connectionHandler, maxAttempts) {
300     //     override
301     //     Boolean execute(Redis connection) {
302     //         return connection.setbit(key, offset, value);
303     //     }
304     //     }.runBinary(key);
305     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
306     // }
307 
308     // override
309     // Boolean getbit(const(ubyte)[] key, long offset) {
310     //     return new RedisClusterCommand!(Boolean)(connectionHandler, maxAttempts) {
311     //     override
312     //     Boolean execute(Redis connection) {
313     //         return connection.getbit(key, offset);
314     //     }
315     //     }.runBinary(key);
316     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
317     // }
318 
319     // override
320     // long setrange(const(ubyte)[] key, long offset, const(ubyte)[] value) {
321     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
322     //     override
323     //     Long execute(Redis connection) {
324     //         return connection.setrange(key, offset, value);
325     //     }
326     //     }.runBinary(key);
327     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
328     // }
329 
330     // override
331     // const(ubyte)[] getrange(const(ubyte)[] key, long startOffset, long endOffset) {
332     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
333     //     override
334     //     const(ubyte)[] execute(Redis connection) {
335     //         return connection.getrange(key, startOffset, endOffset);
336     //     }
337     //     }.runBinary(key);
338     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
339     // }
340 
341     // override
342     // const(ubyte)[] getSet(const(ubyte)[] key, const(ubyte)[] value) {
343     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
344     //     override
345     //     const(ubyte)[] execute(Redis connection) {
346     //         return connection.getSet(key, value);
347     //     }
348     //     }.runBinary(key);
349     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
350     // }
351 
352     // override
353     // long setnx(const(ubyte)[] key, const(ubyte)[] value) {
354     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
355     //     override
356     //     Long execute(Redis connection) {
357     //         return connection.setnx(key, value);
358     //     }
359     //     }.runBinary(key);
360     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
361     // }
362 
363     // override
364     // string psetex(const(ubyte)[] key, long milliseconds, const(ubyte)[] value) {
365     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
366     //     override
367     //     string execute(Redis connection) {
368     //         return connection.psetex(key, milliseconds, value);
369     //     }
370     //     }.runBinary(key);
371     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
372     // }
373 
374     // override
375     // string setex(const(ubyte)[] key, int seconds, const(ubyte)[] value) {
376     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
377     //     override
378     //     string execute(Redis connection) {
379     //         return connection.setex(key, seconds, value);
380     //     }
381     //     }.runBinary(key);
382     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
383     // }
384 
385     // override
386     // long decrBy(const(ubyte)[] key, long decrement) {
387     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
388     //     override
389     //     Long execute(Redis connection) {
390     //         return connection.decrBy(key, decrement);
391     //     }
392     //     }.runBinary(key);
393     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
394     // }
395 
396     // override
397     // long decr(const(ubyte)[] key) {
398     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
399     //     override
400     //     Long execute(Redis connection) {
401     //         return connection.decr(key);
402     //     }
403     //     }.runBinary(key);
404     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
405     // }
406 
407     // override
408     // long incrBy(const(ubyte)[] key, long increment) {
409     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
410     //     override
411     //     Long execute(Redis connection) {
412     //         return connection.incrBy(key, increment);
413     //     }
414     //     }.runBinary(key);
415     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
416     // }
417 
418     // override
419     // Double incrByFloat(const(ubyte)[] key, double increment) {
420     //     return new RedisClusterCommand!(Double)(connectionHandler, maxAttempts) {
421     //     override
422     //     Double execute(Redis connection) {
423     //         return connection.incrByFloat(key, increment);
424     //     }
425     //     }.runBinary(key);
426     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
427     // }
428 
429     // override
430     // long incr(const(ubyte)[] key) {
431     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
432     //     override
433     //     Long execute(Redis connection) {
434     //         return connection.incr(key);
435     //     }
436     //     }.runBinary(key);
437     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
438     // }
439 
440     // override
441     // long append(const(ubyte)[] key, const(ubyte)[] value) {
442     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
443     //     override
444     //     Long execute(Redis connection) {
445     //         return connection.append(key, value);
446     //     }
447     //     }.runBinary(key);
448     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
449     // }
450 
451     // override
452     // const(ubyte)[] substr(const(ubyte)[] key, int start, int end) {
453     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
454     //     override
455     //     const(ubyte)[] execute(Redis connection) {
456     //         return connection.substr(key, start, end);
457     //     }
458     //     }.runBinary(key);
459     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
460     // }
461 
462     // override
463     // long hset(const(ubyte)[] key, const(ubyte)[] field, const(ubyte)[] value) {
464     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
465     //     override
466     //     Long execute(Redis connection) {
467     //         return connection.hset(key, field, value);
468     //     }
469     //     }.runBinary(key);
470     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
471     // }
472 
473     // override
474     // long hset(const(ubyte)[] key, Map!(const(ubyte)[], const(ubyte)[]) hash) {
475     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
476     //     override
477     //     Long execute(Redis connection) {
478     //         return connection.hset(key, hash);
479     //     }
480     //     }.runBinary(key);
481     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
482     // }
483 
484     // override
485     // const(ubyte)[] hget(const(ubyte)[] key, const(ubyte)[] field) {
486     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
487     //     override
488     //     const(ubyte)[] execute(Redis connection) {
489     //         return connection.hget(key, field);
490     //     }
491     //     }.runBinary(key);
492     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
493     // }
494 
495     // override
496     // long hsetnx(const(ubyte)[] key, const(ubyte)[] field, const(ubyte)[] value) {
497     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
498     //     override
499     //     Long execute(Redis connection) {
500     //         return connection.hsetnx(key, field, value);
501     //     }
502     //     }.runBinary(key);
503     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
504     // }
505 
506     // override
507     // string hmset(const(ubyte)[] key, Map!(const(ubyte)[], const(ubyte)[]) hash) {
508     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
509     //     override
510     //     string execute(Redis connection) {
511     //         return connection.hmset(key, hash);
512     //     }
513     //     }.runBinary(key);
514     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
515     // }
516 
517     // override
518     // List!(const(ubyte)[]) hmget(const(ubyte)[] key, const(ubyte)[][] fields...) {
519     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
520     //     override
521     //     List!(const(ubyte)[]) execute(Redis connection) {
522     //         return connection.hmget(key, fields);
523     //     }
524     //     }.runBinary(key);
525     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
526     // }
527 
528     // override
529     // long hincrBy(const(ubyte)[] key, const(ubyte)[] field, long value) {
530     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
531     //     override
532     //     Long execute(Redis connection) {
533     //         return connection.hincrBy(key, field, value);
534     //     }
535     //     }.runBinary(key);
536     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
537     // }
538 
539     // override
540     // Double hincrByFloat(const(ubyte)[] key, const(ubyte)[] field, double value) {
541     //     return new RedisClusterCommand!(Double)(connectionHandler, maxAttempts) {
542     //     override
543     //     Double execute(Redis connection) {
544     //         return connection.hincrByFloat(key, field, value);
545     //     }
546     //     }.runBinary(key);
547     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
548     // }
549 
550     // override
551     // Boolean hexists(const(ubyte)[] key, const(ubyte)[] field) {
552     //     return new RedisClusterCommand!(Boolean)(connectionHandler, maxAttempts) {
553     //     override
554     //     Boolean execute(Redis connection) {
555     //         return connection.hexists(key, field);
556     //     }
557     //     }.runBinary(key);
558     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
559     // }
560 
561     // override
562     // long hdel(const(ubyte)[] key, const(ubyte)[][] field...) {
563     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
564     //     override
565     //     Long execute(Redis connection) {
566     //         return connection.hdel(key, field);
567     //     }
568     //     }.runBinary(key);
569     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
570     // }
571 
572     // override
573     // long hlen(const(ubyte)[] key) {
574     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
575     //     override
576     //     Long execute(Redis connection) {
577     //         return connection.hlen(key);
578     //     }
579     //     }.runBinary(key);
580     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
581     // }
582 
583     // override
584     // Set!(const(ubyte)[]) hkeys(const(ubyte)[] key) {
585     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
586     //     override
587     //     Set!(const(ubyte)[]) execute(Redis connection) {
588     //         return connection.hkeys(key);
589     //     }
590     //     }.runBinary(key);
591     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
592     // }
593 
594     // override
595     // Collection!(const(ubyte)[]) hvals(const(ubyte)[] key) {
596     //     return new RedisClusterCommand!(Collection!(const(ubyte)[]))(connectionHandler, maxAttempts) {
597     //     override
598     //     Collection!(const(ubyte)[]) execute(Redis connection) {
599     //         return connection.hvals(key);
600     //     }
601     //     }.runBinary(key);
602     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
603     // }
604 
605     // override
606     // Map!(const(ubyte)[], const(ubyte)[]) hgetAll(const(ubyte)[] key) {
607     //     return new RedisClusterCommand!(Map!(const(ubyte)[], const(ubyte)[]))(connectionHandler, maxAttempts) {
608     //     override
609     //     Map!(const(ubyte)[], const(ubyte)[]) execute(Redis connection) {
610     //         return connection.hgetAll(key);
611     //     }
612     //     }.runBinary(key);
613     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
614     // }
615 
616     // override
617     // long rpush(const(ubyte)[] key, const(ubyte)[][] args...) {
618     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
619     //     override
620     //     Long execute(Redis connection) {
621     //         return connection.rpush(key, args);
622     //     }
623     //     }.runBinary(key);
624     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
625     // }
626 
627     // override
628     // long lpush(const(ubyte)[] key, const(ubyte)[][] args...) {
629     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
630     //     override
631     //     Long execute(Redis connection) {
632     //         return connection.lpush(key, args);
633     //     }
634     //     }.runBinary(key);
635     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
636     // }
637 
638     // override
639     // long llen(const(ubyte)[] key) {
640     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
641     //     override
642     //     Long execute(Redis connection) {
643     //         return connection.llen(key);
644     //     }
645     //     }.runBinary(key);
646     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
647     // }
648 
649     // override
650     // List!(const(ubyte)[]) lrange(const(ubyte)[] key, long start, long stop) {
651     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
652     //     override
653     //     List!(const(ubyte)[]) execute(Redis connection) {
654     //         return connection.lrange(key, start, stop);
655     //     }
656     //     }.runBinary(key);
657     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
658     // }
659 
660     // override
661     // string ltrim(const(ubyte)[] key, long start, long stop) {
662     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
663     //     override
664     //     string execute(Redis connection) {
665     //         return connection.ltrim(key, start, stop);
666     //     }
667     //     }.runBinary(key);
668     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
669     // }
670 
671     // override
672     // const(ubyte)[] lindex(const(ubyte)[] key, long index) {
673     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
674     //     override
675     //     const(ubyte)[] execute(Redis connection) {
676     //         return connection.lindex(key, index);
677     //     }
678     //     }.runBinary(key);
679     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
680     // }
681 
682     // override
683     // string lset(const(ubyte)[] key, long index, const(ubyte)[] value) {
684     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
685     //     override
686     //     string execute(Redis connection) {
687     //         return connection.lset(key, index, value);
688     //     }
689     //     }.runBinary(key);
690     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
691     // }
692 
693     // override
694     // long lrem(const(ubyte)[] key, long count, const(ubyte)[] value) {
695     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
696     //     override
697     //     Long execute(Redis connection) {
698     //         return connection.lrem(key, count, value);
699     //     }
700     //     }.runBinary(key);
701     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
702     // }
703 
704     // override
705     // const(ubyte)[] lpop(const(ubyte)[] key) {
706     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
707     //     override
708     //     const(ubyte)[] execute(Redis connection) {
709     //         return connection.lpop(key);
710     //     }
711     //     }.runBinary(key);
712     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
713     // }
714 
715     // override
716     // const(ubyte)[] rpop(const(ubyte)[] key) {
717     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
718     //     override
719     //     const(ubyte)[] execute(Redis connection) {
720     //         return connection.rpop(key);
721     //     }
722     //     }.runBinary(key);
723     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
724     // }
725 
726     // override
727     // long sadd(const(ubyte)[] key, const(ubyte)[][] member...) {
728     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
729     //     override
730     //     Long execute(Redis connection) {
731     //         return connection.sadd(key, member);
732     //     }
733     //     }.runBinary(key);
734     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
735     // }
736 
737     // override
738     // Set!(const(ubyte)[]) smembers(const(ubyte)[] key) {
739     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
740     //     override
741     //     Set!(const(ubyte)[]) execute(Redis connection) {
742     //         return connection.smembers(key);
743     //     }
744     //     }.runBinary(key);
745     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
746     // }
747 
748     // override
749     // long srem(const(ubyte)[] key, const(ubyte)[][] member...) {
750     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
751     //     override
752     //     Long execute(Redis connection) {
753     //         return connection.srem(key, member);
754     //     }
755     //     }.runBinary(key);
756     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
757     // }
758 
759     // override
760     // const(ubyte)[] spop(const(ubyte)[] key) {
761     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
762     //     override
763     //     const(ubyte)[] execute(Redis connection) {
764     //         return connection.spop(key);
765     //     }
766     //     }.runBinary(key);
767     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
768     // }
769 
770     // override
771     // Set!(const(ubyte)[]) spop(const(ubyte)[] key, long count) {
772     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
773     //     override
774     //     Set!(const(ubyte)[]) execute(Redis connection) {
775     //         return connection.spop(key, count);
776     //     }
777     //     }.runBinary(key);
778     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
779     // }
780 
781     // override
782     // long scard(const(ubyte)[] key) {
783     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
784     //     override
785     //     Long execute(Redis connection) {
786     //         return connection.scard(key);
787     //     }
788     //     }.runBinary(key);
789     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
790     // }
791 
792     // override
793     // Boolean sismember(const(ubyte)[] key, const(ubyte)[] member) {
794     //     return new RedisClusterCommand!(Boolean)(connectionHandler, maxAttempts) {
795     //     override
796     //     Boolean execute(Redis connection) {
797     //         return connection.sismember(key, member);
798     //     }
799     //     }.runBinary(key);
800     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
801     // }
802 
803     // override
804     // const(ubyte)[] srandmember(const(ubyte)[] key) {
805     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
806     //     override
807     //     const(ubyte)[] execute(Redis connection) {
808     //         return connection.srandmember(key);
809     //     }
810     //     }.runBinary(key);
811     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
812     // }
813 
814     // override
815     // long strlen(const(ubyte)[] key) {
816     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
817     //     override
818     //     Long execute(Redis connection) {
819     //         return connection.strlen(key);
820     //     }
821     //     }.runBinary(key);
822     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
823     // }
824 
825     // override
826     // long zadd(const(ubyte)[] key, double score, const(ubyte)[] member) {
827     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
828     //     override
829     //     Long execute(Redis connection) {
830     //         return connection.zadd(key, score, member);
831     //     }
832     //     }.runBinary(key);
833     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
834     // }
835 
836     // override
837     // long zadd(const(ubyte)[] key, double score, const(ubyte)[] member,
838     //     ZAddParams params) {
839     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
840     //     override
841     //     Long execute(Redis connection) {
842     //         return connection.zadd(key, score, member, params);
843     //     }
844     //     }.runBinary(key);
845     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
846     // }
847 
848     // override
849     // long zadd(const(ubyte)[] key, Map!(const(ubyte)[], Double) scoreMembers) {
850     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
851     //     override
852     //     Long execute(Redis connection) {
853     //         return connection.zadd(key, scoreMembers);
854     //     }
855     //     }.runBinary(key);
856     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
857     // }
858 
859     // override
860     // long zadd(const(ubyte)[] key, Map!(const(ubyte)[], Double) scoreMembers, ZAddParams params) {
861     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
862     //     override
863     //     Long execute(Redis connection) {
864     //         return connection.zadd(key, scoreMembers, params);
865     //     }
866     //     }.runBinary(key);
867     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
868     // }
869 
870     // override
871     // Set!(const(ubyte)[]) zrange(const(ubyte)[] key, long start, long stop) {
872     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
873     //     override
874     //     Set!(const(ubyte)[]) execute(Redis connection) {
875     //         return connection.zrange(key, start, stop);
876     //     }
877     //     }.runBinary(key);
878     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
879     // }
880 
881     // override
882     // long zrem(const(ubyte)[] key, const(ubyte)[][] members...) {
883     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
884     //     override
885     //     Long execute(Redis connection) {
886     //         return connection.zrem(key, members);
887     //     }
888     //     }.runBinary(key);
889     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
890     // }
891 
892     // override
893     // Double zincrby(const(ubyte)[] key, double increment, const(ubyte)[] member) {
894     //     return new RedisClusterCommand!(Double)(connectionHandler, maxAttempts) {
895     //     override
896     //     Double execute(Redis connection) {
897     //         return connection.zincrby(key, increment, member);
898     //     }
899     //     }.runBinary(key);
900     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
901     // }
902 
903     // override
904     // Double zincrby(const(ubyte)[] key, double increment, const(ubyte)[] member,
905     //     ZIncrByParams params) {
906     //     return new RedisClusterCommand!(Double)(connectionHandler, maxAttempts) {
907     //     override
908     //     Double execute(Redis connection) {
909     //         return connection.zincrby(key, increment, member, params);
910     //     }
911     //     }.runBinary(key);
912     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
913     // }
914 
915     // override
916     // long zrank(const(ubyte)[] key, const(ubyte)[] member) {
917     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
918     //     override
919     //     Long execute(Redis connection) {
920     //         return connection.zrank(key, member);
921     //     }
922     //     }.runBinary(key);
923     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
924     // }
925 
926     // override
927     // long zrevrank(const(ubyte)[] key, const(ubyte)[] member) {
928     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
929     //     override
930     //     Long execute(Redis connection) {
931     //         return connection.zrevrank(key, member);
932     //     }
933     //     }.runBinary(key);
934     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
935     // }
936 
937     // override
938     // Set!(const(ubyte)[]) zrevrange(const(ubyte)[] key, long start, long stop) {
939     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
940     //     override
941     //     Set!(const(ubyte)[]) execute(Redis connection) {
942     //         return connection.zrevrange(key, start, stop);
943     //     }
944     //     }.runBinary(key);
945     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
946     // }
947 
948     // override
949     // Set!(Tuple) zrangeWithScores(const(ubyte)[] key, long start, long stop) {
950     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
951     //     override
952     //     Set!(Tuple) execute(Redis connection) {
953     //         return connection.zrangeWithScores(key, start, stop);
954     //     }
955     //     }.runBinary(key);
956     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
957     // }
958 
959     // override
960     // Set!(Tuple) zrevrangeWithScores(const(ubyte)[] key, long start, long stop) {
961     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
962     //     override
963     //     Set!(Tuple) execute(Redis connection) {
964     //         return connection.zrevrangeWithScores(key, start, stop);
965     //     }
966     //     }.runBinary(key);
967     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
968     // }
969 
970     // override
971     // long zcard(const(ubyte)[] key) {
972     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
973     //     override
974     //     Long execute(Redis connection) {
975     //         return connection.zcard(key);
976     //     }
977     //     }.runBinary(key);
978     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
979     // }
980 
981     // override
982     // Double zscore(const(ubyte)[] key, const(ubyte)[] member) {
983     //     return new RedisClusterCommand!(Double)(connectionHandler, maxAttempts) {
984     //     override
985     //     Double execute(Redis connection) {
986     //         return connection.zscore(key, member);
987     //     }
988     //     }.runBinary(key);
989     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
990     // }
991 
992     // override
993     // List!(const(ubyte)[]) sort(const(ubyte)[] key) {
994     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
995     //     override
996     //     List!(const(ubyte)[]) execute(Redis connection) {
997     //         return connection.sort(key);
998     //     }
999     //     }.runBinary(key);
1000     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1001     // }
1002 
1003     // override
1004     // List!(const(ubyte)[]) sort(const(ubyte)[] key, SortingParams sortingParameters) {
1005     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1006     //     override
1007     //     List!(const(ubyte)[]) execute(Redis connection) {
1008     //         return connection.sort(key, sortingParameters);
1009     //     }
1010     //     }.runBinary(key);
1011     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1012     // }
1013 
1014     // override
1015     // long zcount(const(ubyte)[] key, double min, double max) {
1016     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1017     //     override
1018     //     Long execute(Redis connection) {
1019     //         return connection.zcount(key, min, max);
1020     //     }
1021     //     }.runBinary(key);
1022     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1023     // }
1024 
1025     // override
1026     // long zcount(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
1027     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1028     //     override
1029     //     Long execute(Redis connection) {
1030     //         return connection.zcount(key, min, max);
1031     //     }
1032     //     }.runBinary(key);
1033     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1034     // }
1035 
1036     // override
1037     // Set!(const(ubyte)[]) zrangeByScore(const(ubyte)[] key, double min, double max) {
1038     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1039     //     override
1040     //     Set!(const(ubyte)[]) execute(Redis connection) {
1041     //         return connection.zrangeByScore(key, min, max);
1042     //     }
1043     //     }.runBinary(key);
1044     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1045     // }
1046 
1047     // override
1048     // Set!(const(ubyte)[]) zrangeByScore(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
1049     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1050     //     override
1051     //     Set!(const(ubyte)[]) execute(Redis connection) {
1052     //         return connection.zrangeByScore(key, min, max);
1053     //     }
1054     //     }.runBinary(key);
1055     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1056     // }
1057 
1058     // override
1059     // Set!(const(ubyte)[]) zrevrangeByScore(const(ubyte)[] key, double max, double min) {
1060     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1061     //     override
1062     //     Set!(const(ubyte)[]) execute(Redis connection) {
1063     //         return connection.zrevrangeByScore(key, max, min);
1064     //     }
1065     //     }.runBinary(key);
1066     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1067     // }
1068 
1069     // override
1070     // Set!(const(ubyte)[]) zrangeByScore(const(ubyte)[] key, double min, double max,
1071     //     int offset, int count) {
1072     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1073     //     override
1074     //     Set!(const(ubyte)[]) execute(Redis connection) {
1075     //         return connection.zrangeByScore(key, min, max, offset, count);
1076     //     }
1077     //     }.runBinary(key);
1078     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1079     // }
1080 
1081     // override
1082     // Set!(const(ubyte)[]) zrevrangeByScore(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min) {
1083     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1084     //     override
1085     //     Set!(const(ubyte)[]) execute(Redis connection) {
1086     //         return connection.zrevrangeByScore(key, max, min);
1087     //     }
1088     //     }.runBinary(key);
1089     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1090     // }
1091 
1092     // override
1093     // Set!(const(ubyte)[]) zrangeByScore(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max,
1094     //     int offset, int count) {
1095     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1096     //     override
1097     //     Set!(const(ubyte)[]) execute(Redis connection) {
1098     //         return connection.zrangeByScore(key, min, max, offset, count);
1099     //     }
1100     //     }.runBinary(key);
1101     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1102     // }
1103 
1104     // override
1105     // Set!(const(ubyte)[]) zrevrangeByScore(const(ubyte)[] key, double max, double min,
1106     //     int offset, int count) {
1107     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1108     //     override
1109     //     Set!(const(ubyte)[]) execute(Redis connection) {
1110     //         return connection.zrevrangeByScore(key, max, min, offset, count);
1111     //     }
1112     //     }.runBinary(key);
1113     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1114     // }
1115 
1116     // override
1117     // Set!(Tuple) zrangeByScoreWithScores(const(ubyte)[] key, double min, double max) {
1118     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
1119     //     override
1120     //     Set!(Tuple) execute(Redis connection) {
1121     //         return connection.zrangeByScoreWithScores(key, min, max);
1122     //     }
1123     //     }.runBinary(key);
1124     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1125     // }
1126 
1127     // override
1128     // Set!(Tuple) zrevrangeByScoreWithScores(const(ubyte)[] key, double max, double min) {
1129     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
1130     //     override
1131     //     Set!(Tuple) execute(Redis connection) {
1132     //         return connection.zrevrangeByScoreWithScores(key, max, min);
1133     //     }
1134     //     }.runBinary(key);
1135     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1136     // }
1137 
1138     // override
1139     // Set!(Tuple) zrangeByScoreWithScores(const(ubyte)[] key, double min, double max,
1140     //     int offset, int count) {
1141     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
1142     //     override
1143     //     Set!(Tuple) execute(Redis connection) {
1144     //         return connection.zrangeByScoreWithScores(key, min, max, offset, count);
1145     //     }
1146     //     }.runBinary(key);
1147     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1148     // }
1149 
1150     // override
1151     // Set!(const(ubyte)[]) zrevrangeByScore(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min,
1152     //     int offset, int count) {
1153     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1154     //     override
1155     //     Set!(const(ubyte)[]) execute(Redis connection) {
1156     //         return connection.zrevrangeByScore(key, max, min, offset, count);
1157     //     }
1158     //     }.runBinary(key);
1159     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1160     // }
1161 
1162     // override
1163     // Set!(Tuple) zrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
1164     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
1165     //     override
1166     //     Set!(Tuple) execute(Redis connection) {
1167     //         return connection.zrangeByScoreWithScores(key, min, max);
1168     //     }
1169     //     }.runBinary(key);
1170     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1171     // }
1172 
1173     // override
1174     // Set!(Tuple) zrevrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min) {
1175     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
1176     //     override
1177     //     Set!(Tuple) execute(Redis connection) {
1178     //         return connection.zrevrangeByScoreWithScores(key, max, min);
1179     //     }
1180     //     }.runBinary(key);
1181     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1182     // }
1183 
1184     // override
1185     // Set!(Tuple) zrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max,
1186     //     int offset, int count) {
1187     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
1188     //     override
1189     //     Set!(Tuple) execute(Redis connection) {
1190     //         return connection.zrangeByScoreWithScores(key, min, max, offset, count);
1191     //     }
1192     //     }.runBinary(key);
1193     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
1194     // }
1195 
1196     // override
1197     // Set!(Tuple) zrevrangeByScoreWithScores(const(ubyte)[] key, double max,
1198     //     double min, int offset, int count) {
1199     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
1200     //     override
1201     //     Set!(Tuple) execute(Redis connection) {
1202     //         return connection.zrevrangeByScoreWithScores(key, max, min, offset, count);
1203     //     }
1204     //     }.runBinary(key);
1205     // }
1206 
1207     // override
1208     // Set!(Tuple) zrevrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] max,
1209     //     const(ubyte)[] min, int offset, int count) {
1210     //     return new RedisClusterCommand!(Set!(Tuple))(connectionHandler, maxAttempts) {
1211     //     override
1212     //     Set!(Tuple) execute(Redis connection) {
1213     //         return connection.zrevrangeByScoreWithScores(key, max, min, offset, count);
1214     //     }
1215     //     }.runBinary(key);
1216     // }
1217 
1218     // override
1219     // long zremrangeByRank(const(ubyte)[] key, long start, long stop) {
1220     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1221     //     override
1222     //     Long execute(Redis connection) {
1223     //         return connection.zremrangeByRank(key, start, stop);
1224     //     }
1225     //     }.runBinary(key);
1226     // }
1227 
1228     // override
1229     // long zremrangeByScore(const(ubyte)[] key, double min, double max) {
1230     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1231     //     override
1232     //     Long execute(Redis connection) {
1233     //         return connection.zremrangeByScore(key, min, max);
1234     //     }
1235     //     }.runBinary(key);
1236     // }
1237 
1238     // override
1239     // long zremrangeByScore(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
1240     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1241     //     override
1242     //     Long execute(Redis connection) {
1243     //         return connection.zremrangeByScore(key, min, max);
1244     //     }
1245     //     }.runBinary(key);
1246     // }
1247 
1248     // override
1249     // long linsert(const(ubyte)[] key, ListPosition where, const(ubyte)[] pivot,
1250     //     const(ubyte)[] value) {
1251     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1252     //     override
1253     //     Long execute(Redis connection) {
1254     //         return connection.linsert(key, where, pivot, value);
1255     //     }
1256     //     }.runBinary(key);
1257     // }
1258 
1259     // override
1260     // long lpushx(const(ubyte)[] key, const(ubyte)[][] arg...) {
1261     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1262     //     override
1263     //     Long execute(Redis connection) {
1264     //         return connection.lpushx(key, arg);
1265     //     }
1266     //     }.runBinary(key);
1267     // }
1268 
1269     // override
1270     // long rpushx(const(ubyte)[] key, const(ubyte)[][] arg...) {
1271     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1272     //     override
1273     //     Long execute(Redis connection) {
1274     //         return connection.rpushx(key, arg);
1275     //     }
1276     //     }.runBinary(key);
1277     // }
1278 
1279     override
1280     Long del(const(ubyte)[] key) {
1281         mixin(ClusterBinaryCommandTemplate!("del", Long, [key.stringof]));
1282     }
1283 
1284     override
1285     Long del(const(ubyte)[][] keys...) {
1286         mixin(ClusterBinaryCommandTemplate!("del", Long, [keys.stringof]));
1287         // return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1288         // override
1289         // long execute(Redis connection) {
1290         //     return connection.del(keys);
1291         // }
1292         // }.runBinary(keys.length, keys);
1293     }
1294 
1295     override
1296     Long unlink(const(ubyte)[] key) {
1297         mixin(ClusterBinaryCommandTemplate!("unlink", Long, [key.stringof]));
1298     }
1299 
1300     override
1301     Long unlink(const(ubyte)[][] keys...) {
1302         mixin(ClusterBinaryCommandTemplate!("unlink", Long, [keys.stringof]));
1303     }
1304 
1305     // override
1306     // const(ubyte)[] echo(const(ubyte)[] arg) {
1307     //     // note that it'll be run from arbitary node
1308     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
1309     //     override
1310     //     const(ubyte)[] execute(Redis connection) {
1311     //         return connection.echo(arg);
1312     //     }
1313     //     }.runBinary(arg);
1314     // }
1315 
1316     // override
1317     // long bitcount(const(ubyte)[] key) {
1318     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1319     //     override
1320     //     Long execute(Redis connection) {
1321     //         return connection.bitcount(key);
1322     //     }
1323     //     }.runBinary(key);
1324     // }
1325 
1326     // override
1327     // long bitcount(const(ubyte)[] key, long start, long end) {
1328     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1329     //     override
1330     //     Long execute(Redis connection) {
1331     //         return connection.bitcount(key, start, end);
1332     //     }
1333     //     }.runBinary(key);
1334     // }
1335 
1336     // override
1337     // long pfadd(const(ubyte)[] key, const(ubyte)[][] elements...) {
1338     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1339     //     override
1340     //     Long execute(Redis connection) {
1341     //         return connection.pfadd(key, elements);
1342     //     }
1343     //     }.runBinary(key);
1344     // }
1345 
1346     // override
1347     // long pfcount(const(ubyte)[] key) {
1348     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1349     //     override
1350     //     Long execute(Redis connection) {
1351     //         return connection.pfcount(key);
1352     //     }
1353     //     }.runBinary(key);
1354     // }
1355 
1356     // override
1357     // List!(const(ubyte)[]) srandmember(const(ubyte)[] key, int count) {
1358     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1359     //     override
1360     //     List!(const(ubyte)[]) execute(Redis connection) {
1361     //         return connection.srandmember(key, count);
1362     //     }
1363     //     }.runBinary(key);
1364     // }
1365 
1366     // override
1367     // long zlexcount(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
1368     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1369     //     override
1370     //     Long execute(Redis connection) {
1371     //         return connection.zlexcount(key, min, max);
1372     //     }
1373     //     }.runBinary(key);
1374     // }
1375 
1376     // override
1377     // Set!(const(ubyte)[]) zrangeByLex(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
1378     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1379     //     override
1380     //     Set!(const(ubyte)[]) execute(Redis connection) {
1381     //         return connection.zrangeByLex(key, min, max);
1382     //     }
1383     //     }.runBinary(key);
1384     // }
1385 
1386     // override
1387     // Set!(const(ubyte)[]) zrangeByLex(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max,
1388     //     int offset, int count) {
1389     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1390     //     override
1391     //     Set!(const(ubyte)[]) execute(Redis connection) {
1392     //         return connection.zrangeByLex(key, min, max, offset, count);
1393     //     }
1394     //     }.runBinary(key);
1395     // }
1396 
1397     // override
1398     // Set!(const(ubyte)[]) zrevrangeByLex(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min) {
1399     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1400     //     override
1401     //     Set!(const(ubyte)[]) execute(Redis connection) {
1402     //         return connection.zrevrangeByLex(key, max, min);
1403     //     }
1404     //     }.runBinary(key);
1405     // }
1406 
1407     // override
1408     // Set!(const(ubyte)[]) zrevrangeByLex(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min,
1409     //     int offset, int count) {
1410     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1411     //     override
1412     //     Set!(const(ubyte)[]) execute(Redis connection) {
1413     //         return connection.zrevrangeByLex(key, max, min, offset, count);
1414     //     }
1415     //     }.runBinary(key);
1416     // }
1417 
1418     // override
1419     // long zremrangeByLex(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
1420     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1421     //     override
1422     //     Long execute(Redis connection) {
1423     //         return connection.zremrangeByLex(key, min, max);
1424     //     }
1425     //     }.runBinary(key);
1426     // }
1427 
1428     // override
1429     // Object eval(const(ubyte)[] script, const(ubyte)[] keyCount, const(ubyte)[][] params...) {
1430     //     return new RedisClusterCommand!(Object)(connectionHandler, maxAttempts) {
1431     //     override
1432     //     Object execute(Redis connection) {
1433     //         return connection.eval(script, keyCount, params);
1434     //     }
1435     //     }.runBinary(to!int(SafeEncoder.encode(keyCount)), params);
1436     // }
1437 
1438     // override
1439     // Object eval(const(ubyte)[] script, int keyCount, const(ubyte)[][] params...) {
1440     //     return new RedisClusterCommand!(Object)(connectionHandler, maxAttempts) {
1441     //     override
1442     //     Object execute(Redis connection) {
1443     //         return connection.eval(script, keyCount, params);
1444     //     }
1445     //     }.runBinary(keyCount, params);
1446     // }
1447 
1448     // override
1449     // Object eval(const(ubyte)[] script, List!(const(ubyte)[]) keys, List!(const(ubyte)[]) args) {
1450     //     return new RedisClusterCommand!(Object)(connectionHandler, maxAttempts) {
1451     //     override
1452     //     Object execute(Redis connection) {
1453     //         return connection.eval(script, keys, args);
1454     //     }
1455     //     }.runBinary(keys.size(), keys.toArray(new byte[keys.size()][]));
1456     // }
1457 
1458     // override
1459     // Object eval(const(ubyte)[] script, const(ubyte)[] sampleKey) {
1460     //     return new RedisClusterCommand!(Object)(connectionHandler, maxAttempts) {
1461     //     override
1462     //     Object execute(Redis connection) {
1463     //         return connection.eval(script);
1464     //     }
1465     //     }.runBinary(sampleKey);
1466     // }
1467 
1468     // override
1469     // Object evalsha(const(ubyte)[] sha1, const(ubyte)[] sampleKey) {
1470     //     return new RedisClusterCommand!(Object)(connectionHandler, maxAttempts) {
1471     //     override
1472     //     Object execute(Redis connection) {
1473     //         return connection.evalsha(sha1);
1474     //     }
1475     //     }.runBinary(sampleKey);
1476     // }
1477 
1478     // override
1479     // Object evalsha(const(ubyte)[] sha1, List!(const(ubyte)[]) keys, List!(const(ubyte)[]) args) {
1480     //     return new RedisClusterCommand!(Object)(connectionHandler, maxAttempts) {
1481     //     override
1482     //     Object execute(Redis connection) {
1483     //         return connection.evalsha(sha1, keys, args);
1484     //     }
1485     //     }.runBinary(keys.size(), keys.toArray(new byte[keys.size()][]));
1486     // }
1487 
1488     // override
1489     // Object evalsha(const(ubyte)[] sha1, int keyCount, const(ubyte)[][] params...) {
1490     //     return new RedisClusterCommand!(Object)(connectionHandler, maxAttempts) {
1491     //     override
1492     //     Object execute(Redis connection) {
1493     //         return connection.evalsha(sha1, keyCount, params);
1494     //     }
1495     //     }.runBinary(keyCount, params);
1496     // }
1497 
1498     // override
1499     // List!(long) scriptExists(const(ubyte)[] sampleKey, const(ubyte)[][] sha1...) {
1500     //     return new RedisClusterCommand!(List!(long))(connectionHandler, maxAttempts) {
1501     //     override
1502     //     List!(long) execute(Redis connection) {
1503     //         return connection.scriptExists(sha1);
1504     //     }
1505     //     }.runBinary(sampleKey);
1506     // }
1507 
1508     // override
1509     // const(ubyte)[] scriptLoad(const(ubyte)[] script, const(ubyte)[] sampleKey) {
1510     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
1511     //     override
1512     //     const(ubyte)[] execute(Redis connection) {
1513     //         return connection.scriptLoad(script);
1514     //     }
1515     //     }.runBinary(sampleKey);
1516     // }
1517 
1518     // override
1519     // string scriptFlush(const(ubyte)[] sampleKey) {
1520     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
1521     //     override
1522     //     string execute(Redis connection) {
1523     //         return connection.scriptFlush();
1524     //     }
1525     //     }.runBinary(sampleKey);
1526     // }
1527 
1528     // override
1529     // string scriptKill(const(ubyte)[] sampleKey) {
1530     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
1531     //     override
1532     //     string execute(Redis connection) {
1533     //         return connection.scriptKill();
1534     //     }
1535     //     }.runBinary(sampleKey);
1536     // }
1537 
1538     // override
1539     // List!(const(ubyte)[]) blpop(int timeout, const(ubyte)[][] keys...) {
1540     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1541     //     override
1542     //     List!(const(ubyte)[]) execute(Redis connection) {
1543     //         return connection.blpop(timeout, keys);
1544     //     }
1545     //     }.runBinary(keys.length, keys);
1546     // }
1547 
1548     // override
1549     // List!(const(ubyte)[]) brpop(int timeout, const(ubyte)[][] keys...) {
1550     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1551     //     override
1552     //     List!(const(ubyte)[]) execute(Redis connection) {
1553     //         return connection.brpop(timeout, keys);
1554     //     }
1555     //     }.runBinary(keys.length, keys);
1556     // }
1557 
1558     // override
1559     // List!(const(ubyte)[]) mget(const(ubyte)[][] keys...) {
1560     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1561     //     override
1562     //     List!(const(ubyte)[]) execute(Redis connection) {
1563     //         return connection.mget(keys);
1564     //     }
1565     //     }.runBinary(keys.length, keys);
1566     // }
1567 
1568     // override
1569     // string mset(const(ubyte)[][] keysvalues...) {
1570     //     const(ubyte)[][] keys = new byte[keysvalues.length / 2][];
1571 
1572     //     for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) {
1573     //     keys[keyIdx] = keysvalues[keyIdx * 2];
1574     //     }
1575 
1576     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
1577     //     override
1578     //     string execute(Redis connection) {
1579     //         return connection.mset(keysvalues);
1580     //     }
1581     //     }.runBinary(keys.length, keys);
1582     // }
1583 
1584     // override
1585     // long msetnx(const(ubyte)[][] keysvalues...) {
1586     //     const(ubyte)[][] keys = new byte[keysvalues.length / 2][];
1587 
1588     //     for (int keyIdx = 0; keyIdx < keys.length; keyIdx++) {
1589     //     keys[keyIdx] = keysvalues[keyIdx * 2];
1590     //     }
1591 
1592     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1593     //     override
1594     //     Long execute(Redis connection) {
1595     //         return connection.msetnx(keysvalues);
1596     //     }
1597     //     }.runBinary(keys.length, keys);
1598     // }
1599 
1600     // override
1601     // string rename(const(ubyte)[] oldkey, const(ubyte)[] newkey) {
1602     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
1603     //     override
1604     //     string execute(Redis connection) {
1605     //         return connection.rename(oldkey, newkey);
1606     //     }
1607     //     }.runBinary(2, oldkey, newkey);
1608     // }
1609 
1610     // override
1611     // long renamenx(const(ubyte)[] oldkey, const(ubyte)[] newkey) {
1612     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1613     //     override
1614     //     Long execute(Redis connection) {
1615     //         return connection.renamenx(oldkey, newkey);
1616     //     }
1617     //     }.runBinary(2, oldkey, newkey);
1618     // }
1619 
1620     // override
1621     // const(ubyte)[] rpoplpush(const(ubyte)[] srckey, const(ubyte)[] dstkey) {
1622     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
1623     //     override
1624     //     const(ubyte)[] execute(Redis connection) {
1625     //         return connection.rpoplpush(srckey, dstkey);
1626     //     }
1627     //     }.runBinary(2, srckey, dstkey);
1628     // }
1629 
1630     // override
1631     // Set!(const(ubyte)[]) sdiff(const(ubyte)[][] keys...) {
1632     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1633     //     override
1634     //     Set!(const(ubyte)[]) execute(Redis connection) {
1635     //         return connection.sdiff(keys);
1636     //     }
1637     //     }.runBinary(keys.length, keys);
1638     // }
1639 
1640     // override
1641     // long sdiffstore(const(ubyte)[] dstkey, const(ubyte)[][] keys...) {
1642     //     const(ubyte)[][] wholeKeys = KeyMergeUtil.merge(dstkey, keys);
1643 
1644     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1645     //     override
1646     //     Long execute(Redis connection) {
1647     //         return connection.sdiffstore(dstkey, keys);
1648     //     }
1649     //     }.runBinary(wholeKeys.length, wholeKeys);
1650     // }
1651 
1652     // override
1653     // Set!(const(ubyte)[]) sinter(const(ubyte)[][] keys...) {
1654     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1655     //     override
1656     //     Set!(const(ubyte)[]) execute(Redis connection) {
1657     //         return connection.sinter(keys);
1658     //     }
1659     //     }.runBinary(keys.length, keys);
1660     // }
1661 
1662     // override
1663     // long sinterstore(const(ubyte)[] dstkey, const(ubyte)[][] keys...) {
1664     //     const(ubyte)[][] wholeKeys = KeyMergeUtil.merge(dstkey, keys);
1665 
1666     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1667     //     override
1668     //     Long execute(Redis connection) {
1669     //         return connection.sinterstore(dstkey, keys);
1670     //     }
1671     //     }.runBinary(wholeKeys.length, wholeKeys);
1672     // }
1673 
1674     // override
1675     // long smove(const(ubyte)[] srckey, const(ubyte)[] dstkey, const(ubyte)[] member) {
1676     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1677     //     override
1678     //     Long execute(Redis connection) {
1679     //         return connection.smove(srckey, dstkey, member);
1680     //     }
1681     //     }.runBinary(2, srckey, dstkey);
1682     // }
1683 
1684     // override
1685     // long sort(const(ubyte)[] key, SortingParams sortingParameters, const(ubyte)[] dstkey) {
1686     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1687     //     override
1688     //     Long execute(Redis connection) {
1689     //         return connection.sort(key, sortingParameters, dstkey);
1690     //     }
1691     //     }.runBinary(2, key, dstkey);
1692     // }
1693 
1694     // override
1695     // long sort(const(ubyte)[] key, const(ubyte)[] dstkey) {
1696     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1697     //     override
1698     //     Long execute(Redis connection) {
1699     //         return connection.sort(key, dstkey);
1700     //     }
1701     //     }.runBinary(2, key, dstkey);
1702     // }
1703 
1704     // override
1705     // Set!(const(ubyte)[]) sunion(const(ubyte)[][] keys...) {
1706     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1707     //     override
1708     //     Set!(const(ubyte)[]) execute(Redis connection) {
1709     //         return connection.sunion(keys);
1710     //     }
1711     //     }.runBinary(keys.length, keys);
1712     // }
1713 
1714     // override
1715     // long sunionstore(const(ubyte)[] dstkey, const(ubyte)[][] keys...) {
1716     //     const(ubyte)[][] wholeKeys = KeyMergeUtil.merge(dstkey, keys);
1717 
1718     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1719     //     override
1720     //     Long execute(Redis connection) {
1721     //         return connection.sunionstore(dstkey, keys);
1722     //     }
1723     //     }.runBinary(wholeKeys.length, wholeKeys);
1724     // }
1725 
1726     // override
1727     // long zinterstore(const(ubyte)[] dstkey, const(ubyte)[][] sets...) {
1728     //     const(ubyte)[][] wholeKeys = KeyMergeUtil.merge(dstkey, sets);
1729 
1730     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1731     //     override
1732     //     Long execute(Redis connection) {
1733     //         return connection.zinterstore(dstkey, sets);
1734     //     }
1735     //     }.runBinary(wholeKeys.length, wholeKeys);
1736     // }
1737 
1738     // override
1739     // long zinterstore(const(ubyte)[] dstkey, ZParams params, const(ubyte)[][] sets...) {
1740     //     const(ubyte)[][] wholeKeys = KeyMergeUtil.merge(dstkey, sets);
1741 
1742     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1743     //     override
1744     //     Long execute(Redis connection) {
1745     //         return connection.zinterstore(dstkey, params, sets);
1746     //     }
1747     //     }.runBinary(wholeKeys.length, wholeKeys);
1748     // }
1749 
1750     // override
1751     // long zunionstore(const(ubyte)[] dstkey, const(ubyte)[][] sets...) {
1752     //     const(ubyte)[][] wholeKeys = KeyMergeUtil.merge(dstkey, sets);
1753 
1754     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1755     //     override
1756     //     Long execute(Redis connection) {
1757     //         return connection.zunionstore(dstkey, sets);
1758     //     }
1759     //     }.runBinary(wholeKeys.length, wholeKeys);
1760     // }
1761 
1762     // override
1763     // long zunionstore(const(ubyte)[] dstkey, ZParams params, const(ubyte)[][] sets...) {
1764     //     const(ubyte)[][] wholeKeys = KeyMergeUtil.merge(dstkey, sets);
1765 
1766     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1767     //     override
1768     //     Long execute(Redis connection) {
1769     //         return connection.zunionstore(dstkey, params, sets);
1770     //     }
1771     //     }.runBinary(wholeKeys.length, wholeKeys);
1772     // }
1773 
1774     // override
1775     // const(ubyte)[] brpoplpush(const(ubyte)[] source, const(ubyte)[] destination, int timeout) {
1776     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
1777     //     override
1778     //     const(ubyte)[] execute(Redis connection) {
1779     //         return connection.brpoplpush(source, destination, timeout);
1780     //     }
1781     //     }.runBinary(2, source, destination);
1782     // }
1783 
1784     // override
1785     // long publish(const(ubyte)[] channel, const(ubyte)[] message) {
1786     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1787     //     override
1788     //     Long execute(Redis connection) {
1789     //         return connection.publish(channel, message);
1790     //     }
1791     //     }.runWithAnyNode();
1792     // }
1793 
1794     // override
1795     // void subscribe(BinaryRedisPubSub jedisPubSub, const(ubyte)[][] channels...) {
1796     //     new RedisClusterCommand!(Integer)(connectionHandler, maxAttempts) {
1797     //     override
1798     //     Integer execute(Redis connection) {
1799     //         connection.subscribe(jedisPubSub, channels);
1800     //         return 0;
1801     //     }
1802     //     }.runWithAnyNode();
1803     // }
1804 
1805     // override
1806     // void psubscribe(BinaryRedisPubSub jedisPubSub, const(ubyte)[][] patterns...) {
1807     //     new RedisClusterCommand!(Integer)(connectionHandler, maxAttempts) {
1808     //     override
1809     //     Integer execute(Redis connection) {
1810     //         connection.psubscribe(jedisPubSub, patterns);
1811     //         return 0;
1812     //     }
1813     //     }.runWithAnyNode();
1814     // }
1815 
1816     // override
1817     // long bitop(BitOP op, const(ubyte)[] destKey, const(ubyte)[][] srcKeys...) {
1818     //     const(ubyte)[][] wholeKeys = KeyMergeUtil.merge(destKey, srcKeys);
1819 
1820     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1821     //     override
1822     //     Long execute(Redis connection) {
1823     //         return connection.bitop(op, destKey, srcKeys);
1824     //     }
1825     //     }.runBinary(wholeKeys.length, wholeKeys);
1826     // }
1827 
1828     // override
1829     // string pfmerge(const(ubyte)[] destkey, const(ubyte)[][] sourcekeys...) {
1830     //     const(ubyte)[][] wholeKeys = KeyMergeUtil.merge(destkey, sourcekeys);
1831 
1832     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
1833     //     override
1834     //     string execute(Redis connection) {
1835     //         return connection.pfmerge(destkey, sourcekeys);
1836     //     }
1837     //     }.runBinary(wholeKeys.length, wholeKeys);
1838     // }
1839 
1840     // override
1841     // long pfcount(const(ubyte)[][] keys...) {
1842     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1843     //     override
1844     //     Long execute(Redis connection) {
1845     //         return connection.pfcount(keys);
1846     //     }
1847     //     }.runBinary(keys.length, keys);
1848     // }
1849 
1850     // override
1851     // long geoadd(const(ubyte)[] key, double longitude, double latitude,
1852     //     const(ubyte)[] member) {
1853     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1854     //     override
1855     //     Long execute(Redis connection) {
1856     //         return connection.geoadd(key, longitude, latitude, member);
1857     //     }
1858     //     }.runBinary(key);
1859     // }
1860 
1861     // override
1862     // long geoadd(const(ubyte)[] key, Map!(const(ubyte)[], GeoCoordinate) memberCoordinateMap) {
1863     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
1864     //     override
1865     //     Long execute(Redis connection) {
1866     //         return connection.geoadd(key, memberCoordinateMap);
1867     //     }
1868     //     }.runBinary(key);
1869     // }
1870 
1871     // override
1872     // Double geodist(const(ubyte)[] key, const(ubyte)[] member1, const(ubyte)[] member2) {
1873     //     return new RedisClusterCommand!(Double)(connectionHandler, maxAttempts) {
1874     //     override
1875     //     Double execute(Redis connection) {
1876     //         return connection.geodist(key, member1, member2);
1877     //     }
1878     //     }.runBinary(key);
1879     // }
1880 
1881     // override
1882     // Double geodist(const(ubyte)[] key, const(ubyte)[] member1, const(ubyte)[] member2,
1883     //     GeoUnit unit) {
1884     //     return new RedisClusterCommand!(Double)(connectionHandler, maxAttempts) {
1885     //     override
1886     //     Double execute(Redis connection) {
1887     //         return connection.geodist(key, member1, member2, unit);
1888     //     }
1889     //     }.runBinary(key);
1890     // }
1891 
1892     // override
1893     // List!(const(ubyte)[]) geohash(const(ubyte)[] key, const(ubyte)[][] members...) {
1894     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
1895     //     override
1896     //     List!(const(ubyte)[]) execute(Redis connection) {
1897     //         return connection.geohash(key, members);
1898     //     }
1899     //     }.runBinary(key);
1900     // }
1901 
1902     // override
1903     // List!(GeoCoordinate) geopos(const(ubyte)[] key, const(ubyte)[][] members...) {
1904     //     return new RedisClusterCommand!(List!(GeoCoordinate))(connectionHandler, maxAttempts) {
1905     //     override
1906     //     List!(GeoCoordinate) execute(Redis connection) {
1907     //         return connection.geopos(key, members);
1908     //     }
1909     //     }.runBinary(key);
1910     // }
1911 
1912     // override
1913     // List!(GeoRadiusResponse) georadius(const(ubyte)[] key, double longitude,
1914     //     double latitude, double radius, GeoUnit unit) {
1915     //     return new RedisClusterCommand!(List!(GeoRadiusResponse))(connectionHandler, maxAttempts) {
1916     //     override
1917     //     List!(GeoRadiusResponse) execute(Redis connection) {
1918     //         return connection.georadius(key, longitude, latitude, radius, unit);
1919     //     }
1920     //     }.runBinary(key);
1921     // }
1922 
1923     // override
1924     // List!(GeoRadiusResponse) georadiusReadonly(const(ubyte)[] key, double longitude,
1925     //     double latitude, double radius, GeoUnit unit) {
1926     //     return new RedisClusterCommand!(List!(GeoRadiusResponse))(connectionHandler, maxAttempts) {
1927     //     override
1928     //     List!(GeoRadiusResponse) execute(Redis connection) {
1929     //         return connection.georadiusReadonly(key, longitude, latitude, radius, unit);
1930     //     }
1931     //     }.runBinary(key);
1932     // }
1933 
1934     // override
1935     // List!(GeoRadiusResponse) georadius(const(ubyte)[] key, double longitude,
1936     //     double latitude, double radius, GeoUnit unit, GeoRadiusParam param) {
1937     //     return new RedisClusterCommand!(List!(GeoRadiusResponse))(connectionHandler, maxAttempts) {
1938     //     override
1939     //     List!(GeoRadiusResponse) execute(Redis connection) {
1940     //         return connection.georadius(key, longitude, latitude, radius, unit, param);
1941     //     }
1942     //     }.runBinary(key);
1943     // }
1944 
1945     // override
1946     // List!(GeoRadiusResponse) georadiusReadonly(const(ubyte)[] key, double longitude,
1947     //     double latitude, double radius, GeoUnit unit, GeoRadiusParam param) {
1948     //     return new RedisClusterCommand!(List!(GeoRadiusResponse))(connectionHandler, maxAttempts) {
1949     //     override
1950     //     List!(GeoRadiusResponse) execute(Redis connection) {
1951     //         return connection.georadiusReadonly(key, longitude, latitude, radius, unit, param);
1952     //     }
1953     //     }.runBinary(key);
1954     // }
1955 
1956     // override
1957     // List!(GeoRadiusResponse) georadiusByMember(const(ubyte)[] key, const(ubyte)[] member,
1958     //     double radius, GeoUnit unit) {
1959     //     return new RedisClusterCommand!(List!(GeoRadiusResponse))(connectionHandler, maxAttempts) {
1960     //     override
1961     //     List!(GeoRadiusResponse) execute(Redis connection) {
1962     //         return connection.georadiusByMember(key, member, radius, unit);
1963     //     }
1964     //     }.runBinary(key);
1965     // }
1966 
1967     // override
1968     // List!(GeoRadiusResponse) georadiusByMemberReadonly(const(ubyte)[] key, const(ubyte)[] member,
1969     //     double radius, GeoUnit unit) {
1970     //     return new RedisClusterCommand!(List!(GeoRadiusResponse))(connectionHandler, maxAttempts) {
1971     //     override
1972     //     List!(GeoRadiusResponse) execute(Redis connection) {
1973     //         return connection.georadiusByMemberReadonly(key, member, radius, unit);
1974     //     }
1975     //     }.runBinary(key);
1976     // }
1977 
1978     // override
1979     // List!(GeoRadiusResponse) georadiusByMember(const(ubyte)[] key, const(ubyte)[] member,
1980     //     double radius, GeoUnit unit, GeoRadiusParam param) {
1981     //     return new RedisClusterCommand!(List!(GeoRadiusResponse))(connectionHandler, maxAttempts) {
1982     //     override
1983     //     List!(GeoRadiusResponse) execute(Redis connection) {
1984     //         return connection.georadiusByMember(key, member, radius, unit, param);
1985     //     }
1986     //     }.runBinary(key);
1987     // }
1988 
1989     // override
1990     // List!(GeoRadiusResponse) georadiusByMemberReadonly(const(ubyte)[] key, const(ubyte)[] member,
1991     //     double radius, GeoUnit unit, GeoRadiusParam param) {
1992     //     return new RedisClusterCommand!(List!(GeoRadiusResponse))(connectionHandler, maxAttempts) {
1993     //     override
1994     //     List!(GeoRadiusResponse) execute(Redis connection) {
1995     //         return connection.georadiusByMemberReadonly(key, member, radius, unit, param);
1996     //     }
1997     //     }.runBinary(key);
1998     // }
1999 
2000     // override
2001     // Set!(const(ubyte)[]) keys(const(ubyte)[] pattern) {
2002     //     if (pattern is null || pattern.length == 0) {
2003     //     throw new IllegalArgumentException(this.getClass().getSimpleName()
2004     //         ~ " only supports KEYS commands with non-empty patterns");
2005     //     }
2006     //     if (!RedisClusterHashTagUtil.isClusterCompliantMatchPattern(pattern)) {
2007     //     throw new IllegalArgumentException(this.getClass().getSimpleName()
2008     //         ~ " only supports KEYS commands with patterns containing hash-tags ( curly-brackets enclosed strings )");
2009     //     }
2010     //     return new RedisClusterCommand!(Set!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2011     //     override
2012     //     Set!(const(ubyte)[]) execute(Redis connection) {
2013     //         return connection.keys(pattern);
2014     //     }
2015     //     }.runBinary(pattern);
2016     // }
2017 
2018     // override
2019     // ScanResult!(const(ubyte)[]) scan(const(ubyte)[] cursor, ScanParams params) {
2020 
2021     //     const(ubyte)[] matchPattern = null;
2022 
2023     //     if (params is null || (matchPattern = params.binaryMatch()) is null || matchPattern.length == 0) {
2024     //     throw new IllegalArgumentException(BinaryRedisCluster.class.getSimpleName()
2025     //         ~ " only supports SCAN commands with non-empty MATCH patterns");
2026     //     }
2027 
2028     //     if (!RedisClusterHashTagUtil.isClusterCompliantMatchPattern(matchPattern)) {
2029     //     throw new IllegalArgumentException(BinaryRedisCluster.class.getSimpleName()
2030     //         ~ " only supports SCAN commands with MATCH patterns containing hash-tags ( curly-brackets enclosed strings )");
2031     //     }
2032 
2033     //     return new RedisClusterCommand!( ScanResult!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2034     //     override
2035     //     ScanResult!(const(ubyte)[]) execute(Redis connection) {
2036     //         return connection.scan(cursor, params);
2037     //     }
2038     //     }.runBinary(matchPattern);
2039     // }
2040     
2041     // override
2042     // ScanResult!(MapEntry!(const(ubyte)[], const(ubyte)[])) hscan(const(ubyte)[] key, const(ubyte)[] cursor) {
2043     //     return new RedisClusterCommand!(ScanResult!(MapEntry!(const(ubyte)[], const(ubyte)[])))(connectionHandler,
2044     //                                                                         maxAttempts) {
2045     //     override
2046     //     ScanResult!(MapEntry!(const(ubyte)[], const(ubyte)[])) execute(Redis connection) {
2047     //         return connection.hscan(key, cursor);
2048     //     }
2049     //     }.runBinary(key);
2050     // }
2051 
2052     // override
2053     // ScanResult!(MapEntry!(const(ubyte)[], const(ubyte)[])) hscan(const(ubyte)[] key, const(ubyte)[] cursor,
2054     //     ScanParams params) {
2055     //     return new RedisClusterCommand!(ScanResult!(MapEntry!(const(ubyte)[], const(ubyte)[])))(connectionHandler,
2056     //                                                                         maxAttempts) {
2057     //     override
2058     //     ScanResult!(MapEntry!(const(ubyte)[], const(ubyte)[])) execute(Redis connection) {
2059     //         return connection.hscan(key, cursor, params);
2060     //     }
2061     //     }.runBinary(key);
2062     // }
2063 
2064     // override
2065     // ScanResult!(const(ubyte)[]) sscan(const(ubyte)[] key, const(ubyte)[] cursor) {
2066     //     return new RedisClusterCommand!(ScanResult!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2067     //     override
2068     //     ScanResult!(const(ubyte)[]) execute(Redis connection) {
2069     //         return connection.sscan(key, cursor);
2070     //     }
2071     //     }.runBinary(key);
2072     // }
2073 
2074     // override
2075     // ScanResult!(const(ubyte)[]) sscan(const(ubyte)[] key, const(ubyte)[] cursor, ScanParams params) {
2076     //     return new RedisClusterCommand!(ScanResult!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2077     //     override
2078     //     ScanResult!(const(ubyte)[]) execute(Redis connection) {
2079     //         return connection.sscan(key, cursor, params);
2080     //     }
2081     //     }.runBinary(key);
2082     // }
2083 
2084     // override
2085     // ScanResult!(Tuple) zscan(const(ubyte)[] key, const(ubyte)[] cursor) {
2086     //     return new RedisClusterCommand!(ScanResult!(Tuple))(connectionHandler, maxAttempts) {
2087     //     override
2088     //     ScanResult!(Tuple) execute(Redis connection) {
2089     //         return connection.zscan(key, cursor);
2090     //     }
2091     //     }.runBinary(key);
2092     // }
2093 
2094     // override
2095     // ScanResult!(Tuple) zscan(const(ubyte)[] key, const(ubyte)[] cursor, ScanParams params) {
2096     //     return new RedisClusterCommand!(ScanResult!(Tuple))(connectionHandler, maxAttempts) {
2097     //     override
2098     //     ScanResult!(Tuple) execute(Redis connection) {
2099     //         return connection.zscan(key, cursor, params);
2100     //     }
2101     //     }.runBinary(key);
2102     // }
2103 
2104     // override
2105     // List!(long) bitfield(const(ubyte)[] key, const(ubyte)[][] arguments...) {
2106     //     return new RedisClusterCommand!(List!(long))(connectionHandler, maxAttempts) {
2107     //     override
2108     //     List!(long) execute(Redis connection) {
2109     //         return connection.bitfield(key, arguments);
2110     //     }
2111     //     }.runBinary(key);
2112     // }
2113 
2114     // override
2115     // long hstrlen(const(ubyte)[] key, const(ubyte)[] field) {
2116     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
2117     //     override
2118     //     Long execute(Redis connection) {
2119     //         return connection.hstrlen(key, field);
2120     //     }
2121     //     }.runBinary(key);
2122     // }
2123     
2124     // override
2125     // const(ubyte)[] xadd(const(ubyte)[] key, const(ubyte)[] id, Map!(const(ubyte)[], const(ubyte)[]) hash, long maxLen, bool approximateLength){
2126     //     return new RedisClusterCommand!(const(ubyte)[])(connectionHandler, maxAttempts) {
2127     //     override
2128     //     const(ubyte)[] execute(Redis connection) {
2129     //         return connection.xadd(key, id, hash, maxLen, approximateLength);
2130     //     }
2131     //     }.runBinary(key);
2132     // }
2133 
2134     // override
2135     // long xlen(const(ubyte)[] key) {
2136     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
2137     //     override
2138     //     Long execute(Redis connection) {
2139     //         return connection.xlen(key);
2140     //     }
2141     //     }.runBinary(key);
2142     // }
2143 
2144     // override
2145     // List!(const(ubyte)[]) xrange(const(ubyte)[] key, const(ubyte)[] start, const(ubyte)[] end, long count) {
2146     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2147     //     override
2148     //     List!(const(ubyte)[]) execute(Redis connection) {
2149     //         return connection.xrange(key, start, end, count);
2150     //     }
2151     //     }.runBinary(key);
2152     // }
2153 
2154     // override
2155     // List!(const(ubyte)[]) xrevrange(const(ubyte)[] key, const(ubyte)[] end, const(ubyte)[] start, int count) {
2156     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2157     //     override
2158     //     List!(const(ubyte)[]) execute(Redis connection) {
2159     //         return connection.xrevrange(key, end, start, count);
2160     //     }
2161     //     }.runBinary(key);  
2162     // }
2163 
2164     // override
2165     // List!(const(ubyte)[]) xread(int count, long block, Map!(const(ubyte)[], const(ubyte)[]) streams) {
2166     //     const(ubyte)[][] keys = streams.keySet().toArray(new byte[streams.size()][]);
2167         
2168     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2169     //     override
2170     //     List!(const(ubyte)[]) execute(Redis connection) {
2171     //         return connection.xread(count, block, streams);
2172     //     }
2173     //     }.runBinary(keys.length, keys);  
2174     // }
2175 
2176     // override
2177     // long xack(const(ubyte)[] key, const(ubyte)[] group, const(ubyte)[][] ids...) {
2178     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
2179     //     override
2180     //     Long execute(Redis connection) {
2181     //         return connection.xack(key, group, ids);
2182     //     }
2183     //     }.runBinary(key);   
2184     // }
2185 
2186     // override
2187     // string xgroupCreate(const(ubyte)[] key, const(ubyte)[] consumer, const(ubyte)[] id, bool makeStream) {
2188     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
2189     //     override
2190     //     string execute(Redis connection) {
2191     //         return connection.xgroupCreate(key, consumer, id, makeStream);
2192     //     }
2193     //     }.runBinary(key);  
2194     // }
2195 
2196     // override
2197     // string xgroupSetID(const(ubyte)[] key, const(ubyte)[] consumer, const(ubyte)[] id) {
2198     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
2199     //     override
2200     //     string execute(Redis connection) {
2201     //         return connection.xgroupSetID(key, consumer, id);
2202     //     }
2203     //     }.runBinary(key);
2204     // }
2205 
2206     // override
2207     // long xgroupDestroy(const(ubyte)[] key, const(ubyte)[] consumer) {
2208     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
2209     //     override
2210     //     Long execute(Redis connection) {
2211     //         return connection.xgroupDestroy(key, consumer);
2212     //     }
2213     //     }.runBinary(key);
2214     // }
2215 
2216     // override
2217     // string xgroupDelConsumer(const(ubyte)[] key, const(ubyte)[] consumer, const(ubyte)[] consumerName) {
2218     //     return new RedisClusterCommand!(string)(connectionHandler, maxAttempts) {
2219     //     override
2220     //     string execute(Redis connection) {
2221     //         return connection.xgroupDelConsumer(key, consumer, consumerName);
2222     //     }
2223     //     }.runBinary(key);
2224     // }
2225 
2226     // override
2227     //     List!(const(ubyte)[]) xreadGroup(const(ubyte)[] groupname, const(ubyte)[] consumer, int count, long block, 
2228     //     bool noAck, Map!(const(ubyte)[], const(ubyte)[]) streams){
2229         
2230     //     const(ubyte)[][] keys = streams.keySet().toArray(new byte[streams.size()][]);
2231         
2232     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2233     //     override
2234     //     List!(const(ubyte)[]) execute(Redis connection) {
2235     //         return connection.xreadGroup(groupname, consumer, count, block, noAck, streams);
2236     //     }
2237     //     }.runBinary(keys.length, keys);
2238     // }
2239 
2240     // override
2241     // long xdel(const(ubyte)[] key, const(ubyte)[][] ids...) {
2242     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
2243     //     override
2244     //     Long execute(Redis connection) {
2245     //         return connection.xdel(key, ids);
2246     //     }
2247     //     }.runBinary(key);
2248     // }
2249 
2250     // override
2251     // long xtrim(const(ubyte)[] key, long maxLen, bool approximateLength) {
2252     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
2253     //     override
2254     //     Long execute(Redis connection) {
2255     //         return connection.xtrim(key, maxLen, approximateLength);
2256     //     }
2257     //     }.runBinary(key);
2258     // }
2259     
2260     // override
2261     // List!(const(ubyte)[]) xpending(const(ubyte)[] key, const(ubyte)[] groupname, const(ubyte)[] start, const(ubyte)[] end, 
2262     //     int count, const(ubyte)[] consumername) {
2263     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2264     //     override
2265     //     List!(const(ubyte)[]) execute(Redis connection) {
2266     //         return connection.xpending(key, groupname, start, end, count, consumername);
2267     //     }
2268     //     }.runBinary(key);
2269     // }
2270 
2271     // override
2272     // List!(const(ubyte)[]) xclaim(const(ubyte)[] key, const(ubyte)[] groupname, const(ubyte)[] consumername, 
2273     //     Long minIdleTime, long newIdleTime, int retries, bool force, const(ubyte)[][] ids) {
2274     //     return new RedisClusterCommand!(List!(const(ubyte)[]))(connectionHandler, maxAttempts) {
2275     //     override
2276     //     List!(const(ubyte)[]) execute(Redis connection) {
2277     //         return connection.xclaim(key, groupname, consumername, minIdleTime, newIdleTime, retries, force, ids);
2278     //     }
2279     //     }.runBinary(key);
2280     // }
2281 
2282     // override
2283     // long waitReplicas(const(ubyte)[] key, int replicas, long timeout) {
2284     //     return new RedisClusterCommand!(long)(connectionHandler, maxAttempts) {
2285     //     override
2286     //     Long execute(Redis connection) {
2287     //         return connection.waitReplicas(replicas, timeout);
2288     //     }
2289     //     }.runBinary(key);
2290     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
2291     // }
2292 
2293     // override
2294     // Object sendCommand(const(ubyte)[] sampleKey, ProtocolCommand cmd, const(ubyte)[][] args...) {
2295     //     return new RedisClusterCommand!(Object)(connectionHandler, maxAttempts) {
2296     //     override
2297     //     Object execute(Redis connection){
2298     //         return connection.sendCommand(cmd, args);
2299     //     }
2300     //     }.runBinary(sampleKey);
2301     //     mixin(ClusterBinaryCommandTemplate!("dump", const(ubyte)[], [key.stringof]));
2302     // }
2303 }