"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/t_zset.c" between
redis-6.2-rc3.tar.gz and redis-6.2.0.tar.gz

About: redis is an advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.

t_zset.c  (redis-6.2-rc3):t_zset.c  (redis-6.2.0)
skipping to change at line 3955 skipping to change at line 3955
// BZPOPMIN key [key ...] timeout // BZPOPMIN key [key ...] timeout
void bzpopminCommand(client *c) { void bzpopminCommand(client *c) {
blockingGenericZpopCommand(c,ZSET_MIN); blockingGenericZpopCommand(c,ZSET_MIN);
} }
// BZPOPMAX key [key ...] timeout // BZPOPMAX key [key ...] timeout
void bzpopmaxCommand(client *c) { void bzpopmaxCommand(client *c) {
blockingGenericZpopCommand(c,ZSET_MAX); blockingGenericZpopCommand(c,ZSET_MAX);
} }
static void zarndmemberReplyWithZiplist(client *c, unsigned int count, ziplistEn
try *keys, ziplistEntry *vals) {
for (unsigned long i = 0; i < count; i++) {
if (vals && c->resp > 2)
addReplyArrayLen(c,2);
if (keys[i].sval)
addReplyBulkCBuffer(c, keys[i].sval, keys[i].slen);
else
addReplyBulkLongLong(c, keys[i].lval);
if (vals) {
if (vals[i].sval) {
addReplyDouble(c, zzlStrtod(vals[i].sval,vals[i].slen));
} else
addReplyDouble(c, vals[i].lval);
}
}
}
/* How many times bigger should be the zset compared to the requested size /* How many times bigger should be the zset compared to the requested size
* for us to not use the "remove elements" strategy? Read later in the * for us to not use the "remove elements" strategy? Read later in the
* implementation for more info. */ * implementation for more info. */
#define ZRANDMEMBER_SUB_STRATEGY_MUL 3 #define ZRANDMEMBER_SUB_STRATEGY_MUL 3
/* If client is trying to ask for a very large number of random elements,
* queuing may consume an unlimited amount of memory, so we want to limit
* the number of randoms per time. */
#define ZRANDMEMBER_RANDOM_SAMPLE_LIMIT 1000
void zrandmemberWithCountCommand(client *c, long l, int withscores) { void zrandmemberWithCountCommand(client *c, long l, int withscores) {
unsigned long count, size; unsigned long count, size;
int uniq = 1; int uniq = 1;
robj *zsetobj; robj *zsetobj;
if ((zsetobj = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp])) if ((zsetobj = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp]))
== NULL || checkType(c, zsetobj, OBJ_ZSET)) return; == NULL || checkType(c, zsetobj, OBJ_ZSET)) return;
size = zsetLength(zsetobj); size = zsetLength(zsetobj);
if(l >= 0) { if(l >= 0) {
skipping to change at line 4005 skipping to change at line 4027
dictEntry *de = dictGetFairRandomKey(zs->dict); dictEntry *de = dictGetFairRandomKey(zs->dict);
sds key = dictGetKey(de); sds key = dictGetKey(de);
if (withscores && c->resp > 2) if (withscores && c->resp > 2)
addReplyArrayLen(c,2); addReplyArrayLen(c,2);
addReplyBulkCBuffer(c, key, sdslen(key)); addReplyBulkCBuffer(c, key, sdslen(key));
if (withscores) if (withscores)
addReplyDouble(c, dictGetDoubleVal(de)); addReplyDouble(c, dictGetDoubleVal(de));
} }
} else if (zsetobj->encoding == OBJ_ENCODING_ZIPLIST) { } else if (zsetobj->encoding == OBJ_ENCODING_ZIPLIST) {
ziplistEntry *keys, *vals = NULL; ziplistEntry *keys, *vals = NULL;
keys = zmalloc(sizeof(ziplistEntry)*count); unsigned long limit, sample_count;
limit = count > ZRANDMEMBER_RANDOM_SAMPLE_LIMIT ? ZRANDMEMBER_RANDOM
_SAMPLE_LIMIT : count;
keys = zmalloc(sizeof(ziplistEntry)*limit);
if (withscores) if (withscores)
vals = zmalloc(sizeof(ziplistEntry)*count); vals = zmalloc(sizeof(ziplistEntry)*limit);
ziplistRandomPairs(zsetobj->ptr, count, keys, vals); while (count) {
for (unsigned long i = 0; i < count; i++) { sample_count = count > limit ? limit : count;
if (withscores && c->resp > 2) count -= sample_count;
addReplyArrayLen(c,2); ziplistRandomPairs(zsetobj->ptr, sample_count, keys, vals);
if (keys[i].sval) zarndmemberReplyWithZiplist(c, sample_count, keys, vals);
addReplyBulkCBuffer(c, keys[i].sval, keys[i].slen);
else
addReplyBulkLongLong(c, keys[i].lval);
if (withscores) {
if (vals[i].sval) {
addReplyDouble(c, zzlStrtod(vals[i].sval,vals[i].slen));
} else
addReplyDouble(c, vals[i].lval);
}
} }
zfree(keys); zfree(keys);
zfree(vals); zfree(vals);
} }
return; return;
} }
zsetopsrc src; zsetopsrc src;
zsetopval zval; zsetopval zval;
src.subject = zsetobj; src.subject = zsetobj;
skipping to change at line 4069 skipping to change at line 4084
* The number of elements inside the zset is not greater than * The number of elements inside the zset is not greater than
* ZRANDMEMBER_SUB_STRATEGY_MUL times the number of requested elements. * ZRANDMEMBER_SUB_STRATEGY_MUL times the number of requested elements.
* In this case we create a dict from scratch with all the elements, and * In this case we create a dict from scratch with all the elements, and
* subtract random elements to reach the requested number of elements. * subtract random elements to reach the requested number of elements.
* *
* This is done because if the number of requested elements is just * This is done because if the number of requested elements is just
* a bit less than the number of elements in the set, the natural approach * a bit less than the number of elements in the set, the natural approach
* used into CASE 4 is highly inefficient. */ * used into CASE 4 is highly inefficient. */
if (count*ZRANDMEMBER_SUB_STRATEGY_MUL > size) { if (count*ZRANDMEMBER_SUB_STRATEGY_MUL > size) {
dict *d = dictCreate(&sdsReplyDictType, NULL); dict *d = dictCreate(&sdsReplyDictType, NULL);
dictExpand(d, size);
/* Add all the elements into the temporary dictionary. */ /* Add all the elements into the temporary dictionary. */
while (zuiNext(&src, &zval)) { while (zuiNext(&src, &zval)) {
sds key = zuiNewSdsFromValue(&zval); sds key = zuiNewSdsFromValue(&zval);
dictEntry *de = dictAddRaw(d, key, NULL); dictEntry *de = dictAddRaw(d, key, NULL);
serverAssert(de); serverAssert(de);
if (withscores) if (withscores)
dictSetDoubleVal(de, zval.score); dictSetDoubleVal(de, zval.score);
} }
serverAssert(dictSize(d) == size); serverAssert(dictSize(d) == size);
skipping to change at line 4110 skipping to change at line 4126
dictReleaseIterator(di); dictReleaseIterator(di);
dictRelease(d); dictRelease(d);
} }
/* CASE 4: We have a big zset compared to the requested number of elements. /* CASE 4: We have a big zset compared to the requested number of elements.
* In this case we can simply get random elements from the zset and add * In this case we can simply get random elements from the zset and add
* to the temporary set, trying to eventually get enough unique elements * to the temporary set, trying to eventually get enough unique elements
* to reach the specified count. */ * to reach the specified count. */
else { else {
if (zsetobj->encoding == OBJ_ENCODING_ZIPLIST) {
/* it is inefficient to repeatedly pick one random element from a
* ziplist. so we use this instead: */
ziplistEntry *keys, *vals = NULL;
keys = zmalloc(sizeof(ziplistEntry)*count);
if (withscores)
vals = zmalloc(sizeof(ziplistEntry)*count);
serverAssert(ziplistRandomPairsUnique(zsetobj->ptr, count, keys, val
s) == count);
zarndmemberReplyWithZiplist(c, count, keys, vals);
zfree(keys);
zfree(vals);
return;
}
/* Hashtable encoding (generic implementation) */
unsigned long added = 0; unsigned long added = 0;
dict *d = dictCreate(&hashDictType, NULL); dict *d = dictCreate(&hashDictType, NULL);
dictExpand(d, count);
while (added < count) { while (added < count) {
ziplistEntry key; ziplistEntry key;
double score; double score;
zsetTypeRandomElement(zsetobj, size, &key, withscores ? &score: NULL ); zsetTypeRandomElement(zsetobj, size, &key, withscores ? &score: NULL );
/* Try to add the object to the dictionary. If it already exists /* Try to add the object to the dictionary. If it already exists
* free it, otherwise increment the number of objects we have * free it, otherwise increment the number of objects we have
* in the result dictionary. */ * in the result dictionary. */
sds skey = zsetSdsFromZiplistEntry(&key); sds skey = zsetSdsFromZiplistEntry(&key);
 End of changes. 7 change blocks. 
16 lines changed or deleted 51 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)