/* This skiplist implementation is almost a C translation of the original
* algorithm described by William Pugh in "Skip Lists: A Probabilistic
* Alternative to Balanced Trees", modified in three ways:
- * a) this implementation allows for repeated values.
+ * a) this implementation allows for repeated scores.
* b) the comparison is not just by key (our 'score') but by satellite data.
* c) there is a back pointer, so it's a doubly linked list with the back
* pointers being only at "level 1". This allows to traverse the list
zfree(zsl);
}
+/* Returns a random level for the new skiplist node we are going to create.
+ * The return value of this function is between 1 and ZSKIPLIST_MAXLEVEL
+ * (both inclusive), with a powerlaw-alike distribution where higher
+ * levels are less likely to be returned. */
int zslRandomLevel(void) {
int level = 1;
while ((random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
return 0;
p = ziplistIndex(zl,-1); /* Last score. */
- redisAssert(p != NULL);
+ if (p == NULL) return 0; /* Empty sorted set */
score = zzlGetScore(p);
if (!zslValueGteMin(score,range))
return 0;
if (val->flags & OPVAL_DIRTY_ROBJ)
decrRefCount(val->ele);
- bzero(val,sizeof(zsetopval));
+ memset(val,0,sizeof(zsetopval));
if (op->type == REDIS_SET) {
iterset *it = &op->iter.set;
if (op->encoding == REDIS_ENCODING_INTSET) {
- if (!intsetGet(it->is.is,it->is.ii,(int64_t*)&val->ell))
+ int64_t ell = val->ell;
+
+ if (!intsetGet(it->is.is,it->is.ii,&ell))
return 0;
val->score = 1.0;
double score, value;
score = src[0].weight * zval.score;
+ if (isnan(score)) score = 0;
+
for (j = 1; j < setnum; j++) {
/* It is not safe to access the zset we are
* iterating, so explicitly check for equal object. */
/* Initialize score */
score = src[i].weight * zval.score;
+ if (isnan(score)) score = 0;
/* Because the inputs are sorted by size, it's only possible
* for sets at larger indices to hold this element. */