mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-22 16:18:28 -05:00
Wrapper for adding unknown multi bulk length to reply list
This commit is contained in:
parent
834ef78e27
commit
b301c1fc2b
@ -332,13 +332,10 @@ badfmt: /* Bad format errors */
|
||||
|
||||
void configGetCommand(redisClient *c) {
|
||||
robj *o = getDecodedObject(c->argv[2]);
|
||||
robj *lenobj = createObject(REDIS_STRING,NULL);
|
||||
void *replylen = addDeferredMultiBulkLength(c);
|
||||
char *pattern = o->ptr;
|
||||
int matches = 0;
|
||||
|
||||
addReply(c,lenobj);
|
||||
decrRefCount(lenobj);
|
||||
|
||||
if (stringmatch(pattern,"dbfilename",0)) {
|
||||
addReplyBulkCString(c,"dbfilename");
|
||||
addReplyBulkCString(c,server.dbfilename);
|
||||
@ -410,7 +407,7 @@ void configGetCommand(redisClient *c) {
|
||||
matches++;
|
||||
}
|
||||
decrRefCount(o);
|
||||
lenobj->ptr = sdscatprintf(sdsempty(),"*%d\r\n",matches*2);
|
||||
setDeferredMultiBulkLength(c,replylen,matches*2);
|
||||
}
|
||||
|
||||
void configCommand(redisClient *c) {
|
||||
|
6
src/db.c
6
src/db.c
@ -223,11 +223,9 @@ void keysCommand(redisClient *c) {
|
||||
sds pattern = c->argv[1]->ptr;
|
||||
int plen = sdslen(pattern);
|
||||
unsigned long numkeys = 0;
|
||||
robj *lenobj = createObject(REDIS_STRING,NULL);
|
||||
void *replylen = addDeferredMultiBulkLength(c);
|
||||
|
||||
di = dictGetIterator(c->db->dict);
|
||||
addReply(c,lenobj);
|
||||
decrRefCount(lenobj);
|
||||
while((de = dictNext(di)) != NULL) {
|
||||
sds key = dictGetEntryKey(de);
|
||||
robj *keyobj;
|
||||
@ -243,7 +241,7 @@ void keysCommand(redisClient *c) {
|
||||
}
|
||||
}
|
||||
dictReleaseIterator(di);
|
||||
lenobj->ptr = sdscatprintf(sdsempty(),"*%lu\r\n",numkeys);
|
||||
setDeferredMultiBulkLength(c,replylen,numkeys);
|
||||
}
|
||||
|
||||
void dbsizeCommand(redisClient *c) {
|
||||
|
@ -145,6 +145,34 @@ void addReplyString(redisClient *c, char *s, size_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds an empty object to the reply list that will contain the multi bulk
|
||||
* length, which is not known when this function is called. */
|
||||
void *addDeferredMultiBulkLength(redisClient *c) {
|
||||
if (_ensureFileEvent(c) != REDIS_OK) return NULL;
|
||||
_addReplyObjectToList(c,createObject(REDIS_STRING,NULL));
|
||||
return listLast(c->reply);
|
||||
}
|
||||
|
||||
/* Populate the length object and try glueing it to the next chunk. */
|
||||
void setDeferredMultiBulkLength(redisClient *c, void *node, long length) {
|
||||
listNode *ln = (listNode*)node;
|
||||
robj *len, *next;
|
||||
|
||||
/* Abort when *node is NULL (see addDeferredMultiBulkLength). */
|
||||
if (node == NULL) return;
|
||||
|
||||
len = listNodeValue(ln);
|
||||
len->ptr = sdscatprintf(sdsempty(),"*%ld\r\n",length);
|
||||
if (ln->next != NULL) {
|
||||
next = listNodeValue(ln->next);
|
||||
/* Only glue when the next node is a reply chunk. */
|
||||
if (next->type == REDIS_REPLY_NODE) {
|
||||
len->ptr = sdscatlen(len->ptr,next->ptr,sdslen(next->ptr));
|
||||
listDelNode(c->reply,ln->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addReplyDouble(redisClient *c, double d) {
|
||||
char dbuf[128], sbuf[128];
|
||||
int dlen, slen;
|
||||
|
@ -603,6 +603,8 @@ void resetClient(redisClient *c);
|
||||
void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void sendReplyToClientWritev(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
void addReply(redisClient *c, robj *obj);
|
||||
void *addDeferredMultiBulkLength(redisClient *c);
|
||||
void setDeferredMultiBulkLength(redisClient *c, void *node, long length);
|
||||
void addReplySds(redisClient *c, sds s);
|
||||
void processInputBuffer(redisClient *c);
|
||||
void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||
|
11
src/t_hash.c
11
src/t_hash.c
@ -350,17 +350,15 @@ void hlenCommand(redisClient *c) {
|
||||
}
|
||||
|
||||
void genericHgetallCommand(redisClient *c, int flags) {
|
||||
robj *o, *lenobj, *obj;
|
||||
robj *o, *obj;
|
||||
unsigned long count = 0;
|
||||
hashTypeIterator *hi;
|
||||
void *replylen = NULL;
|
||||
|
||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymultibulk)) == NULL
|
||||
|| checkType(c,o,REDIS_HASH)) return;
|
||||
|
||||
lenobj = createObject(REDIS_STRING,NULL);
|
||||
addReply(c,lenobj);
|
||||
decrRefCount(lenobj);
|
||||
|
||||
replylen = addDeferredMultiBulkLength(c);
|
||||
hi = hashTypeInitIterator(o);
|
||||
while (hashTypeNext(hi) != REDIS_ERR) {
|
||||
if (flags & REDIS_HASH_KEY) {
|
||||
@ -377,8 +375,7 @@ void genericHgetallCommand(redisClient *c, int flags) {
|
||||
}
|
||||
}
|
||||
hashTypeReleaseIterator(hi);
|
||||
|
||||
lenobj->ptr = sdscatprintf(sdsempty(),"*%lu\r\n",count);
|
||||
setDeferredMultiBulkLength(c,replylen,count);
|
||||
}
|
||||
|
||||
void hkeysCommand(redisClient *c) {
|
||||
|
@ -320,7 +320,8 @@ int qsortCompareSetsByCardinality(const void *s1, const void *s2) {
|
||||
void sinterGenericCommand(redisClient *c, robj **setkeys, unsigned long setnum, robj *dstkey) {
|
||||
robj **sets = zmalloc(sizeof(robj*)*setnum);
|
||||
setTypeIterator *si;
|
||||
robj *ele, *lenobj = NULL, *dstset = NULL;
|
||||
robj *ele, *dstset = NULL;
|
||||
void *replylen = NULL;
|
||||
unsigned long j, cardinality = 0;
|
||||
|
||||
for (j = 0; j < setnum; j++) {
|
||||
@ -356,9 +357,7 @@ void sinterGenericCommand(redisClient *c, robj **setkeys, unsigned long setnum,
|
||||
* to the output list and save the pointer to later modify it with the
|
||||
* right length */
|
||||
if (!dstkey) {
|
||||
lenobj = createObject(REDIS_STRING,NULL);
|
||||
addReply(c,lenobj);
|
||||
decrRefCount(lenobj);
|
||||
replylen = addDeferredMultiBulkLength(c);
|
||||
} else {
|
||||
/* If we have a target key where to store the resulting set
|
||||
* create this key with an empty set inside */
|
||||
@ -400,7 +399,7 @@ void sinterGenericCommand(redisClient *c, robj **setkeys, unsigned long setnum,
|
||||
touchWatchedKey(c->db,dstkey);
|
||||
server.dirty++;
|
||||
} else {
|
||||
lenobj->ptr = sdscatprintf(sdsempty(),"*%lu\r\n",cardinality);
|
||||
setDeferredMultiBulkLength(c,replylen,cardinality);
|
||||
}
|
||||
zfree(sets);
|
||||
}
|
||||
|
12
src/t_zset.c
12
src/t_zset.c
@ -866,7 +866,8 @@ void genericZrangebyscoreCommand(redisClient *c, int justcount) {
|
||||
zset *zsetobj = o->ptr;
|
||||
zskiplist *zsl = zsetobj->zsl;
|
||||
zskiplistNode *ln;
|
||||
robj *ele, *lenobj = NULL;
|
||||
robj *ele;
|
||||
void *replylen = NULL;
|
||||
unsigned long rangelen = 0;
|
||||
|
||||
/* Get the first node with the score >= min, or with
|
||||
@ -884,11 +885,8 @@ void genericZrangebyscoreCommand(redisClient *c, int justcount) {
|
||||
* are in the list, so we push this object that will represent
|
||||
* the multi-bulk length in the output buffer, and will "fix"
|
||||
* it later */
|
||||
if (!justcount) {
|
||||
lenobj = createObject(REDIS_STRING,NULL);
|
||||
addReply(c,lenobj);
|
||||
decrRefCount(lenobj);
|
||||
}
|
||||
if (!justcount)
|
||||
replylen = addDeferredMultiBulkLength(c);
|
||||
|
||||
while(ln && (maxex ? (ln->score < max) : (ln->score <= max))) {
|
||||
if (offset) {
|
||||
@ -910,7 +908,7 @@ void genericZrangebyscoreCommand(redisClient *c, int justcount) {
|
||||
if (justcount) {
|
||||
addReplyLongLong(c,(long)rangelen);
|
||||
} else {
|
||||
lenobj->ptr = sdscatprintf(sdsempty(),"*%lu\r\n",
|
||||
setDeferredMultiBulkLength(c,replylen,
|
||||
withscores ? (rangelen*2) : rangelen);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user