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.BinaryShardedRedis;
13 
14 import hunt.redis.Client;
15 import hunt.redis.Exceptions;
16 import hunt.redis.GeoCoordinate;
17 import hunt.redis.GeoRadiusResponse;
18 import hunt.redis.GeoUnit;
19 import hunt.redis.ListPosition;
20 import hunt.redis.Redis;
21 import hunt.redis.RedisShardInfo;
22 import hunt.redis.ShardedRedisPipeline;
23 import hunt.redis.ScanParams;
24 import hunt.redis.ScanResult;
25 import hunt.redis.SortingParams;
26 import hunt.redis.Tuple;
27 
28 
29 import hunt.collection.Collection;
30 import hunt.collection.List;
31 import hunt.collection.Map;
32 import hunt.collection.Set;
33 
34 import hunt.redis.commands.BinaryRedisCommands;
35 import hunt.redis.Protocol;
36 import hunt.redis.params.GeoRadiusParam;
37 import hunt.redis.params.SetParams;
38 import hunt.redis.params.ZAddParams;
39 import hunt.redis.params.ZIncrByParams;
40 import hunt.redis.util.Hashing;
41 import hunt.redis.util.Sharded;
42 
43 import hunt.Double;
44 import hunt.Long;
45 
46 import std.conv;
47 import std.regex;
48 alias Pattern = Regex!char;
49 
50 /**
51  * 
52  */
53 class BinaryShardedRedis : Sharded!(Redis, RedisShardInfo), BinaryRedisCommands {
54     this(List!(RedisShardInfo) shards) {
55         super(shards);
56     }
57 
58     this(List!(RedisShardInfo) shards, Hashing algo) {
59         super(shards, algo);
60     }
61 
62     this(List!(RedisShardInfo) shards, Pattern keyTagPattern) {
63         super(shards, keyTagPattern);
64     }
65 
66     this(List!(RedisShardInfo) shards, Hashing algo, Pattern keyTagPattern) {
67         super(shards, algo, keyTagPattern);
68     }
69 
70     void disconnect() {
71         foreach(Redis jedis ; getAllShards()) {
72             if (jedis.isConnected()) {
73                 try {
74                     jedis.quit();
75                 } catch (RedisConnectionException e) {
76                     // ignore the exception node, so that all other normal nodes can release all connections.
77                 }
78                 try {
79                     jedis.disconnect();
80                 } catch (RedisConnectionException e) {
81                     // ignore the exception node, so that all other normal nodes can release all connections.
82                 }
83             }
84         }
85     }
86 
87     protected Redis create(RedisShardInfo shard) {
88         return new Redis(shard);
89     }
90 
91     override
92     string set(const(ubyte)[] key, const(ubyte)[] value) {
93         Redis j = getShard(key);
94         return j.set(key, value);
95     }
96 
97     override
98     string set(const(ubyte)[] key, const(ubyte)[] value, SetParams params) {
99         Redis j = getShard(key);
100         return j.set(key, value, params);
101     }
102 
103     override
104     const(ubyte)[] get(const(ubyte)[] key) {
105         Redis j = getShard(key);
106         return j.get(key);
107     }
108 
109     override
110     bool exists(const(ubyte)[] key) {
111         Redis j = getShard(key);
112         return j.exists(key);
113     }
114 
115     override
116     string type(const(ubyte)[] key) {
117         Redis j = getShard(key);
118         return j.type(key);
119     }
120 
121     override
122     const(ubyte)[] dump(const(ubyte)[] key) {
123         Redis j = getShard(key);
124         return j.dump(key);
125     }
126 
127     override
128     string restore(const(ubyte)[] key, int ttl, const(ubyte)[] serializedValue) {
129         Redis j = getShard(key);
130         return j.restore(key, ttl, serializedValue);
131     }
132 
133     override
134     string restoreReplace(const(ubyte)[] key, int ttl, const(ubyte)[] serializedValue) {
135         Redis j = getShard(key);
136         return j.restoreReplace(key, ttl, serializedValue);
137     }
138 
139     override
140     Long expire(const(ubyte)[] key, int seconds) {
141         Redis j = getShard(key);
142         return j.expire(key, seconds);
143     }
144 
145     override
146     Long pexpire(const(ubyte)[] key, long milliseconds) {
147         Redis j = getShard(key);
148         return j.pexpire(key, milliseconds);
149     }
150 
151     override
152     Long expireAt(const(ubyte)[] key, long unixTime) {
153         Redis j = getShard(key);
154         return j.expireAt(key, unixTime);
155     }
156 
157     override
158     Long pexpireAt(const(ubyte)[] key, long millisecondsTimestamp) {
159         Redis j = getShard(key);
160         return j.pexpireAt(key, millisecondsTimestamp);
161     }
162 
163     override
164     Long ttl(const(ubyte)[] key) {
165         Redis j = getShard(key);
166         return j.ttl(key);
167     }
168 
169     override
170     Long pttl(const(ubyte)[] key) {
171         Redis j = getShard(key);
172         return j.pttl(key);
173     }
174 
175     override
176     Long touch(const(ubyte)[] key) {
177         Redis j = getShard(key);
178         return j.touch(key);
179     }
180 
181     override
182     const(ubyte)[] getSet(const(ubyte)[] key, const(ubyte)[] value) {
183         Redis j = getShard(key);
184         return j.getSet(key, value);
185     }
186 
187     override
188     Long setnx(const(ubyte)[] key, const(ubyte)[] value) {
189         Redis j = getShard(key);
190         return j.setnx(key, value);
191     }
192 
193     override
194     string setex(const(ubyte)[] key, int seconds, const(ubyte)[] value) {
195         Redis j = getShard(key);
196         return j.setex(key, seconds, value);
197     }
198 
199     override
200     string psetex(const(ubyte)[] key, long milliseconds, const(ubyte)[] value) {
201         Redis j = getShard(key);
202         return j.psetex(key, milliseconds, value);
203     }
204 
205     override
206     Long decrBy(const(ubyte)[] key, long decrement) {
207         Redis j = getShard(key);
208         return j.decrBy(key, decrement);
209     }
210 
211     override
212     Long decr(const(ubyte)[] key) {
213         Redis j = getShard(key);
214         return j.decr(key);
215     }
216 
217     override
218     Long del(const(ubyte)[] key) {
219         Redis j = getShard(key);
220         return j.del(key);
221     }
222 
223     override
224     Long unlink(const(ubyte)[] key) {
225         Redis j = getShard(key);
226         return j.unlink(key);
227     }
228 
229     override
230     Long incrBy(const(ubyte)[] key, long increment) {
231         Redis j = getShard(key);
232         return j.incrBy(key, increment);
233     }
234 
235     override
236     Double incrByFloat(const(ubyte)[] key, double increment) {
237         Redis j = getShard(key);
238         return j.incrByFloat(key, increment);
239     }
240 
241 //     override
242 //     Long incr(const(ubyte)[] key) {
243 //         Redis j = getShard(key);
244 //         return j.incr(key);
245 //     }
246 
247 //     override
248 //     Long append(const(ubyte)[] key, const(ubyte)[] value) {
249 //         Redis j = getShard(key);
250 //         return j.append(key, value);
251 //     }
252 
253 //     override
254 //     const(ubyte)[] substr(const(ubyte)[] key, int start, int end) {
255 //         Redis j = getShard(key);
256 //         return j.substr(key, start, end);
257 //     }
258 
259 //     override
260 //     Long hset(const(ubyte)[] key, const(ubyte)[] field, const(ubyte)[] value) {
261 //         Redis j = getShard(key);
262 //         return j.hset(key, field, value);
263 //     }
264 
265 //     override
266 //     Long hset(const(ubyte)[] key, Map!(const(ubyte)[], const(ubyte)[]) hash) {
267 //         Redis j = getShard(key);
268 //         return j.hset(key, hash);
269 //     }
270 
271 //     override
272 //     const(ubyte)[] hget(const(ubyte)[] key, const(ubyte)[] field) {
273 //         Redis j = getShard(key);
274 //         return j.hget(key, field);
275 //     }
276 
277 //     override
278 //     Long hsetnx(const(ubyte)[] key, const(ubyte)[] field, const(ubyte)[] value) {
279 //         Redis j = getShard(key);
280 //         return j.hsetnx(key, field, value);
281 //     }
282 
283 //     override
284 //     string hmset(const(ubyte)[] key, Map!(const(ubyte)[], const(ubyte)[]) hash) {
285 //         Redis j = getShard(key);
286 //         return j.hmset(key, hash);
287 //     }
288 
289 //     override
290 //     List!(const(ubyte)[]) hmget(const(ubyte)[] key, const(ubyte)[][] fields...) {
291 //         Redis j = getShard(key);
292 //         return j.hmget(key, fields);
293 //     }
294 
295 //     override
296 //     Long hincrBy(const(ubyte)[] key, const(ubyte)[] field, long value) {
297 //         Redis j = getShard(key);
298 //         return j.hincrBy(key, field, value);
299 //     }
300 
301 //     override
302 //     Double hincrByFloat(const(ubyte)[] key, const(ubyte)[] field, double value) {
303 //         Redis j = getShard(key);
304 //         return j.hincrByFloat(key, field, value);
305 //     }
306 
307 //     override
308 //     bool hexists(const(ubyte)[] key, const(ubyte)[] field) {
309 //         Redis j = getShard(key);
310 //         return j.hexists(key, field);
311 //     }
312 
313 //     override
314 //     Long hdel(const(ubyte)[] key, const(ubyte)[][] fields...) {
315 //         Redis j = getShard(key);
316 //         return j.hdel(key, fields);
317 //     }
318 
319 //     override
320 //     Long hlen(const(ubyte)[] key) {
321 //         Redis j = getShard(key);
322 //         return j.hlen(key);
323 //     }
324 
325 //     override
326 //     Set!(const(ubyte)[]) hkeys(const(ubyte)[] key) {
327 //         Redis j = getShard(key);
328 //         return j.hkeys(key);
329 //     }
330 
331 //     override
332 //     Collection!(const(ubyte)[]) hvals(const(ubyte)[] key) {
333 //         Redis j = getShard(key);
334 //         return j.hvals(key);
335 //     }
336 
337 //     override
338 //     Map!(const(ubyte)[], const(ubyte)[]) hgetAll(const(ubyte)[] key) {
339 //         Redis j = getShard(key);
340 //         return j.hgetAll(key);
341 //     }
342 
343 //     override
344 //     Long rpush(const(ubyte)[] key, const(ubyte)[][] strings...) {
345 //         Redis j = getShard(key);
346 //         return j.rpush(key, strings);
347 //     }
348 
349 //     override
350 //     Long lpush(const(ubyte)[] key, const(ubyte)[][] strings...) {
351 //         Redis j = getShard(key);
352 //         return j.lpush(key, strings);
353 //     }
354 
355     override
356     Long strlen(const(ubyte)[] key) {
357         Redis j = getShard(key);
358         return j.strlen(key);
359     }
360 
361 //     override
362 //     Long lpushx(const(ubyte)[] key, const(ubyte)[][] string...) {
363 //         Redis j = getShard(key);
364 //         return j.lpushx(key, string);
365 //     }
366 
367     override
368     Long persist(const(ubyte)[] key) {
369         Redis j = getShard(key);
370         return j.persist(key);
371     }
372 
373 //     override
374 //     Long rpushx(const(ubyte)[] key, const(ubyte)[][] string...) {
375 //         Redis j = getShard(key);
376 //         return j.rpushx(key, string);
377 //     }
378 
379 //     override
380 //     Long llen(const(ubyte)[] key) {
381 //         Redis j = getShard(key);
382 //         return j.llen(key);
383 //     }
384 
385 //     override
386 //     List!(const(ubyte)[]) lrange(const(ubyte)[] key, long start, long stop) {
387 //         Redis j = getShard(key);
388 //         return j.lrange(key, start, stop);
389 //     }
390 
391 //     override
392 //     string ltrim(const(ubyte)[] key, long start, long stop) {
393 //         Redis j = getShard(key);
394 //         return j.ltrim(key, start, stop);
395 //     }
396 
397 //     override
398 //     const(ubyte)[] lindex(const(ubyte)[] key, long index) {
399 //         Redis j = getShard(key);
400 //         return j.lindex(key, index);
401 //     }
402 
403 //     override
404 //     string lset(const(ubyte)[] key, long index, const(ubyte)[] value) {
405 //         Redis j = getShard(key);
406 //         return j.lset(key, index, value);
407 //     }
408 
409 //     override
410 //     Long lrem(const(ubyte)[] key, long count, const(ubyte)[] value) {
411 //         Redis j = getShard(key);
412 //         return j.lrem(key, count, value);
413 //     }
414 
415 //     override
416 //     const(ubyte)[] lpop(const(ubyte)[] key) {
417 //         Redis j = getShard(key);
418 //         return j.lpop(key);
419 //     }
420 
421 //     override
422 //     const(ubyte)[] rpop(const(ubyte)[] key) {
423 //         Redis j = getShard(key);
424 //         return j.rpop(key);
425 //     }
426 
427 //     override
428 //     Long sadd(const(ubyte)[] key, const(ubyte)[][] members...) {
429 //         Redis j = getShard(key);
430 //         return j.sadd(key, members);
431 //     }
432 
433 //     override
434 //     Set!(const(ubyte)[]) smembers(const(ubyte)[] key) {
435 //         Redis j = getShard(key);
436 //         return j.smembers(key);
437 //     }
438 
439 //     override
440 //     Long srem(const(ubyte)[] key, const(ubyte)[][] members...) {
441 //         Redis j = getShard(key);
442 //         return j.srem(key, members);
443 //     }
444 
445 //     override
446 //     const(ubyte)[] spop(const(ubyte)[] key) {
447 //         Redis j = getShard(key);
448 //         return j.spop(key);
449 //     }
450 
451 //     override
452 //     Set!(const(ubyte)[]) spop(const(ubyte)[] key, long count) {
453 //         Redis j = getShard(key);
454 //         return j.spop(key, count);
455 //     }
456 
457 //     override
458 //     Long scard(const(ubyte)[] key) {
459 //         Redis j = getShard(key);
460 //         return j.scard(key);
461 //     }
462 
463 //     override
464 //     bool sismember(const(ubyte)[] key, const(ubyte)[] member) {
465 //         Redis j = getShard(key);
466 //         return j.sismember(key, member);
467 //     }
468 
469 //     override
470 //     const(ubyte)[] srandmember(const(ubyte)[] key) {
471 //         Redis j = getShard(key);
472 //         return j.srandmember(key);
473 //     }
474 
475 //     override
476 //     List!(const(ubyte)[]) srandmember(const(ubyte)[] key, int count) {
477 //         Redis j = getShard(key);
478 //         return j.srandmember(key, count);
479 //     }
480 
481 //     override
482 //     Long zadd(const(ubyte)[] key, double score, const(ubyte)[] member) {
483 //         Redis j = getShard(key);
484 //         return j.zadd(key, score, member);
485 //     }
486 
487 //     override
488 //     Long zadd(const(ubyte)[] key, double score, const(ubyte)[] member, ZAddParams params) {
489 //         Redis j = getShard(key);
490 //         return j.zadd(key, score, member, params);
491 //     }
492 
493 //     override
494 //     Long zadd(const(ubyte)[] key, Map!(const(ubyte)[], Double) scoreMembers) {
495 //         Redis j = getShard(key);
496 //         return j.zadd(key, scoreMembers);
497 //     }
498 
499 //     override
500 //     Long zadd(const(ubyte)[] key, Map!(const(ubyte)[], Double) scoreMembers, ZAddParams params) {
501 //         Redis j = getShard(key);
502 //         return j.zadd(key, scoreMembers, params);
503 //     }
504 
505 //     override
506 //     Set!(const(ubyte)[]) zrange(const(ubyte)[] key, long start, long stop) {
507 //         Redis j = getShard(key);
508 //         return j.zrange(key, start, stop);
509 //     }
510 
511 //     override
512 //     Long zrem(const(ubyte)[] key, const(ubyte)[][] members...) {
513 //         Redis j = getShard(key);
514 //         return j.zrem(key, members);
515 //     }
516 
517 //     override
518 //     Double zincrby(const(ubyte)[] key, double increment, const(ubyte)[] member) {
519 //         Redis j = getShard(key);
520 //         return j.zincrby(key, increment, member);
521 //     }
522 
523 //     override
524 //     Double zincrby(const(ubyte)[] key, double increment, const(ubyte)[] member, ZIncrByParams params) {
525 //         Redis j = getShard(key);
526 //         return j.zincrby(key, increment, member, params);
527 //     }
528 
529 //     override
530 //     Long zrank(const(ubyte)[] key, const(ubyte)[] member) {
531 //         Redis j = getShard(key);
532 //         return j.zrank(key, member);
533 //     }
534 
535 //     override
536 //     Long zrevrank(const(ubyte)[] key, const(ubyte)[] member) {
537 //         Redis j = getShard(key);
538 //         return j.zrevrank(key, member);
539 //     }
540 
541 //     override
542 //     Set!(const(ubyte)[]) zrevrange(const(ubyte)[] key, long start, long stop) {
543 //         Redis j = getShard(key);
544 //         return j.zrevrange(key, start, stop);
545 //     }
546 
547 //     override
548 //     Set!(Tuple) zrangeWithScores(const(ubyte)[] key, long start, long stop) {
549 //         Redis j = getShard(key);
550 //         return j.zrangeWithScores(key, start, stop);
551 //     }
552 
553 //     override
554 //     Set!(Tuple) zrevrangeWithScores(const(ubyte)[] key, long start, long stop) {
555 //         Redis j = getShard(key);
556 //         return j.zrevrangeWithScores(key, start, stop);
557 //     }
558 
559 //     override
560 //     Long zcard(const(ubyte)[] key) {
561 //         Redis j = getShard(key);
562 //         return j.zcard(key);
563 //     }
564 
565 //     override
566 //     Double zscore(const(ubyte)[] key, const(ubyte)[] member) {
567 //         Redis j = getShard(key);
568 //         return j.zscore(key, member);
569 //     }
570 
571 //     override
572 //     List!(const(ubyte)[]) sort(const(ubyte)[] key) {
573 //         Redis j = getShard(key);
574 //         return j.sort(key);
575 //     }
576 
577 //     override
578 //     List!(const(ubyte)[]) sort(const(ubyte)[] key, SortingParams sortingParameters) {
579 //         Redis j = getShard(key);
580 //         return j.sort(key, sortingParameters);
581 //     }
582 
583 //     override
584 //     Long zcount(const(ubyte)[] key, double min, double max) {
585 //         Redis j = getShard(key);
586 //         return j.zcount(key, min, max);
587 //     }
588 
589 //     override
590 //     Long zcount(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
591 //         Redis j = getShard(key);
592 //         return j.zcount(key, min, max);
593 //     }
594 
595 //     override
596 //     Set!(const(ubyte)[]) zrangeByScore(const(ubyte)[] key, double min, double max) {
597 //         Redis j = getShard(key);
598 //         return j.zrangeByScore(key, min, max);
599 //     }
600 
601 //     override
602 //     Set!(const(ubyte)[]) zrangeByScore(const(ubyte)[] key, double min, double max, int offset, int count) {
603 //         Redis j = getShard(key);
604 //         return j.zrangeByScore(key, min, max, offset, count);
605 //     }
606 
607 //     override
608 //     Set!(Tuple) zrangeByScoreWithScores(const(ubyte)[] key, double min, double max) {
609 //         Redis j = getShard(key);
610 //         return j.zrangeByScoreWithScores(key, min, max);
611 //     }
612 
613 //     override
614 //     Set!(Tuple) zrangeByScoreWithScores(const(ubyte)[] key, double min, double max, int offset,
615 //             int count) {
616 //         Redis j = getShard(key);
617 //         return j.zrangeByScoreWithScores(key, min, max, offset, count);
618 //     }
619 
620 //     override
621 //     Set!(const(ubyte)[]) zrangeByScore(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
622 //         Redis j = getShard(key);
623 //         return j.zrangeByScore(key, min, max);
624 //     }
625 
626 //     override
627 //     Set!(Tuple) zrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
628 //         Redis j = getShard(key);
629 //         return j.zrangeByScoreWithScores(key, min, max);
630 //     }
631 
632 //     override
633 //     Set!(Tuple) zrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max, int offset,
634 //             int count) {
635 //         Redis j = getShard(key);
636 //         return j.zrangeByScoreWithScores(key, min, max, offset, count);
637 //     }
638 
639 //     override
640 //     Set!(const(ubyte)[]) zrangeByScore(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max, int offset, int count) {
641 //         Redis j = getShard(key);
642 //         return j.zrangeByScore(key, min, max, offset, count);
643 //     }
644 
645 //     override
646 //     Set!(const(ubyte)[]) zrevrangeByScore(const(ubyte)[] key, double max, double min) {
647 //         Redis j = getShard(key);
648 //         return j.zrevrangeByScore(key, max, min);
649 //     }
650 
651 //     override
652 //     Set!(const(ubyte)[]) zrevrangeByScore(const(ubyte)[] key, double max, double min, int offset, int count) {
653 //         Redis j = getShard(key);
654 //         return j.zrevrangeByScore(key, max, min, offset, count);
655 //     }
656 
657 //     override
658 //     Set!(Tuple) zrevrangeByScoreWithScores(const(ubyte)[] key, double max, double min) {
659 //         Redis j = getShard(key);
660 //         return j.zrevrangeByScoreWithScores(key, max, min);
661 //     }
662 
663 //     override
664 //     Set!(Tuple) zrevrangeByScoreWithScores(const(ubyte)[] key, double max, double min, int offset,
665 //             int count) {
666 //         Redis j = getShard(key);
667 //         return j.zrevrangeByScoreWithScores(key, max, min, offset, count);
668 //     }
669 
670 //     override
671 //     Set!(const(ubyte)[]) zrevrangeByScore(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min) {
672 //         Redis j = getShard(key);
673 //         return j.zrevrangeByScore(key, max, min);
674 //     }
675 
676 //     override
677 //     Set!(const(ubyte)[]) zrevrangeByScore(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min, int offset, int count) {
678 //         Redis j = getShard(key);
679 //         return j.zrevrangeByScore(key, max, min, offset, count);
680 //     }
681 
682 //     override
683 //     Set!(Tuple) zrevrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min) {
684 //         Redis j = getShard(key);
685 //         return j.zrevrangeByScoreWithScores(key, max, min);
686 //     }
687 
688 //     override
689 //     Set!(Tuple) zrevrangeByScoreWithScores(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min, int offset,
690 //             int count) {
691 //         Redis j = getShard(key);
692 //         return j.zrevrangeByScoreWithScores(key, max, min, offset, count);
693 //     }
694 
695 //     override
696 //     Long zremrangeByRank(const(ubyte)[] key, long start, long stop) {
697 //         Redis j = getShard(key);
698 //         return j.zremrangeByRank(key, start, stop);
699 //     }
700 
701 //     override
702 //     Long zremrangeByScore(const(ubyte)[] key, double min, double max) {
703 //         Redis j = getShard(key);
704 //         return j.zremrangeByScore(key, min, max);
705 //     }
706 
707 //     override
708 //     Long zremrangeByScore(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
709 //         Redis j = getShard(key);
710 //         return j.zremrangeByScore(key, min, max);
711 //     }
712 
713 //     override
714 //     Long zlexcount(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
715 //         Redis j = getShard(key);
716 //         return j.zlexcount(key, min, max);
717 //     }
718 
719 //     override
720 //     Set!(const(ubyte)[]) zrangeByLex(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
721 //         Redis j = getShard(key);
722 //         return j.zrangeByLex(key, min, max);
723 //     }
724 
725 //     override
726 //     Set!(const(ubyte)[]) zrangeByLex(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max,
727 //             int offset, int count) {
728 //         Redis j = getShard(key);
729 //         return j.zrangeByLex(key, min, max, offset, count);
730 //     }
731 
732 //     override
733 //     Set!(const(ubyte)[]) zrevrangeByLex(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min) {
734 //         Redis j = getShard(key);
735 //         return j.zrevrangeByLex(key, max, min);
736 //     }
737 
738 //     override
739 //     Set!(const(ubyte)[]) zrevrangeByLex(const(ubyte)[] key, const(ubyte)[] max, const(ubyte)[] min, int offset, int count) {
740 //         Redis j = getShard(key);
741 //         return j.zrevrangeByLex(key, max, min, offset, count);
742 //     }
743 
744 //     override
745 //     Long zremrangeByLex(const(ubyte)[] key, const(ubyte)[] min, const(ubyte)[] max) {
746 //         Redis j = getShard(key);
747 //         return j.zremrangeByLex(key, min, max);
748 //     }
749 
750 //     override
751 //     Long linsert(const(ubyte)[] key, ListPosition where, const(ubyte)[] pivot, const(ubyte)[] value) {
752 //         Redis j = getShard(key);
753 //         return j.linsert(key, where, pivot, value);
754 //     }
755 
756 //     ShardedRedisPipeline pipelined() {
757 //         ShardedRedisPipeline pipeline = new ShardedRedisPipeline();
758 //         pipeline.setShardedRedis(this);
759 //         return pipeline;
760 //     }
761 
762 //     Long objectRefcount(const(ubyte)[] key) {
763 //         Redis j = getShard(key);
764 //         return j.objectRefcount(key);
765 //     }
766 
767 //     const(ubyte)[] objectEncoding(const(ubyte)[] key) {
768 //         Redis j = getShard(key);
769 //         return j.objectEncoding(key);
770 //     }
771 
772 //     Long objectIdletime(const(ubyte)[] key) {
773 //         Redis j = getShard(key);
774 //         return j.objectIdletime(key);
775 //     }
776 
777     override
778     bool setbit(const(ubyte)[] key, long offset, bool value) {
779         Redis j = getShard(key);
780         return j.setbit(key, offset, value);
781     }
782 
783     override
784     bool setbit(const(ubyte)[] key, long offset, const(ubyte)[] value) {
785         Redis j = getShard(key);
786         return j.setbit(key, offset, value);
787     }
788 
789     override
790     bool getbit(const(ubyte)[] key, long offset) {
791         Redis j = getShard(key);
792         return j.getbit(key, offset);
793     }
794 
795     override
796     Long setrange(const(ubyte)[] key, long offset, const(ubyte)[] value) {
797         Redis j = getShard(key);
798         return j.setrange(key, offset, value);
799     }
800 
801     override
802     const(ubyte)[] getrange(const(ubyte)[] key, long startOffset, long endOffset) {
803         Redis j = getShard(key);
804         return j.getrange(key, startOffset, endOffset);
805     }
806 
807     override
808     Long move(const(ubyte)[] key, int dbIndex) {
809         Redis j = getShard(key);
810         return j.move(key, dbIndex);
811     }
812 
813     override
814     const(ubyte)[] echo(const(ubyte)[] arg) {
815         Redis j = getShard(arg);
816         return j.echo(arg);
817     }
818 
819 //     List!(const(ubyte)[]) brpop(const(ubyte)[] arg) {
820 //         Redis j = getShard(arg);
821 //         return j.brpop(arg);
822 //     }
823 
824 //     List!(const(ubyte)[]) blpop(const(ubyte)[] arg) {
825 //         Redis j = getShard(arg);
826 //         return j.blpop(arg);
827 //     }
828 
829     override
830     Long bitcount(const(ubyte)[] key) {
831         Redis j = getShard(key);
832         return j.bitcount(key);
833     }
834 
835     override
836     Long bitcount(const(ubyte)[] key, long start, long end) {
837         Redis j = getShard(key);
838         return j.bitcount(key, start, end);
839     }
840 
841     override
842     Long pfadd(const(ubyte)[] key, const(ubyte)[][] elements...) {
843         Redis j = getShard(key);
844         return j.pfadd(key, elements);
845     }
846 
847     override
848     Long pfcount(const(ubyte)[] key) {
849         Redis j = getShard(key);
850         return j.pfcount(key);
851     }
852 
853 //     override
854 //     Long geoadd(const(ubyte)[] key, double longitude, double latitude, const(ubyte)[] member) {
855 //         Redis j = getShard(key);
856 //         return j.geoadd(key, longitude, latitude, member);
857 //     }
858 
859 //     override
860 //     Long geoadd(const(ubyte)[] key, Map!(const(ubyte)[], GeoCoordinate) memberCoordinateMap) {
861 //         Redis j = getShard(key);
862 //         return j.geoadd(key, memberCoordinateMap);
863 //     }
864 
865 //     override
866 //     Double geodist(const(ubyte)[] key, const(ubyte)[] member1, const(ubyte)[] member2) {
867 //         Redis j = getShard(key);
868 //         return j.geodist(key, member1, member2);
869 //     }
870 
871 //     override
872 //     Double geodist(const(ubyte)[] key, const(ubyte)[] member1, const(ubyte)[] member2, GeoUnit unit) {
873 //         Redis j = getShard(key);
874 //         return j.geodist(key, member1, member2, unit);
875 //     }
876 
877 //     override
878 //     List!(const(ubyte)[]) geohash(const(ubyte)[] key, const(ubyte)[][] members...) {
879 //         Redis j = getShard(key);
880 //         return j.geohash(key, members);
881 //     }
882 
883 //     override
884 //     List!(GeoCoordinate) geopos(const(ubyte)[] key, const(ubyte)[][] members...) {
885 //         Redis j = getShard(key);
886 //         return j.geopos(key, members);
887 //     }
888 
889 //     override
890 //     List!(GeoRadiusResponse) georadius(const(ubyte)[] key, double longitude, double latitude,
891 //             double radius, GeoUnit unit) {
892 //         Redis j = getShard(key);
893 //         return j.georadius(key, longitude, latitude, radius, unit);
894 //     }
895 
896 //     override
897 //     List!(GeoRadiusResponse) georadiusReadonly(const(ubyte)[] key, double longitude, double latitude,
898 //             double radius, GeoUnit unit) {
899 //         Redis j = getShard(key);
900 //         return j.georadiusReadonly(key, longitude, latitude, radius, unit);
901 //     }
902 
903 //     override
904 //     List!(GeoRadiusResponse) georadius(const(ubyte)[] key, double longitude, double latitude,
905 //             double radius, GeoUnit unit, GeoRadiusParam param) {
906 //         Redis j = getShard(key);
907 //         return j.georadius(key, longitude, latitude, radius, unit, param);
908 //     }
909 
910 //     override
911 //     List!(GeoRadiusResponse) georadiusReadonly(const(ubyte)[] key, double longitude, double latitude,
912 //             double radius, GeoUnit unit, GeoRadiusParam param) {
913 //         Redis j = getShard(key);
914 //         return j.georadiusReadonly(key, longitude, latitude, radius, unit, param);
915 //     }
916 
917 //     override
918 //     List!(GeoRadiusResponse) georadiusByMember(const(ubyte)[] key, const(ubyte)[] member, double radius,
919 //             GeoUnit unit) {
920 //         Redis j = getShard(key);
921 //         return j.georadiusByMember(key, member, radius, unit);
922 //     }
923 
924 //     override
925 //     List!(GeoRadiusResponse) georadiusByMemberReadonly(const(ubyte)[] key, const(ubyte)[] member, double radius,
926 //             GeoUnit unit) {
927 //         Redis j = getShard(key);
928 //         return j.georadiusByMemberReadonly(key, member, radius, unit);
929 //     }
930 
931 //     override
932 //     List!(GeoRadiusResponse) georadiusByMember(const(ubyte)[] key, const(ubyte)[] member, double radius,
933 //             GeoUnit unit, GeoRadiusParam param) {
934 //         Redis j = getShard(key);
935 //         return j.georadiusByMember(key, member, radius, unit, param);
936 //     }
937 
938 //     override
939 //     List!(GeoRadiusResponse) georadiusByMemberReadonly(const(ubyte)[] key, const(ubyte)[] member, double radius,
940 //             GeoUnit unit, GeoRadiusParam param) {
941 //         Redis j = getShard(key);
942 //         return j.georadiusByMemberReadonly(key, member, radius, unit, param);
943 //     }
944 
945 //     override
946 //     ScanResult!(MapEntry!(const(ubyte)[], const(ubyte)[])) hscan(const(ubyte)[] key, const(ubyte)[] cursor) {
947 //         Redis j = getShard(key);
948 //         return j.hscan(key, cursor);
949 //     }
950 
951 //     override
952 //     ScanResult!(MapEntry!(const(ubyte)[], const(ubyte)[])) hscan(const(ubyte)[] key, const(ubyte)[] cursor, ScanParams params) {
953 //         Redis j = getShard(key);
954 //         return j.hscan(key, cursor, params);
955 //     }
956 
957 //     override
958 //     ScanResult!(const(ubyte)[]) sscan(const(ubyte)[] key, const(ubyte)[] cursor) {
959 //         Redis j = getShard(key);
960 //         return j.sscan(key, cursor);
961 //     }
962 
963 //     override
964 //     ScanResult!(const(ubyte)[]) sscan(const(ubyte)[] key, const(ubyte)[] cursor, ScanParams params) {
965 //         Redis j = getShard(key);
966 //         return j.sscan(key, cursor, params);
967 //     }
968 
969 //     override
970 //     ScanResult!(Tuple) zscan(const(ubyte)[] key, const(ubyte)[] cursor) {
971 //         Redis j = getShard(key);
972 //         return j.zscan(key, cursor);
973 //     }
974 
975 //     override
976 //     ScanResult!(Tuple) zscan(const(ubyte)[] key, const(ubyte)[] cursor, ScanParams params) {
977 //         Redis j = getShard(key);
978 //         return j.zscan(key, cursor, params);
979 //     }
980 
981 //     override
982 //     List!(long) bitfield(const(ubyte)[] key, const(ubyte)[][] arguments...) {
983 //         Redis j = getShard(key);
984 //         return j.bitfield(key, arguments);
985 //  }
986 
987 //     override
988 //     Long hstrlen(const(ubyte)[] key, const(ubyte)[] field) {
989 //         Redis j = getShard(key);
990 //         return j.hstrlen(key, field);
991 //     }
992 
993 //     override
994 //     const(ubyte)[] xadd(const(ubyte)[] key, const(ubyte)[] id, Map!(const(ubyte)[], const(ubyte)[]) hash, long maxLen, bool approximateLength) {
995 //         Redis j = getShard(key);
996 //         return j.xadd(key, id, hash, maxLen, approximateLength);
997 //     }
998 
999 //     override
1000 //     Long xlen(const(ubyte)[] key) {
1001 //         Redis j = getShard(key);
1002 //         return j.xlen(key);
1003 //     }
1004 
1005 //     override
1006 //     List!(const(ubyte)[]) xrange(const(ubyte)[] key, const(ubyte)[] start, const(ubyte)[] end, long count) {
1007 //         Redis j = getShard(key);
1008 //         return j.xrange(key, start, end, count);
1009 //     }
1010 
1011 //     override
1012 //     List!(const(ubyte)[]) xrevrange(const(ubyte)[] key, const(ubyte)[] end, const(ubyte)[] start, int count) {
1013 //         Redis j = getShard(key);
1014 //         return j.xrevrange(key, end, start, count);
1015 //     }
1016 
1017 //     override
1018 //     Long xack(const(ubyte)[] key, const(ubyte)[] group, const(ubyte)[][] ids...) {
1019 //         Redis j = getShard(key);
1020 //         return j.xack(key, group, ids);
1021 //     }
1022 
1023 //     override
1024 //     string xgroupCreate(const(ubyte)[] key, const(ubyte)[] consumer, const(ubyte)[] id, bool makeStream) {
1025 //         Redis j = getShard(key);
1026 //         return j.xgroupCreate(key, consumer, id, makeStream);
1027 //     }
1028 
1029 //     override
1030 //     string xgroupSetID(const(ubyte)[] key, const(ubyte)[] consumer, const(ubyte)[] id) {
1031 //         Redis j = getShard(key);
1032 //         return j.xgroupSetID(key, consumer, id);
1033 //     }
1034 
1035 //     override
1036 //     Long xgroupDestroy(const(ubyte)[] key, const(ubyte)[] consumer) {
1037 //         Redis j = getShard(key);
1038 //         return j.xgroupDestroy(key, consumer);
1039 //     }
1040 
1041 //     override
1042 //     string xgroupDelConsumer(const(ubyte)[] key, const(ubyte)[] consumer, const(ubyte)[] consumerName) {
1043 //         Redis j = getShard(key);
1044 //         return j.xgroupDelConsumer(key, consumer, consumerName);
1045 //     }
1046 
1047 //     override
1048 //     Long xdel(const(ubyte)[] key, const(ubyte)[][] ids...) {
1049 //         Redis j = getShard(key);
1050 //         return j.xdel(key, ids);
1051 //     }
1052 
1053 //     override
1054 //     Long xtrim(const(ubyte)[] key, long maxLen, bool approximateLength) {
1055 //         Redis j = getShard(key);
1056 //         return j.xtrim(key, maxLen, approximateLength);
1057 //     }
1058 
1059 //     override
1060 //     List!(const(ubyte)[]) xpending(const(ubyte)[] key, const(ubyte)[] groupname, const(ubyte)[] start, const(ubyte)[] end, int count, const(ubyte)[] consumername) {
1061 //         Redis j = getShard(key);
1062 //         return j.xpending(key, groupname, start, end, count, consumername);
1063 //     }
1064 
1065 //     override
1066 //     List!(const(ubyte)[]) xclaim(const(ubyte)[] key, const(ubyte)[] groupname, const(ubyte)[] consumername, long minIdleTime, long newIdleTime,
1067 //             int retries, bool force, const(ubyte)[][] ids) {
1068 //         Redis j = getShard(key);
1069 //         return j.xclaim(key, groupname, consumername, minIdleTime, newIdleTime, retries, force, ids);
1070 //     }
1071 
1072 //     override
1073 //     Object sendCommand(ProtocolCommand cmd, const(ubyte)[][] args...) {
1074 //         // default since no sample key provided in RedisCommands interface
1075 //         const(ubyte)[] sampleKey = args.length > 0 ? args[0] : cast(const(ubyte)[])(cmd.to!string());
1076 //         Redis j = getShard(args[0]);
1077 //         return j.sendCommand(cmd, args);
1078 //     }
1079 
1080 }