inline support for dual encoding in the LINDEX and LSET commands

This commit is contained in:
Pieter Noordhuis 2010-05-30 02:11:59 +02:00
parent d72562f7ba
commit 697bd5673f

82
redis.c
View File

@ -4878,45 +4878,69 @@ static void llenCommand(redisClient *c) {
} }
static void lindexCommand(redisClient *c) { static void lindexCommand(redisClient *c) {
robj *o; robj *o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk);
if (o == NULL || checkType(c,o,REDIS_LIST)) return;
int index = atoi(c->argv[2]->ptr); int index = atoi(c->argv[2]->ptr);
list *list;
listNode *ln;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL || if (o->encoding == REDIS_ENCODING_ZIPLIST) {
checkType(c,o,REDIS_LIST)) return; unsigned char *p;
list = o->ptr; char *v;
unsigned int vlen;
ln = listIndex(list, index); long long vval;
if (ln == NULL) { p = ziplistIndex(o->ptr,index);
addReply(c,shared.nullbulk); if (ziplistGet(p,&v,&vlen,&vval)) {
if (v) {
addReplySds(c,sdsnewlen(v,vlen));
} else {
addReplyLongLong(c,vval);
}
} else {
addReply(c,shared.nullbulk);
}
} else if (o->encoding == REDIS_ENCODING_LIST) {
listNode *ln = listIndex(o->ptr,index);
if (ln != NULL) {
addReply(c,(robj*)listNodeValue(ln));
} else {
addReply(c,shared.nullbulk);
}
} else { } else {
robj *ele = listNodeValue(ln); redisPanic("Unknown list encoding");
addReplyBulk(c,ele);
} }
} }
static void lsetCommand(redisClient *c) { static void lsetCommand(redisClient *c) {
robj *o; robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr);
if (o == NULL || checkType(c,o,REDIS_LIST)) return;
int index = atoi(c->argv[2]->ptr); int index = atoi(c->argv[2]->ptr);
list *list; robj *value = c->argv[3];
listNode *ln;
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr)) == NULL || if (o->encoding == REDIS_ENCODING_ZIPLIST) {
checkType(c,o,REDIS_LIST)) return; unsigned char *p, *zl = o->ptr;
list = o->ptr; p = ziplistIndex(zl,index);
if (p == NULL) {
ln = listIndex(list, index); addReply(c,shared.outofrangeerr);
if (ln == NULL) { } else {
addReply(c,shared.outofrangeerr); o->ptr = ziplistDelete(o->ptr,&p,ZIPLIST_TAIL);
value = getDecodedObject(value);
o->ptr = ziplistInsert(o->ptr,p,value->ptr,sdslen(value->ptr));
decrRefCount(value);
addReply(c,shared.ok);
server.dirty++;
}
} else if (o->encoding == REDIS_ENCODING_LIST) {
listNode *ln = listIndex(o->ptr,index);
if (ln == NULL) {
addReply(c,shared.outofrangeerr);
} else {
decrRefCount((robj*)listNodeValue(ln));
listNodeValue(ln) = value;
incrRefCount(value);
addReply(c,shared.ok);
server.dirty++;
}
} else { } else {
robj *ele = listNodeValue(ln); redisPanic("Unknown list encoding");
decrRefCount(ele);
listNodeValue(ln) = c->argv[3];
incrRefCount(c->argv[3]);
addReply(c,shared.ok);
server.dirty++;
} }
} }