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

Function RM_ZsetRangePrev

src/module.cpp:3073–3132  ·  view source on GitHub ↗

Go to the previous element of the sorted set iterator. Returns 1 if there was * a previous element, 0 if we are already at the first element or the range * does not include any item at all. */

Source from the content-addressed store, hash-verified

3071 * a previous element, 0 if we are already at the first element or the range
3072 * does not include any item at all. */
3073int RM_ZsetRangePrev(RedisModuleKey *key) {
3074 if (!key->value || key->value->type != OBJ_ZSET) return 0;
3075 if (!key->u.zset.type || !key->u.zset.current) return 0; /* No active iterator. */
3076
3077 if (key->value->encoding == OBJ_ENCODING_ZIPLIST) {
3078 unsigned char *zl = (unsigned char*)ptrFromObj(key->value);
3079 unsigned char *eptr = (unsigned char*)key->u.zset.current;
3080 unsigned char *prev;
3081 prev = ziplistPrev(zl,eptr); /* Go back to previous score. */
3082 if (prev) prev = ziplistPrev(zl,prev); /* Back to previous ele. */
3083 if (prev == NULL) {
3084 key->u.zset.er = 1;
3085 return 0;
3086 } else {
3087 /* Are we still within the range? */
3088 if (key->u.zset.type == REDISMODULE_ZSET_RANGE_SCORE) {
3089 /* Fetch the previous element score for the
3090 * range check. */
3091 unsigned char *saved_prev = prev;
3092 prev = ziplistNext(zl,prev); /* Skip element to get the score.*/
3093 double score = zzlGetScore(prev); /* Obtain the prev score. */
3094 if (!zslValueGteMin(score,&key->u.zset.rs)) {
3095 key->u.zset.er = 1;
3096 return 0;
3097 }
3098 prev = saved_prev;
3099 } else if (key->u.zset.type == REDISMODULE_ZSET_RANGE_LEX) {
3100 if (!zzlLexValueGteMin(prev,&key->u.zset.lrs)) {
3101 key->u.zset.er = 1;
3102 return 0;
3103 }
3104 }
3105 key->u.zset.current = prev;
3106 return 1;
3107 }
3108 } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) {
3109 zskiplistNode *ln = (zskiplistNode*)key->u.zset.current, *prev = ln->backward;
3110 if (prev == NULL) {
3111 key->u.zset.er = 1;
3112 return 0;
3113 } else {
3114 /* Are we still within the range? */
3115 if (key->u.zset.type == REDISMODULE_ZSET_RANGE_SCORE &&
3116 !zslValueGteMin(prev->score,&key->u.zset.rs))
3117 {
3118 key->u.zset.er = 1;
3119 return 0;
3120 } else if (key->u.zset.type == REDISMODULE_ZSET_RANGE_LEX) {
3121 if (!zslLexValueGteMin(prev->ele,&key->u.zset.lrs)) {
3122 key->u.zset.er = 1;
3123 return 0;
3124 }
3125 }
3126 key->u.zset.current = prev;
3127 return 1;
3128 }
3129 } else {
3130 serverPanic("Unsupported zset encoding");

Callers

nothing calls this directly

Calls 7

ptrFromObjFunction · 0.85
ziplistPrevFunction · 0.85
ziplistNextFunction · 0.85
zzlGetScoreFunction · 0.85
zslValueGteMinFunction · 0.85
zzlLexValueGteMinFunction · 0.85
zslLexValueGteMinFunction · 0.85

Tested by

no test coverage detected