| 662 | #define SRANDMEMBER_SUB_STRATEGY_MUL 3 |
| 663 | |
| 664 | void srandmemberWithCountCommand(client *c) { |
| 665 | long l; |
| 666 | unsigned long count, size; |
| 667 | int uniq = 1; |
| 668 | robj_roptr set; |
| 669 | const char *ele; |
| 670 | int64_t llele = 0; |
| 671 | int encoding; |
| 672 | |
| 673 | dict *d; |
| 674 | |
| 675 | if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return; |
| 676 | if (l < -g_pserver->rand_total_threshold || l > g_pserver->rand_total_threshold) { |
| 677 | addReplyError(c,"value is out of range"); |
| 678 | return; |
| 679 | } |
| 680 | if (l >= 0) { |
| 681 | count = (unsigned long) l; |
| 682 | } else { |
| 683 | /* A negative count means: return the same elements multiple times |
| 684 | * (i.e. don't remove the extracted element after every extraction). */ |
| 685 | count = -l; |
| 686 | uniq = 0; |
| 687 | } |
| 688 | |
| 689 | if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.emptyarray)) |
| 690 | == nullptr || checkType(c,set,OBJ_SET)) return; |
| 691 | size = setTypeSize(set); |
| 692 | |
| 693 | /* If count is zero, serve it ASAP to avoid special cases later. */ |
| 694 | if (count == 0) { |
| 695 | addReply(c,shared.emptyarray); |
| 696 | return; |
| 697 | } |
| 698 | |
| 699 | /* CASE 1: The count was negative, so the extraction method is just: |
| 700 | * "return N random elements" sampling the whole set every time. |
| 701 | * This case is trivial and can be served without auxiliary data |
| 702 | * structures. This case is the only one that also needs to return the |
| 703 | * elements in random order. */ |
| 704 | if (!uniq || count == 1) { |
| 705 | addReplyArrayLen(c,count); |
| 706 | while(count--) { |
| 707 | encoding = setTypeRandomElement(set,&ele,&llele); |
| 708 | if (encoding == OBJ_ENCODING_INTSET) { |
| 709 | addReplyBulkLongLong(c,llele); |
| 710 | } else { |
| 711 | addReplyBulkCBuffer(c,ele,sdslen(ele)); |
| 712 | } |
| 713 | if (c->flags & CLIENT_CLOSE_ASAP) |
| 714 | break; |
| 715 | } |
| 716 | return; |
| 717 | } |
| 718 | |
| 719 | /* CASE 2: |
| 720 | * The number of requested elements is greater than the number of |
| 721 | * elements inside the set: simply return the whole set. */ |
no test coverage detected