Skip to content

SkipList zslGetRank clearification #3081

@zhixinwen

Description

@zhixinwen

The code of *unsigned long zslGetRank(zskiplist *zsl, double score, robj *o) * can be found in t_zset.c

unsigned long zslGetRank(zskiplist *zsl, double score, sds ele) {
    zskiplistNode *x;
    unsigned long rank = 0;
    int i;
    x = zsl->header;
    for (i = zsl->level-1; i >= 0; i--) {
        while (x->level[i].forward &&
            (x->level[i].forward->score < score ||
                (x->level[i].forward->score == score &&
                sdscmp(x->level[i].forward->ele,ele) <= 0))) {
            rank += x->level[i].span;
            x = x->level[i].forward;
        }

    /* x might be equal to zsl->header, so test if obj is non-NULL */
    if (x->ele && sdscmp(x->ele,ele) == 0) {
        return rank;
    }
}
return 0;

}

It seems that the function will return rank even when there is no corresponding score in the SkipList.
x may stop at a point when x->level[i].forward->score > score and x -> score < score. if x->obj is equal to robj* o as well, then the rank is returned, even though the score does not match.

When Redis use this function, it is used with dict; therefore this may be why it does not cause a problem for now. But for robustness and consistency of API (it does return 0 for unfound objects), shouldn't we check the score as well?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions