mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
LRANGE converted into a COW friendly command. Some refactoring, comment, and new addReply*() family function added in the process.
This commit is contained in:
parent
bbac56c2f8
commit
d51ebef509
@ -178,6 +178,9 @@ void addReply(redisClient *c, robj *obj) {
|
||||
if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK)
|
||||
_addReplyObjectToList(c,obj);
|
||||
} else {
|
||||
/* FIXME: convert the long into string and use _addReplyToBuffer()
|
||||
* instead of calling getDecodedObject. As this place in the
|
||||
* code is too performance critical. */
|
||||
obj = getDecodedObject(obj);
|
||||
if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK)
|
||||
_addReplyObjectToList(c,obj);
|
||||
@ -275,6 +278,7 @@ void setDeferredMultiBulkLength(redisClient *c, void *node, long length) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a duble as a bulk reply */
|
||||
void addReplyDouble(redisClient *c, double d) {
|
||||
char dbuf[128], sbuf[128];
|
||||
int dlen, slen;
|
||||
@ -283,6 +287,8 @@ void addReplyDouble(redisClient *c, double d) {
|
||||
addReplyString(c,sbuf,slen);
|
||||
}
|
||||
|
||||
/* Add a long long as integer reply or bulk len / multi bulk count.
|
||||
* Basically this is used to output <prefix><long long><crlf>. */
|
||||
void _addReplyLongLong(redisClient *c, long long ll, char prefix) {
|
||||
char buf[128];
|
||||
int len;
|
||||
@ -301,6 +307,7 @@ void addReplyMultiBulkLen(redisClient *c, long length) {
|
||||
_addReplyLongLong(c,length,'*');
|
||||
}
|
||||
|
||||
/* Create the length prefix of a bulk reply, example: $2234 */
|
||||
void addReplyBulkLen(redisClient *c, robj *obj) {
|
||||
size_t len;
|
||||
|
||||
@ -322,23 +329,38 @@ void addReplyBulkLen(redisClient *c, robj *obj) {
|
||||
_addReplyLongLong(c,len,'$');
|
||||
}
|
||||
|
||||
/* Add a Redis Object as a bulk reply */
|
||||
void addReplyBulk(redisClient *c, robj *obj) {
|
||||
addReplyBulkLen(c,obj);
|
||||
addReply(c,obj);
|
||||
addReply(c,shared.crlf);
|
||||
}
|
||||
|
||||
/* In the CONFIG command we need to add vanilla C string as bulk replies */
|
||||
/* Add a C buffer as bulk reply */
|
||||
void addReplyBulkCBuffer(redisClient *c, void *p, size_t len) {
|
||||
_addReplyLongLong(c,len,'$');
|
||||
addReplyString(c,p,len);
|
||||
addReply(c,shared.crlf);
|
||||
}
|
||||
|
||||
/* Add a C nul term string as bulk reply */
|
||||
void addReplyBulkCString(redisClient *c, char *s) {
|
||||
if (s == NULL) {
|
||||
addReply(c,shared.nullbulk);
|
||||
} else {
|
||||
robj *o = createStringObject(s,strlen(s));
|
||||
addReplyBulk(c,o);
|
||||
decrRefCount(o);
|
||||
addReplyBulkCBuffer(c,s,strlen(s));
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a long long as a bulk reply */
|
||||
void addReplyBulkLongLong(redisClient *c, long long ll) {
|
||||
char buf[64];
|
||||
int len;
|
||||
|
||||
len = ll2string(buf,64,ll);
|
||||
addReplyBulkCBuffer(c,buf,len);
|
||||
}
|
||||
|
||||
static void acceptCommonHandler(int fd) {
|
||||
redisClient *c;
|
||||
if ((c = createClient(fd)) == NULL) {
|
||||
|
@ -639,6 +639,8 @@ void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void addReplyBulk(redisClient *c, robj *obj);
|
||||
void addReplyBulkCString(redisClient *c, char *s);
|
||||
void addReplyBulkCBuffer(redisClient *c, void *p, size_t len);
|
||||
void addReplyBulkLongLong(redisClient *c, long long ll);
|
||||
void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void addReply(redisClient *c, robj *obj);
|
||||
void addReplySds(redisClient *c, sds s);
|
||||
|
36
src/t_list.c
36
src/t_list.c
@ -472,12 +472,11 @@ void rpopCommand(redisClient *c) {
|
||||
}
|
||||
|
||||
void lrangeCommand(redisClient *c) {
|
||||
robj *o, *value;
|
||||
robj *o;
|
||||
int start = atoi(c->argv[2]->ptr);
|
||||
int end = atoi(c->argv[3]->ptr);
|
||||
int llen;
|
||||
int rangelen, j;
|
||||
listTypeEntry entry;
|
||||
int rangelen;
|
||||
|
||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymultibulk)) == NULL
|
||||
|| checkType(c,o,REDIS_LIST)) return;
|
||||
@ -499,14 +498,31 @@ void lrangeCommand(redisClient *c) {
|
||||
|
||||
/* Return the result in form of a multi-bulk reply */
|
||||
addReplyMultiBulkLen(c,rangelen);
|
||||
listTypeIterator *li = listTypeInitIterator(o,start,REDIS_TAIL);
|
||||
for (j = 0; j < rangelen; j++) {
|
||||
redisAssert(listTypeNext(li,&entry));
|
||||
value = listTypeGet(&entry);
|
||||
addReplyBulk(c,value);
|
||||
decrRefCount(value);
|
||||
if (o->encoding == REDIS_ENCODING_ZIPLIST) {
|
||||
unsigned char *p = ziplistIndex(o->ptr,start);
|
||||
unsigned char *vstr;
|
||||
unsigned int vlen;
|
||||
long long vlong;
|
||||
|
||||
while(rangelen--) {
|
||||
ziplistGet(p,&vstr,&vlen,&vlong);
|
||||
if (vstr) {
|
||||
addReplyBulkCBuffer(c,vstr,vlen);
|
||||
} else {
|
||||
addReplyBulkLongLong(c,vlong);
|
||||
}
|
||||
p = ziplistNext(o->ptr,p);
|
||||
}
|
||||
} else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
|
||||
listNode *ln = listIndex(o->ptr,start);
|
||||
|
||||
while(rangelen--) {
|
||||
addReplyBulk(c,ln->value);
|
||||
ln = ln->next;
|
||||
}
|
||||
} else {
|
||||
redisPanic("List encoding is not LINKEDLIST nor ZIPLIST!");
|
||||
}
|
||||
listTypeReleaseIterator(li);
|
||||
}
|
||||
|
||||
void ltrimCommand(redisClient *c) {
|
||||
|
@ -595,7 +595,12 @@ unsigned char *ziplistIndex(unsigned char *zl, int index) {
|
||||
return (p[0] == ZIP_END || index > 0) ? NULL : p;
|
||||
}
|
||||
|
||||
/* Return pointer to next entry in ziplist. */
|
||||
/* Return pointer to next entry in ziplist.
|
||||
*
|
||||
* zl is the pointer to the ziplist
|
||||
* p is the pointer to the current element
|
||||
*
|
||||
* The element after 'p' is returned, otherwise NULL if we are at the end. */
|
||||
unsigned char *ziplistNext(unsigned char *zl, unsigned char *p) {
|
||||
((void) zl);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user