]> git.saurik.com Git - redis.git/commitdiff
merged memory reduction patch
authorPieter Noordhuis <pcnoordhuis@gmail.com>
Thu, 4 Mar 2010 15:35:57 +0000 (16:35 +0100)
committerPieter Noordhuis <pcnoordhuis@gmail.com>
Thu, 4 Mar 2010 15:35:57 +0000 (16:35 +0100)
1  2 
redis.c

diff --cc redis.c
index bff1cdfc548adf64050f4540822b548fcabc23c2,0353940e2914d10510180f388ebfd5d5c903bd09..4f7d3efcd0e2e57627c97e65bf5d983e0c449371
+++ b/redis.c
@@@ -4909,7 -4864,11 +4910,7 @@@ static void zslInsert(zskiplist *zsl, d
              (x->forward[i]->score < score ||
                  (x->forward[i]->score == score &&
                  compareStringObjects(x->forward[i]->obj,obj) < 0))) {
-             span[i] += x->span[i];
 -            if (i > 0) {
 -                rank[i] += x->span[i-1];
 -            } else {
 -                rank[i]++;
 -            }
++            rank[i] += i > 0 ? x->span[i-1] : 1;
              x = x->forward[i];
          }
          update[i] = x;
@@@ -5054,53 -5023,6 +5065,53 @@@ static zskiplistNode *zslFirstWithScore
      return x->forward[0];
  }
  
-             rank += x->span[i];
 +/* Find the rank for an element by both score and key.
 + * Returns 0 when the element cannot be found, rank otherwise.
 + * Note that the rank is 1-based due to the span of zsl->header to the
 + * first element. */
 +static unsigned long zslGetRank(zskiplist *zsl, double score, robj *o) {
 +    zskiplistNode *x;
 +    unsigned long rank = 0;
 +    int i;
 +
 +    x = zsl->header;
 +    for (i = zsl->level-1; i >= 0; i--) {
 +        while (x->forward[i] &&
 +            (x->forward[i]->score < score ||
 +                (x->forward[i]->score == score &&
 +                compareStringObjects(x->forward[i]->obj,o) <= 0))) {
-         while (x->forward[i] && (traversed + x->span[i]) <= rank) {
-             traversed += x->span[i];
++            rank += i > 0 ? x->span[i-1] : 1;
 +            x = x->forward[i];
 +        }
 +
 +        /* x might be equal to zsl->header, so test if obj is non-NULL */
 +        if (x->obj && compareStringObjects(x->obj,o) == 0) {
 +            return rank;
 +        }
 +    }
 +    return 0;
 +}
 +
 +/* Finds an element by its rank. The rank argument needs to be 1-based. */
 +zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank) {
 +    zskiplistNode *x;
 +    unsigned long traversed = 0;
 +    int i;
 +
 +    x = zsl->header;
 +    for (i = zsl->level-1; i >= 0; i--) {
++        while (x->forward[i] && (traversed + (i > 0 ? x->span[i-1] : 1)) <= rank) {
++            traversed += i > 0 ? x->span[i-1] : 1;
 +            x = x->forward[i];
 +        }
 +
 +        if (traversed == rank) {
 +            return x;
 +        }
 +    }
 +    return NULL;
 +}
 +
  /* The actual Z-commands implementations */
  
  /* This generic command implements both ZADD and ZINCRBY.