MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / hrandfieldWithCountCommand

Function hrandfieldWithCountCommand

src/t_hash.cpp:1026–1222  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1024#define HRANDFIELD_RANDOM_SAMPLE_LIMIT 1000
1025
1026void hrandfieldWithCountCommand(client *c, long l, int withvalues) {
1027 unsigned long count, size;
1028 int uniq = 1;
1029 robj_roptr hash;
1030
1031 if ((hash = lookupKeyReadOrReply(c,c->argv[1],shared.emptyarray))
1032 == nullptr || checkType(c,hash,OBJ_HASH)) return;
1033 size = hashTypeLength(hash);
1034
1035 if(l >= 0) {
1036 count = (unsigned long) l;
1037 } else {
1038 count = -l;
1039 uniq = 0;
1040 }
1041
1042 /* If count is zero, serve it ASAP to avoid special cases later. */
1043 if (count == 0) {
1044 addReply(c,shared.emptyarray);
1045 return;
1046 }
1047
1048 /* CASE 1: The count was negative, so the extraction method is just:
1049 * "return N random elements" sampling the whole set every time.
1050 * This case is trivial and can be served without auxiliary data
1051 * structures. This case is the only one that also needs to return the
1052 * elements in random order. */
1053 if (!uniq || count == 1) {
1054 if (withvalues && c->resp == 2)
1055 addReplyArrayLen(c, count*2);
1056 else
1057 addReplyArrayLen(c, count);
1058 if (hash->encoding == OBJ_ENCODING_HT) {
1059 sds key, value;
1060 while (count--) {
1061 dictEntry *de = dictGetFairRandomKey((dict*)ptrFromObj(hash));
1062 key = (sds)dictGetKey(de);
1063 value = (sds)dictGetVal(de);
1064 if (withvalues && c->resp > 2)
1065 addReplyArrayLen(c,2);
1066 addReplyBulkCBuffer(c, key, sdslen(key));
1067 if (withvalues)
1068 addReplyBulkCBuffer(c, value, sdslen(value));
1069 if (c->flags & CLIENT_CLOSE_ASAP)
1070 break;
1071 }
1072 } else if (hash->encoding == OBJ_ENCODING_ZIPLIST) {
1073 ziplistEntry *keys, *vals = NULL;
1074 unsigned long limit, sample_count;
1075 limit = count > HRANDFIELD_RANDOM_SAMPLE_LIMIT ? HRANDFIELD_RANDOM_SAMPLE_LIMIT : count;
1076 keys = (ziplistEntry*)zmalloc(sizeof(ziplistEntry)*limit);
1077 if (withvalues)
1078 vals = (ziplistEntry*)zmalloc(sizeof(ziplistEntry)*limit);
1079 while (count) {
1080 sample_count = count > limit ? limit : count;
1081 count -= sample_count;
1082 ziplistRandomPairs((unsigned char*)ptrFromObj(hash), sample_count, keys, vals);
1083 harndfieldReplyWithZiplist(c, sample_count, keys, vals);

Callers 1

hrandfieldCommandFunction · 0.85

Calls 15

lookupKeyReadOrReplyFunction · 0.85
checkTypeFunction · 0.85
hashTypeLengthFunction · 0.85
addReplyFunction · 0.85
addReplyArrayLenFunction · 0.85
dictGetFairRandomKeyFunction · 0.85
ptrFromObjFunction · 0.85
addReplyBulkCBufferFunction · 0.85
sdslenFunction · 0.85
zmallocFunction · 0.85
ziplistRandomPairsFunction · 0.85

Tested by

no test coverage detected