mirror of
https://github.com/fluencelabs/redis
synced 2025-03-20 17:40:50 +00:00
update LRANGE to use basic iteration code to support dual encoding
This commit is contained in:
parent
697bd5673f
commit
a6dd455b09
89
redis.c
89
redis.c
@ -4836,6 +4836,77 @@ static unsigned long lLength(robj *subject) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Structure to hold set iteration abstraction. */
|
||||||
|
typedef struct {
|
||||||
|
robj *subject;
|
||||||
|
unsigned char encoding;
|
||||||
|
unsigned char *zi;
|
||||||
|
listNode *ln;
|
||||||
|
} lIterator;
|
||||||
|
|
||||||
|
/* Initialize an iterator at the specified index. */
|
||||||
|
static lIterator *lInitIterator(robj *subject, int index) {
|
||||||
|
lIterator *li = zmalloc(sizeof(lIterator));
|
||||||
|
li->subject = subject;
|
||||||
|
li->encoding = subject->encoding;
|
||||||
|
if (li->encoding == REDIS_ENCODING_ZIPLIST) {
|
||||||
|
li->zi = ziplistIndex(subject->ptr,index);
|
||||||
|
} else if (li->encoding == REDIS_ENCODING_LIST) {
|
||||||
|
li->ln = listIndex(subject->ptr,index);
|
||||||
|
} else {
|
||||||
|
redisPanic("Unknown list encoding");
|
||||||
|
}
|
||||||
|
return li;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up the iterator. */
|
||||||
|
static void lReleaseIterator(lIterator *li) {
|
||||||
|
zfree(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return entry or NULL at the current position of the iterator. */
|
||||||
|
static robj *lGet(lIterator *li) {
|
||||||
|
robj *value = NULL;
|
||||||
|
if (li->encoding == REDIS_ENCODING_ZIPLIST) {
|
||||||
|
char *v;
|
||||||
|
unsigned int vlen;
|
||||||
|
long long vval;
|
||||||
|
redisAssert(li->zi != NULL);
|
||||||
|
if (ziplistGet(li->zi,&v,&vlen,&vval)) {
|
||||||
|
if (v) {
|
||||||
|
value = createStringObject(v,vlen);
|
||||||
|
} else {
|
||||||
|
value = createStringObjectFromLongLong(vval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (li->encoding == REDIS_ENCODING_LIST) {
|
||||||
|
redisAssert(li->ln != NULL);
|
||||||
|
value = listNodeValue(li->ln);
|
||||||
|
incrRefCount(value);
|
||||||
|
} else {
|
||||||
|
redisPanic("Unknown list encoding");
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move to the next or previous entry in the list. */
|
||||||
|
static void lMove(lIterator *li, int where) {
|
||||||
|
if (li->encoding == REDIS_ENCODING_ZIPLIST) {
|
||||||
|
redisAssert(li->zi != NULL);
|
||||||
|
if (where == REDIS_HEAD)
|
||||||
|
li->zi = ziplistPrev(li->zi);
|
||||||
|
else
|
||||||
|
li->zi = ziplistNext(li->zi);
|
||||||
|
} else if (li->encoding == REDIS_ENCODING_LIST) {
|
||||||
|
redisAssert(li->ln != NULL);
|
||||||
|
if (where == REDIS_HEAD)
|
||||||
|
li->ln = li->ln->prev;
|
||||||
|
else
|
||||||
|
li->ln = li->ln->next;
|
||||||
|
} else {
|
||||||
|
redisPanic("Unknown list encoding");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void pushGenericCommand(redisClient *c, int where) {
|
static void pushGenericCommand(redisClient *c, int where) {
|
||||||
robj *lobj = lookupKeyWrite(c->db,c->argv[1]);
|
robj *lobj = lookupKeyWrite(c->db,c->argv[1]);
|
||||||
@ -4968,19 +5039,15 @@ static void rpopCommand(redisClient *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void lrangeCommand(redisClient *c) {
|
static void lrangeCommand(redisClient *c) {
|
||||||
robj *o;
|
robj *o, *value;
|
||||||
int start = atoi(c->argv[2]->ptr);
|
int start = atoi(c->argv[2]->ptr);
|
||||||
int end = atoi(c->argv[3]->ptr);
|
int end = atoi(c->argv[3]->ptr);
|
||||||
int llen;
|
int llen;
|
||||||
int rangelen, j;
|
int rangelen, j;
|
||||||
list *list;
|
|
||||||
listNode *ln;
|
|
||||||
robj *ele;
|
|
||||||
|
|
||||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymultibulk)) == NULL
|
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymultibulk)) == NULL
|
||||||
|| checkType(c,o,REDIS_LIST)) return;
|
|| checkType(c,o,REDIS_LIST)) return;
|
||||||
list = o->ptr;
|
llen = lLength(o);
|
||||||
llen = listLength(list);
|
|
||||||
|
|
||||||
/* convert negative indexes */
|
/* convert negative indexes */
|
||||||
if (start < 0) start = llen+start;
|
if (start < 0) start = llen+start;
|
||||||
@ -4998,13 +5065,15 @@ static void lrangeCommand(redisClient *c) {
|
|||||||
rangelen = (end-start)+1;
|
rangelen = (end-start)+1;
|
||||||
|
|
||||||
/* Return the result in form of a multi-bulk reply */
|
/* Return the result in form of a multi-bulk reply */
|
||||||
ln = listIndex(list, start);
|
|
||||||
addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",rangelen));
|
addReplySds(c,sdscatprintf(sdsempty(),"*%d\r\n",rangelen));
|
||||||
|
lIterator *li = lInitIterator(o,start);
|
||||||
for (j = 0; j < rangelen; j++) {
|
for (j = 0; j < rangelen; j++) {
|
||||||
ele = listNodeValue(ln);
|
value = lGet(li);
|
||||||
addReplyBulk(c,ele);
|
redisAssert(value != NULL);
|
||||||
ln = ln->next;
|
addReplyBulk(c,value);
|
||||||
|
lMove(li,REDIS_TAIL);
|
||||||
}
|
}
|
||||||
|
lReleaseIterator(li);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ltrimCommand(redisClient *c) {
|
static void ltrimCommand(redisClient *c) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user