Move a bunch of files to C++
Former-commit-id: 011948bcef748df33cb18e76dc5ba48d3c5706dc
This commit is contained in:
parent
ccd70014a7
commit
83a7f2f2bd
@ -128,7 +128,7 @@ void processUnblockedClients(int iel) {
|
|||||||
while (listLength(unblocked_clients)) {
|
while (listLength(unblocked_clients)) {
|
||||||
ln = listFirst(unblocked_clients);
|
ln = listFirst(unblocked_clients);
|
||||||
serverAssert(ln != NULL);
|
serverAssert(ln != NULL);
|
||||||
c = ln->value;
|
c = (client*)ln->value;
|
||||||
listDelNode(unblocked_clients,ln);
|
listDelNode(unblocked_clients,ln);
|
||||||
AssertCorrectThread(c);
|
AssertCorrectThread(c);
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ void disconnectAllBlockedClients(void) {
|
|||||||
|
|
||||||
listRewind(server.clients,&li);
|
listRewind(server.clients,&li);
|
||||||
while((ln = listNext(&li))) {
|
while((ln = listNext(&li))) {
|
||||||
client *c = listNodeValue(ln);
|
client *c = (client*)listNodeValue(ln);
|
||||||
|
|
||||||
fastlock_lock(&c->lock);
|
fastlock_lock(&c->lock);
|
||||||
if (c->flags & CLIENT_BLOCKED) {
|
if (c->flags & CLIENT_BLOCKED) {
|
||||||
@ -280,7 +280,7 @@ void handleClientsBlockedOnKeys(void) {
|
|||||||
|
|
||||||
while(listLength(l) != 0) {
|
while(listLength(l) != 0) {
|
||||||
listNode *ln = listFirst(l);
|
listNode *ln = listFirst(l);
|
||||||
readyList *rl = ln->value;
|
readyList *rl = (readyList*)ln->value;
|
||||||
|
|
||||||
/* First of all remove this key from db->ready_keys so that
|
/* First of all remove this key from db->ready_keys so that
|
||||||
* we can safely call signalKeyAsReady() against this key. */
|
* we can safely call signalKeyAsReady() against this key. */
|
||||||
@ -295,12 +295,12 @@ void handleClientsBlockedOnKeys(void) {
|
|||||||
* this key, from the first blocked to the last. */
|
* this key, from the first blocked to the last. */
|
||||||
de = dictFind(rl->db->blocking_keys,rl->key);
|
de = dictFind(rl->db->blocking_keys,rl->key);
|
||||||
if (de) {
|
if (de) {
|
||||||
list *clients = dictGetVal(de);
|
list *clients = (list*)dictGetVal(de);
|
||||||
int numclients = listLength(clients);
|
int numclients = listLength(clients);
|
||||||
|
|
||||||
while(numclients--) {
|
while(numclients--) {
|
||||||
listNode *clientnode = listFirst(clients);
|
listNode *clientnode = listFirst(clients);
|
||||||
client *receiver = clientnode->value;
|
client *receiver = (client*)clientnode->value;
|
||||||
|
|
||||||
if (receiver->btype != BLOCKED_LIST) {
|
if (receiver->btype != BLOCKED_LIST) {
|
||||||
/* Put at the tail, so that at the next call
|
/* Put at the tail, so that at the next call
|
||||||
@ -358,13 +358,13 @@ void handleClientsBlockedOnKeys(void) {
|
|||||||
* this key, from the first blocked to the last. */
|
* this key, from the first blocked to the last. */
|
||||||
de = dictFind(rl->db->blocking_keys,rl->key);
|
de = dictFind(rl->db->blocking_keys,rl->key);
|
||||||
if (de) {
|
if (de) {
|
||||||
list *clients = dictGetVal(de);
|
list *clients = (list*)dictGetVal(de);
|
||||||
int numclients = listLength(clients);
|
int numclients = listLength(clients);
|
||||||
unsigned long zcard = zsetLength(o);
|
unsigned long zcard = zsetLength(o);
|
||||||
|
|
||||||
while(numclients-- && zcard) {
|
while(numclients-- && zcard) {
|
||||||
listNode *clientnode = listFirst(clients);
|
listNode *clientnode = listFirst(clients);
|
||||||
client *receiver = clientnode->value;
|
client *receiver = (client*)clientnode->value;
|
||||||
|
|
||||||
if (receiver->btype != BLOCKED_ZSET) {
|
if (receiver->btype != BLOCKED_ZSET) {
|
||||||
/* Put at the tail, so that at the next call
|
/* Put at the tail, so that at the next call
|
||||||
@ -402,21 +402,21 @@ void handleClientsBlockedOnKeys(void) {
|
|||||||
/* Serve clients blocked on stream key. */
|
/* Serve clients blocked on stream key. */
|
||||||
else if (o != NULL && o->type == OBJ_STREAM) {
|
else if (o != NULL && o->type == OBJ_STREAM) {
|
||||||
dictEntry *de = dictFind(rl->db->blocking_keys,rl->key);
|
dictEntry *de = dictFind(rl->db->blocking_keys,rl->key);
|
||||||
stream *s = ptrFromObj(o);
|
stream *s = (stream*)ptrFromObj(o);
|
||||||
|
|
||||||
/* We need to provide the new data arrived on the stream
|
/* We need to provide the new data arrived on the stream
|
||||||
* to all the clients that are waiting for an offset smaller
|
* to all the clients that are waiting for an offset smaller
|
||||||
* than the current top item. */
|
* than the current top item. */
|
||||||
if (de) {
|
if (de) {
|
||||||
list *clients = dictGetVal(de);
|
list *clients = (list*)dictGetVal(de);
|
||||||
listNode *ln;
|
listNode *ln;
|
||||||
listIter li;
|
listIter li;
|
||||||
listRewind(clients,&li);
|
listRewind(clients,&li);
|
||||||
|
|
||||||
while((ln = listNext(&li))) {
|
while((ln = listNext(&li))) {
|
||||||
client *receiver = listNodeValue(ln);
|
client *receiver = (client*)listNodeValue(ln);
|
||||||
if (receiver->btype != BLOCKED_STREAM) continue;
|
if (receiver->btype != BLOCKED_STREAM) continue;
|
||||||
streamID *gt = dictFetchValue(receiver->bpop.keys,
|
streamID *gt = (streamID*)dictFetchValue(receiver->bpop.keys,
|
||||||
rl->key);
|
rl->key);
|
||||||
|
|
||||||
/* If we blocked in the context of a consumer
|
/* If we blocked in the context of a consumer
|
||||||
@ -431,7 +431,7 @@ void handleClientsBlockedOnKeys(void) {
|
|||||||
streamCG *group = NULL;
|
streamCG *group = NULL;
|
||||||
if (receiver->bpop.xread_group) {
|
if (receiver->bpop.xread_group) {
|
||||||
group = streamLookupCG(s,
|
group = streamLookupCG(s,
|
||||||
ptrFromObj(receiver->bpop.xread_group));
|
szFromObj(receiver->bpop.xread_group));
|
||||||
/* If the group was not found, send an error
|
/* If the group was not found, send an error
|
||||||
* to the consumer. */
|
* to the consumer. */
|
||||||
if (!group) {
|
if (!group) {
|
||||||
@ -457,7 +457,7 @@ void handleClientsBlockedOnKeys(void) {
|
|||||||
|
|
||||||
if (group) {
|
if (group) {
|
||||||
consumer = streamLookupConsumer(group,
|
consumer = streamLookupConsumer(group,
|
||||||
ptrFromObj(receiver->bpop.xread_consumer),
|
szFromObj(receiver->bpop.xread_consumer),
|
||||||
1);
|
1);
|
||||||
noack = receiver->bpop.xread_group_noack;
|
noack = receiver->bpop.xread_group_noack;
|
||||||
}
|
}
|
||||||
@ -568,7 +568,7 @@ void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeo
|
|||||||
incrRefCount(keys[j]);
|
incrRefCount(keys[j]);
|
||||||
serverAssertWithInfo(c,keys[j],retval == DICT_OK);
|
serverAssertWithInfo(c,keys[j],retval == DICT_OK);
|
||||||
} else {
|
} else {
|
||||||
l = dictGetVal(de);
|
l = (list*)dictGetVal(de);
|
||||||
}
|
}
|
||||||
listAddNodeTail(l,c);
|
listAddNodeTail(l,c);
|
||||||
}
|
}
|
||||||
@ -586,10 +586,10 @@ void unblockClientWaitingData(client *c) {
|
|||||||
di = dictGetIterator(c->bpop.keys);
|
di = dictGetIterator(c->bpop.keys);
|
||||||
/* The client may wait for multiple keys, so unblock it for every key. */
|
/* The client may wait for multiple keys, so unblock it for every key. */
|
||||||
while((de = dictNext(di)) != NULL) {
|
while((de = dictNext(di)) != NULL) {
|
||||||
robj *key = dictGetKey(de);
|
robj *key = (robj*)dictGetKey(de);
|
||||||
|
|
||||||
/* Remove this client from the list of clients waiting for this key. */
|
/* Remove this client from the list of clients waiting for this key. */
|
||||||
l = dictFetchValue(c->db->blocking_keys,key);
|
l = (list*)dictFetchValue(c->db->blocking_keys,key);
|
||||||
serverAssertWithInfo(c,key,l != NULL);
|
serverAssertWithInfo(c,key,l != NULL);
|
||||||
listDelNode(l,listSearchKey(l,c));
|
listDelNode(l,listSearchKey(l,c));
|
||||||
/* If the list is empty we need to remove it to avoid wasting memory */
|
/* If the list is empty we need to remove it to avoid wasting memory */
|
||||||
@ -629,7 +629,7 @@ void signalKeyAsReady(redisDb *db, robj *key) {
|
|||||||
if (dictFind(db->ready_keys,key) != NULL) return;
|
if (dictFind(db->ready_keys,key) != NULL) return;
|
||||||
|
|
||||||
/* Ok, we need to queue this key into server.ready_keys. */
|
/* Ok, we need to queue this key into server.ready_keys. */
|
||||||
rl = zmalloc(sizeof(*rl), MALLOC_SHARED);
|
rl = (readyList*)zmalloc(sizeof(*rl), MALLOC_SHARED);
|
||||||
rl->key = key;
|
rl->key = key;
|
||||||
rl->db = db;
|
rl->db = db;
|
||||||
incrRefCount(key);
|
incrRefCount(key);
|
@ -1402,7 +1402,7 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
|
|||||||
|
|
||||||
/* ==================== Logging functions for debugging ===================== */
|
/* ==================== Logging functions for debugging ===================== */
|
||||||
|
|
||||||
void serverLogHexDump(int level, char *descr, void *value, size_t len) {
|
void serverLogHexDump(int level, const char *descr, void *value, size_t len) {
|
||||||
char buf[65], *b;
|
char buf[65], *b;
|
||||||
unsigned char *v = value;
|
unsigned char *v = value;
|
||||||
char charset[] = "0123456789abcdef";
|
char charset[] = "0123456789abcdef";
|
||||||
|
@ -46,6 +46,10 @@ typedef struct intset {
|
|||||||
#endif
|
#endif
|
||||||
} intset;
|
} intset;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
intset *intsetNew(void);
|
intset *intsetNew(void);
|
||||||
intset *intsetAdd(intset *is, int64_t value, uint8_t *success);
|
intset *intsetAdd(intset *is, int64_t value, uint8_t *success);
|
||||||
intset *intsetRemove(intset *is, int64_t value, int *success);
|
intset *intsetRemove(intset *is, int64_t value, int *success);
|
||||||
@ -59,4 +63,8 @@ size_t intsetBlobLen(intset *is);
|
|||||||
int intsetTest(int argc, char *argv[]);
|
int intsetTest(int argc, char *argv[]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // __INTSET_H
|
#endif // __INTSET_H
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#ifndef __PQSORT_H
|
#ifndef __PQSORT_H
|
||||||
#define __PQSORT_H
|
#define __PQSORT_H
|
||||||
|
|
||||||
void
|
extern "C" void
|
||||||
pqsort(void *a, size_t n, size_t es,
|
pqsort(void *a, size_t n, size_t es,
|
||||||
int (*cmp) (const void *, const void *), size_t lrange, size_t rrange);
|
int (*cmp) (const void *, const void *), size_t lrange, size_t rrange);
|
||||||
|
|
||||||
|
@ -122,6 +122,10 @@ typedef struct quicklistEntry {
|
|||||||
#define quicklistNodeIsCompressed(node) \
|
#define quicklistNodeIsCompressed(node) \
|
||||||
((node)->encoding == QUICKLIST_NODE_ENCODING_LZF)
|
((node)->encoding == QUICKLIST_NODE_ENCODING_LZF)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
quicklist *quicklistCreate(void);
|
quicklist *quicklistCreate(void);
|
||||||
quicklist *quicklistNew(int fill, int compress);
|
quicklist *quicklistNew(int fill, int compress);
|
||||||
@ -174,4 +178,8 @@ int quicklistTest(int argc, char *argv[]);
|
|||||||
#define AL_START_HEAD 0
|
#define AL_START_HEAD 0
|
||||||
#define AL_START_TAIL 1
|
#define AL_START_TAIL 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __QUICKLIST_H__ */
|
#endif /* __QUICKLIST_H__ */
|
||||||
|
23
src/server.h
23
src/server.h
@ -672,6 +672,11 @@ __attribute__((always_inline)) inline void *ptrFromObj(const robj *o)
|
|||||||
return o->m_ptr;
|
return o->m_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) inline char *szFromObj(const robj *o)
|
||||||
|
{
|
||||||
|
return (char*)ptrFromObj(o);
|
||||||
|
}
|
||||||
|
|
||||||
/* Macro used to initialize a Redis object allocated on the stack.
|
/* Macro used to initialize a Redis object allocated on the stack.
|
||||||
* Note that this macro is taken near the structure definition to make sure
|
* Note that this macro is taken near the structure definition to make sure
|
||||||
* we'll update it when the structure is changed, to avoid bugs like
|
* we'll update it when the structure is changed, to avoid bugs like
|
||||||
@ -926,15 +931,21 @@ struct sharedObjectsStruct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* ZSETs use a specialized version of Skiplists */
|
/* ZSETs use a specialized version of Skiplists */
|
||||||
|
struct zskiplistLevel {
|
||||||
|
struct zskiplistNode *forward;
|
||||||
|
unsigned long span;
|
||||||
|
};
|
||||||
typedef struct zskiplistNode {
|
typedef struct zskiplistNode {
|
||||||
sds ele;
|
sds ele;
|
||||||
double score;
|
double score;
|
||||||
struct zskiplistNode *backward;
|
struct zskiplistNode *backward;
|
||||||
#ifndef __cplusplus
|
|
||||||
struct zskiplistLevel {
|
#ifdef __cplusplus
|
||||||
struct zskiplistNode *forward;
|
zskiplistLevel *level(size_t idx) {
|
||||||
unsigned long span;
|
return reinterpret_cast<zskiplistLevel*>(this+1) + idx;
|
||||||
} level[];
|
}
|
||||||
|
#else
|
||||||
|
struct zskiplistLevel level[];
|
||||||
#endif
|
#endif
|
||||||
} zskiplistNode;
|
} zskiplistNode;
|
||||||
|
|
||||||
@ -2393,7 +2404,7 @@ sds genRedisInfoString(const char *section);
|
|||||||
void enableWatchdog(int period);
|
void enableWatchdog(int period);
|
||||||
void disableWatchdog(void);
|
void disableWatchdog(void);
|
||||||
void watchdogScheduleSignal(int period);
|
void watchdogScheduleSignal(int period);
|
||||||
void serverLogHexDump(int level, char *descr, void *value, size_t len);
|
void serverLogHexDump(int level, const char *descr, void *value, size_t len);
|
||||||
int memtest_preserving_test(unsigned long *m, size_t bytes, int passes);
|
int memtest_preserving_test(unsigned long *m, size_t bytes, int passes);
|
||||||
void mixDigest(unsigned char *digest, void *ptr, size_t len);
|
void mixDigest(unsigned char *digest, void *ptr, size_t len);
|
||||||
void xorDigest(unsigned char *digest, void *ptr, size_t len);
|
void xorDigest(unsigned char *digest, void *ptr, size_t len);
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank);
|
zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank);
|
||||||
|
|
||||||
redisSortOperation *createSortOperation(int type, robj *pattern) {
|
redisSortOperation *createSortOperation(int type, robj *pattern) {
|
||||||
redisSortOperation *so = zmalloc(sizeof(*so), MALLOC_LOCAL);
|
redisSortOperation *so = (redisSortOperation*)zmalloc(sizeof(*so), MALLOC_LOCAL);
|
||||||
so->type = type;
|
so->type = type;
|
||||||
so->pattern = pattern;
|
so->pattern = pattern;
|
||||||
return so;
|
return so;
|
||||||
@ -66,7 +66,7 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst, int writeflag)
|
|||||||
|
|
||||||
/* If the pattern is "#" return the substitution object itself in order
|
/* If the pattern is "#" return the substitution object itself in order
|
||||||
* to implement the "SORT ... GET #" feature. */
|
* to implement the "SORT ... GET #" feature. */
|
||||||
spat = ptrFromObj(pattern);
|
spat = szFromObj(pattern);
|
||||||
if (spat[0] == '#' && spat[1] == '\0') {
|
if (spat[0] == '#' && spat[1] == '\0') {
|
||||||
incrRefCount(subst);
|
incrRefCount(subst);
|
||||||
return subst;
|
return subst;
|
||||||
@ -76,7 +76,7 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst, int writeflag)
|
|||||||
* a decoded object on the fly. Otherwise getDecodedObject will just
|
* a decoded object on the fly. Otherwise getDecodedObject will just
|
||||||
* increment the ref count, that we'll decrement later. */
|
* increment the ref count, that we'll decrement later. */
|
||||||
subst = getDecodedObject(subst);
|
subst = getDecodedObject(subst);
|
||||||
ssub = ptrFromObj(subst);
|
ssub = szFromObj(subst);
|
||||||
|
|
||||||
/* If we can't find '*' in the pattern we return NULL as to GET a
|
/* If we can't find '*' in the pattern we return NULL as to GET a
|
||||||
* fixed key does not make sense. */
|
* fixed key does not make sense. */
|
||||||
@ -99,7 +99,7 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst, int writeflag)
|
|||||||
sublen = sdslen(ssub);
|
sublen = sdslen(ssub);
|
||||||
postfixlen = sdslen(spat)-(prefixlen+1)-(fieldlen ? fieldlen+2 : 0);
|
postfixlen = sdslen(spat)-(prefixlen+1)-(fieldlen ? fieldlen+2 : 0);
|
||||||
keyobj = createStringObject(NULL,prefixlen+sublen+postfixlen);
|
keyobj = createStringObject(NULL,prefixlen+sublen+postfixlen);
|
||||||
k = ptrFromObj(keyobj);
|
k = szFromObj(keyobj);
|
||||||
memcpy(k,spat,prefixlen);
|
memcpy(k,spat,prefixlen);
|
||||||
memcpy(k+prefixlen,ssub,sublen);
|
memcpy(k+prefixlen,ssub,sublen);
|
||||||
memcpy(k+prefixlen+sublen,p+1,postfixlen);
|
memcpy(k+prefixlen+sublen,p+1,postfixlen);
|
||||||
@ -117,7 +117,7 @@ robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst, int writeflag)
|
|||||||
|
|
||||||
/* Retrieve value from hash by the field name. The returend object
|
/* Retrieve value from hash by the field name. The returend object
|
||||||
* is a new object with refcount already incremented. */
|
* is a new object with refcount already incremented. */
|
||||||
o = hashTypeGetValueObject(o, ptrFromObj(fieldobj));
|
o = hashTypeGetValueObject(o, szFromObj(fieldobj));
|
||||||
} else {
|
} else {
|
||||||
if (o->type != OBJ_STRING) goto noobj;
|
if (o->type != OBJ_STRING) goto noobj;
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ noobj:
|
|||||||
* the additional parameter is not standard but a BSD-specific we have to
|
* the additional parameter is not standard but a BSD-specific we have to
|
||||||
* pass sorting parameters via the global 'server' structure */
|
* pass sorting parameters via the global 'server' structure */
|
||||||
int sortCompare(const void *s1, const void *s2) {
|
int sortCompare(const void *s1, const void *s2) {
|
||||||
const redisSortObject *so1 = s1, *so2 = s2;
|
const redisSortObject *so1 = (redisSortObject*)s1, *so2 = (redisSortObject*)s2;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
|
||||||
if (!server.sort_alpha) {
|
if (!server.sort_alpha) {
|
||||||
@ -172,7 +172,7 @@ int sortCompare(const void *s1, const void *s2) {
|
|||||||
} else {
|
} else {
|
||||||
/* Here we can use strcoll() directly as we are sure that
|
/* Here we can use strcoll() directly as we are sure that
|
||||||
* the objects are decoded string objects. */
|
* the objects are decoded string objects. */
|
||||||
cmp = strcoll(ptrFromObj(so1->u.cmpobj),ptrFromObj(so2->u.cmpobj));
|
cmp = strcoll(szFromObj(so1->u.cmpobj),szFromObj(so2->u.cmpobj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -210,13 +210,13 @@ void sortCommand(client *c) {
|
|||||||
/* The SORT command has an SQL-alike syntax, parse it */
|
/* The SORT command has an SQL-alike syntax, parse it */
|
||||||
while(j < c->argc) {
|
while(j < c->argc) {
|
||||||
int leftargs = c->argc-j-1;
|
int leftargs = c->argc-j-1;
|
||||||
if (!strcasecmp(ptrFromObj(c->argv[j]),"asc")) {
|
if (!strcasecmp(szFromObj(c->argv[j]),"asc")) {
|
||||||
desc = 0;
|
desc = 0;
|
||||||
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"desc")) {
|
} else if (!strcasecmp(szFromObj(c->argv[j]),"desc")) {
|
||||||
desc = 1;
|
desc = 1;
|
||||||
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"alpha")) {
|
} else if (!strcasecmp(szFromObj(c->argv[j]),"alpha")) {
|
||||||
alpha = 1;
|
alpha = 1;
|
||||||
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"limit") && leftargs >= 2) {
|
} else if (!strcasecmp(szFromObj(c->argv[j]),"limit") && leftargs >= 2) {
|
||||||
if ((getLongFromObjectOrReply(c, c->argv[j+1], &limit_start, NULL)
|
if ((getLongFromObjectOrReply(c, c->argv[j+1], &limit_start, NULL)
|
||||||
!= C_OK) ||
|
!= C_OK) ||
|
||||||
(getLongFromObjectOrReply(c, c->argv[j+2], &limit_count, NULL)
|
(getLongFromObjectOrReply(c, c->argv[j+2], &limit_count, NULL)
|
||||||
@ -226,14 +226,14 @@ void sortCommand(client *c) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
j+=2;
|
j+=2;
|
||||||
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"store") && leftargs >= 1) {
|
} else if (!strcasecmp(szFromObj(c->argv[j]),"store") && leftargs >= 1) {
|
||||||
storekey = c->argv[j+1];
|
storekey = c->argv[j+1];
|
||||||
j++;
|
j++;
|
||||||
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"by") && leftargs >= 1) {
|
} else if (!strcasecmp(szFromObj(c->argv[j]),"by") && leftargs >= 1) {
|
||||||
sortby = c->argv[j+1];
|
sortby = c->argv[j+1];
|
||||||
/* If the BY pattern does not contain '*', i.e. it is constant,
|
/* If the BY pattern does not contain '*', i.e. it is constant,
|
||||||
* we don't need to sort nor to lookup the weight keys. */
|
* we don't need to sort nor to lookup the weight keys. */
|
||||||
if (strchr(ptrFromObj(c->argv[j+1]),'*') == NULL) {
|
if (strchr(szFromObj(c->argv[j+1]),'*') == NULL) {
|
||||||
dontsort = 1;
|
dontsort = 1;
|
||||||
} else {
|
} else {
|
||||||
/* If BY is specified with a real patter, we can't accept
|
/* If BY is specified with a real patter, we can't accept
|
||||||
@ -245,7 +245,7 @@ void sortCommand(client *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"get") && leftargs >= 1) {
|
} else if (!strcasecmp(szFromObj(c->argv[j]),"get") && leftargs >= 1) {
|
||||||
if (server.cluster_enabled) {
|
if (server.cluster_enabled) {
|
||||||
addReplyError(c,"GET option of SORT denied in Cluster mode.");
|
addReplyError(c,"GET option of SORT denied in Cluster mode.");
|
||||||
syntax_error++;
|
syntax_error++;
|
||||||
@ -347,7 +347,7 @@ void sortCommand(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load the sorting vector with all the objects to sort */
|
/* Load the sorting vector with all the objects to sort */
|
||||||
vector = zmalloc(sizeof(redisSortObject)*vectorlen, MALLOC_LOCAL);
|
vector = (redisSortObject*)zmalloc(sizeof(redisSortObject)*vectorlen, MALLOC_LOCAL);
|
||||||
j = 0;
|
j = 0;
|
||||||
|
|
||||||
if (sortval->type == OBJ_LIST && dontsort) {
|
if (sortval->type == OBJ_LIST && dontsort) {
|
||||||
@ -403,7 +403,7 @@ void sortCommand(client *c) {
|
|||||||
* Note that in this case we also handle LIMIT here in a direct
|
* Note that in this case we also handle LIMIT here in a direct
|
||||||
* way, just getting the required range, as an optimization. */
|
* way, just getting the required range, as an optimization. */
|
||||||
|
|
||||||
zset *zs = ptrFromObj(sortval);
|
zset *zs = (zset*)ptrFromObj(sortval);
|
||||||
zskiplist *zsl = zs->zsl;
|
zskiplist *zsl = zs->zsl;
|
||||||
zskiplistNode *ln;
|
zskiplistNode *ln;
|
||||||
sds sdsele;
|
sds sdsele;
|
||||||
@ -417,7 +417,7 @@ void sortCommand(client *c) {
|
|||||||
if (start > 0)
|
if (start > 0)
|
||||||
ln = zslGetElementByRank(zsl,zsetlen-start);
|
ln = zslGetElementByRank(zsl,zsetlen-start);
|
||||||
} else {
|
} else {
|
||||||
ln = zsl->header->level[0].forward;
|
ln = zsl->header->level(0)->forward;
|
||||||
if (start > 0)
|
if (start > 0)
|
||||||
ln = zslGetElementByRank(zsl,start+1);
|
ln = zslGetElementByRank(zsl,start+1);
|
||||||
}
|
}
|
||||||
@ -429,7 +429,7 @@ void sortCommand(client *c) {
|
|||||||
vector[j].u.score = 0;
|
vector[j].u.score = 0;
|
||||||
vector[j].u.cmpobj = NULL;
|
vector[j].u.cmpobj = NULL;
|
||||||
j++;
|
j++;
|
||||||
ln = desc ? ln->backward : ln->level[0].forward;
|
ln = desc ? ln->backward : ln->level(0)->forward;
|
||||||
}
|
}
|
||||||
/* Fix start/end: output code is not aware of this optimization. */
|
/* Fix start/end: output code is not aware of this optimization. */
|
||||||
end -= start;
|
end -= start;
|
||||||
@ -441,7 +441,7 @@ void sortCommand(client *c) {
|
|||||||
sds sdsele;
|
sds sdsele;
|
||||||
di = dictGetIterator(set);
|
di = dictGetIterator(set);
|
||||||
while((setele = dictNext(di)) != NULL) {
|
while((setele = dictNext(di)) != NULL) {
|
||||||
sdsele = dictGetKey(setele);
|
sdsele = (sds)dictGetKey(setele);
|
||||||
vector[j].obj = createStringObject(sdsele,sdslen(sdsele));
|
vector[j].obj = createStringObject(sdsele,sdslen(sdsele));
|
||||||
vector[j].u.score = 0;
|
vector[j].u.score = 0;
|
||||||
vector[j].u.cmpobj = NULL;
|
vector[j].u.cmpobj = NULL;
|
||||||
@ -472,7 +472,7 @@ void sortCommand(client *c) {
|
|||||||
if (sdsEncodedObject(byval)) {
|
if (sdsEncodedObject(byval)) {
|
||||||
char *eptr;
|
char *eptr;
|
||||||
|
|
||||||
vector[j].u.score = strtod(ptrFromObj(byval),&eptr);
|
vector[j].u.score = strtod(szFromObj(byval),&eptr);
|
||||||
if (eptr[0] != '\0' || errno == ERANGE ||
|
if (eptr[0] != '\0' || errno == ERANGE ||
|
||||||
isnan(vector[j].u.score))
|
isnan(vector[j].u.score))
|
||||||
{
|
{
|
||||||
@ -520,7 +520,7 @@ void sortCommand(client *c) {
|
|||||||
if (!getop) addReplyBulk(c,vector[j].obj);
|
if (!getop) addReplyBulk(c,vector[j].obj);
|
||||||
listRewind(operations,&li);
|
listRewind(operations,&li);
|
||||||
while((ln = listNext(&li))) {
|
while((ln = listNext(&li))) {
|
||||||
redisSortOperation *sop = ln->value;
|
redisSortOperation *sop = (redisSortOperation*)ln->value;
|
||||||
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
||||||
vector[j].obj,storekey!=NULL);
|
vector[j].obj,storekey!=NULL);
|
||||||
|
|
||||||
@ -550,7 +550,7 @@ void sortCommand(client *c) {
|
|||||||
} else {
|
} else {
|
||||||
listRewind(operations,&li);
|
listRewind(operations,&li);
|
||||||
while((ln = listNext(&li))) {
|
while((ln = listNext(&li))) {
|
||||||
redisSortOperation *sop = ln->value;
|
redisSortOperation *sop = (redisSortOperation*)ln->value;
|
||||||
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
robj *val = lookupKeyByPattern(c->db,sop->pattern,
|
||||||
vector[j].obj,storekey!=NULL);
|
vector[j].obj,storekey!=NULL);
|
||||||
|
|
@ -44,7 +44,7 @@ void hashTypeTryConversion(robj *o, robj **argv, int start, int end) {
|
|||||||
|
|
||||||
for (i = start; i <= end; i++) {
|
for (i = start; i <= end; i++) {
|
||||||
if (sdsEncodedObject(argv[i]) &&
|
if (sdsEncodedObject(argv[i]) &&
|
||||||
sdslen(ptrFromObj(argv[i])) > server.hash_max_ziplist_value)
|
sdslen(szFromObj(argv[i])) > server.hash_max_ziplist_value)
|
||||||
{
|
{
|
||||||
hashTypeConvert(o, OBJ_ENCODING_HT);
|
hashTypeConvert(o, OBJ_ENCODING_HT);
|
||||||
break;
|
break;
|
||||||
@ -64,7 +64,7 @@ int hashTypeGetFromZiplist(robj *o, sds field,
|
|||||||
|
|
||||||
serverAssert(o->encoding == OBJ_ENCODING_ZIPLIST);
|
serverAssert(o->encoding == OBJ_ENCODING_ZIPLIST);
|
||||||
|
|
||||||
zl = ptrFromObj(o);
|
zl = (unsigned char*)ptrFromObj(o);
|
||||||
fptr = ziplistIndex(zl, ZIPLIST_HEAD);
|
fptr = ziplistIndex(zl, ZIPLIST_HEAD);
|
||||||
if (fptr != NULL) {
|
if (fptr != NULL) {
|
||||||
fptr = ziplistFind(fptr, (unsigned char*)field, sdslen(field), 1);
|
fptr = ziplistFind(fptr, (unsigned char*)field, sdslen(field), 1);
|
||||||
@ -92,9 +92,9 @@ sds hashTypeGetFromHashTable(robj *o, sds field) {
|
|||||||
|
|
||||||
serverAssert(o->encoding == OBJ_ENCODING_HT);
|
serverAssert(o->encoding == OBJ_ENCODING_HT);
|
||||||
|
|
||||||
de = dictFind(ptrFromObj(o), field);
|
de = dictFind((dict*)ptrFromObj(o), field);
|
||||||
if (de == NULL) return NULL;
|
if (de == NULL) return NULL;
|
||||||
return dictGetVal(de);
|
return (sds)dictGetVal(de);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Higher level function of hashTypeGet*() that returns the hash value
|
/* Higher level function of hashTypeGet*() that returns the hash value
|
||||||
@ -205,7 +205,7 @@ int hashTypeSet(robj *o, sds field, sds value, int flags) {
|
|||||||
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl, *fptr, *vptr;
|
unsigned char *zl, *fptr, *vptr;
|
||||||
|
|
||||||
zl = ptrFromObj(o);
|
zl = (unsigned char*)ptrFromObj(o);
|
||||||
fptr = ziplistIndex(zl, ZIPLIST_HEAD);
|
fptr = ziplistIndex(zl, ZIPLIST_HEAD);
|
||||||
if (fptr != NULL) {
|
if (fptr != NULL) {
|
||||||
fptr = ziplistFind(fptr, (unsigned char*)field, sdslen(field), 1);
|
fptr = ziplistFind(fptr, (unsigned char*)field, sdslen(field), 1);
|
||||||
@ -237,9 +237,9 @@ int hashTypeSet(robj *o, sds field, sds value, int flags) {
|
|||||||
if (hashTypeLength(o) > server.hash_max_ziplist_entries)
|
if (hashTypeLength(o) > server.hash_max_ziplist_entries)
|
||||||
hashTypeConvert(o, OBJ_ENCODING_HT);
|
hashTypeConvert(o, OBJ_ENCODING_HT);
|
||||||
} else if (o->encoding == OBJ_ENCODING_HT) {
|
} else if (o->encoding == OBJ_ENCODING_HT) {
|
||||||
dictEntry *de = dictFind(ptrFromObj(o),field);
|
dictEntry *de = dictFind((dict*)ptrFromObj(o),field);
|
||||||
if (de) {
|
if (de) {
|
||||||
sdsfree(dictGetVal(de));
|
sdsfree((sds)dictGetVal(de));
|
||||||
if (flags & HASH_SET_TAKE_VALUE) {
|
if (flags & HASH_SET_TAKE_VALUE) {
|
||||||
dictGetVal(de) = value;
|
dictGetVal(de) = value;
|
||||||
value = NULL;
|
value = NULL;
|
||||||
@ -261,7 +261,7 @@ int hashTypeSet(robj *o, sds field, sds value, int flags) {
|
|||||||
} else {
|
} else {
|
||||||
v = sdsdup(value);
|
v = sdsdup(value);
|
||||||
}
|
}
|
||||||
dictAdd(ptrFromObj(o),f,v);
|
dictAdd((dict*)ptrFromObj(o),f,v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
@ -282,7 +282,7 @@ int hashTypeDelete(robj *o, sds field) {
|
|||||||
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl, *fptr;
|
unsigned char *zl, *fptr;
|
||||||
|
|
||||||
zl = ptrFromObj(o);
|
zl = (unsigned char*)ptrFromObj(o);
|
||||||
fptr = ziplistIndex(zl, ZIPLIST_HEAD);
|
fptr = ziplistIndex(zl, ZIPLIST_HEAD);
|
||||||
if (fptr != NULL) {
|
if (fptr != NULL) {
|
||||||
fptr = ziplistFind(fptr, (unsigned char*)field, sdslen(field), 1);
|
fptr = ziplistFind(fptr, (unsigned char*)field, sdslen(field), 1);
|
||||||
@ -298,7 +298,7 @@ int hashTypeDelete(robj *o, sds field) {
|
|||||||
deleted = 1;
|
deleted = 1;
|
||||||
|
|
||||||
/* Always check if the dictionary needs a resize after a delete. */
|
/* Always check if the dictionary needs a resize after a delete. */
|
||||||
if (htNeedsResize(ptrFromObj(o))) dictResize(ptrFromObj(o));
|
if (htNeedsResize((dict*)ptrFromObj(o))) dictResize((dict*)ptrFromObj(o));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -312,7 +312,7 @@ unsigned long hashTypeLength(const robj *o) {
|
|||||||
unsigned long length = ULONG_MAX;
|
unsigned long length = ULONG_MAX;
|
||||||
|
|
||||||
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
length = ziplistLen(ptrFromObj(o)) / 2;
|
length = ziplistLen((unsigned char*)ptrFromObj(o)) / 2;
|
||||||
} else if (o->encoding == OBJ_ENCODING_HT) {
|
} else if (o->encoding == OBJ_ENCODING_HT) {
|
||||||
length = dictSize((const dict*)ptrFromObj(o));
|
length = dictSize((const dict*)ptrFromObj(o));
|
||||||
} else {
|
} else {
|
||||||
@ -322,7 +322,7 @@ unsigned long hashTypeLength(const robj *o) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hashTypeIterator *hashTypeInitIterator(robj *subject) {
|
hashTypeIterator *hashTypeInitIterator(robj *subject) {
|
||||||
hashTypeIterator *hi = zmalloc(sizeof(hashTypeIterator), MALLOC_LOCAL);
|
hashTypeIterator *hi = (hashTypeIterator*)zmalloc(sizeof(hashTypeIterator), MALLOC_LOCAL);
|
||||||
hi->subject = subject;
|
hi->subject = subject;
|
||||||
hi->encoding = subject->encoding;
|
hi->encoding = subject->encoding;
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ hashTypeIterator *hashTypeInitIterator(robj *subject) {
|
|||||||
hi->fptr = NULL;
|
hi->fptr = NULL;
|
||||||
hi->vptr = NULL;
|
hi->vptr = NULL;
|
||||||
} else if (hi->encoding == OBJ_ENCODING_HT) {
|
} else if (hi->encoding == OBJ_ENCODING_HT) {
|
||||||
hi->di = dictGetIterator(subject->m_ptr);
|
hi->di = dictGetIterator((dict*)subject->m_ptr);
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown hash encoding");
|
serverPanic("Unknown hash encoding");
|
||||||
}
|
}
|
||||||
@ -350,7 +350,7 @@ int hashTypeNext(hashTypeIterator *hi) {
|
|||||||
unsigned char *zl;
|
unsigned char *zl;
|
||||||
unsigned char *fptr, *vptr;
|
unsigned char *fptr, *vptr;
|
||||||
|
|
||||||
zl = hi->subject->m_ptr;
|
zl = (unsigned char*)hi->subject->m_ptr;
|
||||||
fptr = hi->fptr;
|
fptr = hi->fptr;
|
||||||
vptr = hi->vptr;
|
vptr = hi->vptr;
|
||||||
|
|
||||||
@ -407,9 +407,9 @@ sds hashTypeCurrentFromHashTable(hashTypeIterator *hi, int what) {
|
|||||||
serverAssert(hi->encoding == OBJ_ENCODING_HT);
|
serverAssert(hi->encoding == OBJ_ENCODING_HT);
|
||||||
|
|
||||||
if (what & OBJ_HASH_KEY) {
|
if (what & OBJ_HASH_KEY) {
|
||||||
return dictGetKey(hi->de);
|
return (sds)dictGetKey(hi->de);
|
||||||
} else {
|
} else {
|
||||||
return dictGetVal(hi->de);
|
return (sds)dictGetVal(hi->de);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,7 +484,7 @@ void hashTypeConvertZiplist(robj *o, int enc) {
|
|||||||
ret = dictAdd(dict, key, value);
|
ret = dictAdd(dict, key, value);
|
||||||
if (ret != DICT_OK) {
|
if (ret != DICT_OK) {
|
||||||
serverLogHexDump(LL_WARNING,"ziplist with dup elements dump",
|
serverLogHexDump(LL_WARNING,"ziplist with dup elements dump",
|
||||||
ptrFromObj(o),ziplistBlobLen(ptrFromObj(o)));
|
ptrFromObj(o),ziplistBlobLen((unsigned char*)ptrFromObj(o)));
|
||||||
serverPanic("Ziplist corruption detected");
|
serverPanic("Ziplist corruption detected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -516,10 +516,10 @@ void hsetnxCommand(client *c) {
|
|||||||
if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
|
if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
|
||||||
hashTypeTryConversion(o,c->argv,2,3);
|
hashTypeTryConversion(o,c->argv,2,3);
|
||||||
|
|
||||||
if (hashTypeExists(o, ptrFromObj(c->argv[2]))) {
|
if (hashTypeExists(o, szFromObj(c->argv[2]))) {
|
||||||
addReply(c, shared.czero);
|
addReply(c, shared.czero);
|
||||||
} else {
|
} else {
|
||||||
hashTypeSet(o,ptrFromObj(c->argv[2]),ptrFromObj(c->argv[3]),HASH_SET_COPY);
|
hashTypeSet(o,szFromObj(c->argv[2]),szFromObj(c->argv[3]),HASH_SET_COPY);
|
||||||
addReply(c, shared.cone);
|
addReply(c, shared.cone);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(NOTIFY_HASH,"hset",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hset",c->argv[1],c->db->id);
|
||||||
@ -540,10 +540,10 @@ void hsetCommand(client *c) {
|
|||||||
hashTypeTryConversion(o,c->argv,2,c->argc-1);
|
hashTypeTryConversion(o,c->argv,2,c->argc-1);
|
||||||
|
|
||||||
for (i = 2; i < c->argc; i += 2)
|
for (i = 2; i < c->argc; i += 2)
|
||||||
created += !hashTypeSet(o,ptrFromObj(c->argv[i]),ptrFromObj(c->argv[i+1]),HASH_SET_COPY);
|
created += !hashTypeSet(o,szFromObj(c->argv[i]),szFromObj(c->argv[i+1]),HASH_SET_COPY);
|
||||||
|
|
||||||
/* HMSET (deprecated) and HSET return value is different. */
|
/* HMSET (deprecated) and HSET return value is different. */
|
||||||
char *cmdname = ptrFromObj(c->argv[0]);
|
char *cmdname = szFromObj(c->argv[0]);
|
||||||
if (cmdname[1] == 's' || cmdname[1] == 'S') {
|
if (cmdname[1] == 's' || cmdname[1] == 'S') {
|
||||||
/* HSET */
|
/* HSET */
|
||||||
addReplyLongLong(c, created);
|
addReplyLongLong(c, created);
|
||||||
@ -559,13 +559,13 @@ void hsetCommand(client *c) {
|
|||||||
void hincrbyCommand(client *c) {
|
void hincrbyCommand(client *c) {
|
||||||
long long value, incr, oldvalue;
|
long long value, incr, oldvalue;
|
||||||
robj *o;
|
robj *o;
|
||||||
sds new;
|
sds newstr;
|
||||||
unsigned char *vstr;
|
unsigned char *vstr;
|
||||||
unsigned int vlen;
|
unsigned int vlen;
|
||||||
|
|
||||||
if (getLongLongFromObjectOrReply(c,c->argv[3],&incr,NULL) != C_OK) return;
|
if (getLongLongFromObjectOrReply(c,c->argv[3],&incr,NULL) != C_OK) return;
|
||||||
if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
|
if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
|
||||||
if (hashTypeGetValue(o,ptrFromObj(c->argv[2]),&vstr,&vlen,&value) == C_OK) {
|
if (hashTypeGetValue(o,szFromObj(c->argv[2]),&vstr,&vlen,&value) == C_OK) {
|
||||||
if (vstr) {
|
if (vstr) {
|
||||||
if (string2ll((char*)vstr,vlen,&value) == 0) {
|
if (string2ll((char*)vstr,vlen,&value) == 0) {
|
||||||
addReplyError(c,"hash value is not an integer");
|
addReplyError(c,"hash value is not an integer");
|
||||||
@ -583,8 +583,8 @@ void hincrbyCommand(client *c) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value += incr;
|
value += incr;
|
||||||
new = sdsfromlonglong(value);
|
newstr = sdsfromlonglong(value);
|
||||||
hashTypeSet(o,ptrFromObj(c->argv[2]),new,HASH_SET_TAKE_VALUE);
|
hashTypeSet(o,szFromObj(c->argv[2]),newstr,HASH_SET_TAKE_VALUE);
|
||||||
addReplyLongLong(c,value);
|
addReplyLongLong(c,value);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(NOTIFY_HASH,"hincrby",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hincrby",c->argv[1],c->db->id);
|
||||||
@ -595,13 +595,13 @@ void hincrbyfloatCommand(client *c) {
|
|||||||
long double value, incr;
|
long double value, incr;
|
||||||
long long ll;
|
long long ll;
|
||||||
robj *o;
|
robj *o;
|
||||||
sds new;
|
sds newstr;
|
||||||
unsigned char *vstr;
|
unsigned char *vstr;
|
||||||
unsigned int vlen;
|
unsigned int vlen;
|
||||||
|
|
||||||
if (getLongDoubleFromObjectOrReply(c,c->argv[3],&incr,NULL) != C_OK) return;
|
if (getLongDoubleFromObjectOrReply(c,c->argv[3],&incr,NULL) != C_OK) return;
|
||||||
if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
|
if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
|
||||||
if (hashTypeGetValue(o,ptrFromObj(c->argv[2]),&vstr,&vlen,&ll) == C_OK) {
|
if (hashTypeGetValue(o,szFromObj(c->argv[2]),&vstr,&vlen,&ll) == C_OK) {
|
||||||
if (vstr) {
|
if (vstr) {
|
||||||
if (string2ld((char*)vstr,vlen,&value) == 0) {
|
if (string2ld((char*)vstr,vlen,&value) == 0) {
|
||||||
addReplyError(c,"hash value is not a float");
|
addReplyError(c,"hash value is not a float");
|
||||||
@ -622,8 +622,8 @@ void hincrbyfloatCommand(client *c) {
|
|||||||
|
|
||||||
char buf[MAX_LONG_DOUBLE_CHARS];
|
char buf[MAX_LONG_DOUBLE_CHARS];
|
||||||
int len = ld2string(buf,sizeof(buf),value,1);
|
int len = ld2string(buf,sizeof(buf),value,1);
|
||||||
new = sdsnewlen(buf,len);
|
newstr = sdsnewlen(buf,len);
|
||||||
hashTypeSet(o,ptrFromObj(c->argv[2]),new,HASH_SET_TAKE_VALUE);
|
hashTypeSet(o,szFromObj(c->argv[2]),newstr,HASH_SET_TAKE_VALUE);
|
||||||
addReplyBulkCBuffer(c,buf,len);
|
addReplyBulkCBuffer(c,buf,len);
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(NOTIFY_HASH,"hincrbyfloat",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_HASH,"hincrbyfloat",c->argv[1],c->db->id);
|
||||||
@ -682,7 +682,7 @@ void hgetCommand(client *c) {
|
|||||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.null[c->resp])) == NULL ||
|
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.null[c->resp])) == NULL ||
|
||||||
checkType(c,o,OBJ_HASH)) return;
|
checkType(c,o,OBJ_HASH)) return;
|
||||||
|
|
||||||
addHashFieldToReply(c, o, ptrFromObj(c->argv[2]));
|
addHashFieldToReply(c, o, szFromObj(c->argv[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmgetCommand(client *c) {
|
void hmgetCommand(client *c) {
|
||||||
@ -699,7 +699,7 @@ void hmgetCommand(client *c) {
|
|||||||
|
|
||||||
addReplyArrayLen(c, c->argc-2);
|
addReplyArrayLen(c, c->argc-2);
|
||||||
for (i = 2; i < c->argc; i++) {
|
for (i = 2; i < c->argc; i++) {
|
||||||
addHashFieldToReply(c, o, ptrFromObj(c->argv[i]));
|
addHashFieldToReply(c, o, szFromObj(c->argv[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,7 +711,7 @@ void hdelCommand(client *c) {
|
|||||||
checkType(c,o,OBJ_HASH)) return;
|
checkType(c,o,OBJ_HASH)) return;
|
||||||
|
|
||||||
for (j = 2; j < c->argc; j++) {
|
for (j = 2; j < c->argc; j++) {
|
||||||
if (hashTypeDelete(o,ptrFromObj(c->argv[j]))) {
|
if (hashTypeDelete(o,szFromObj(c->argv[j]))) {
|
||||||
deleted++;
|
deleted++;
|
||||||
if (hashTypeLength(o) == 0) {
|
if (hashTypeLength(o) == 0) {
|
||||||
dbDelete(c->db,c->argv[1]);
|
dbDelete(c->db,c->argv[1]);
|
||||||
@ -745,7 +745,7 @@ void hstrlenCommand(client *c) {
|
|||||||
|
|
||||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
|
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
|
||||||
checkType(c,o,OBJ_HASH)) return;
|
checkType(c,o,OBJ_HASH)) return;
|
||||||
addReplyLongLong(c,hashTypeGetValueLength(o,ptrFromObj(c->argv[2])));
|
addReplyLongLong(c,hashTypeGetValueLength(o,szFromObj(c->argv[2])));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addHashIteratorCursorToReply(client *c, hashTypeIterator *hi, int what) {
|
static void addHashIteratorCursorToReply(client *c, hashTypeIterator *hi, int what) {
|
||||||
@ -820,7 +820,7 @@ void hexistsCommand(client *c) {
|
|||||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
|
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
|
||||||
checkType(c,o,OBJ_HASH)) return;
|
checkType(c,o,OBJ_HASH)) return;
|
||||||
|
|
||||||
addReply(c, hashTypeExists(o,ptrFromObj(c->argv[2])) ? shared.cone : shared.czero);
|
addReply(c, hashTypeExists(o,szFromObj(c->argv[2])) ? shared.cone : shared.czero);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hscanCommand(client *c) {
|
void hscanCommand(client *c) {
|
@ -42,8 +42,8 @@ void listTypePush(robj *subject, robj *value, int where) {
|
|||||||
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
int pos = (where == LIST_HEAD) ? QUICKLIST_HEAD : QUICKLIST_TAIL;
|
int pos = (where == LIST_HEAD) ? QUICKLIST_HEAD : QUICKLIST_TAIL;
|
||||||
value = getDecodedObject(value);
|
value = getDecodedObject(value);
|
||||||
size_t len = sdslen(ptrFromObj(value));
|
size_t len = sdslen(szFromObj(value));
|
||||||
quicklistPush(ptrFromObj(subject), ptrFromObj(value), len, pos);
|
quicklistPush((quicklist*)ptrFromObj(subject), ptrFromObj(value), len, pos);
|
||||||
decrRefCount(value);
|
decrRefCount(value);
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
@ -60,7 +60,7 @@ robj *listTypePop(robj *subject, int where) {
|
|||||||
|
|
||||||
int ql_where = where == LIST_HEAD ? QUICKLIST_HEAD : QUICKLIST_TAIL;
|
int ql_where = where == LIST_HEAD ? QUICKLIST_HEAD : QUICKLIST_TAIL;
|
||||||
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
if (quicklistPopCustom(ptrFromObj(subject), ql_where, (unsigned char **)&value,
|
if (quicklistPopCustom((quicklist*)ptrFromObj(subject), ql_where, (unsigned char **)&value,
|
||||||
NULL, &vlong, listPopSaver)) {
|
NULL, &vlong, listPopSaver)) {
|
||||||
if (!value)
|
if (!value)
|
||||||
value = createStringObjectFromLongLong(vlong);
|
value = createStringObjectFromLongLong(vlong);
|
||||||
@ -73,7 +73,7 @@ robj *listTypePop(robj *subject, int where) {
|
|||||||
|
|
||||||
unsigned long listTypeLength(const robj *subject) {
|
unsigned long listTypeLength(const robj *subject) {
|
||||||
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (subject->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
return quicklistCount(ptrFromObj(subject));
|
return quicklistCount((quicklist*)ptrFromObj(subject));
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
@ -82,7 +82,7 @@ unsigned long listTypeLength(const robj *subject) {
|
|||||||
/* Initialize an iterator at the specified index. */
|
/* Initialize an iterator at the specified index. */
|
||||||
listTypeIterator *listTypeInitIterator(robj *subject, long index,
|
listTypeIterator *listTypeInitIterator(robj *subject, long index,
|
||||||
unsigned char direction) {
|
unsigned char direction) {
|
||||||
listTypeIterator *li = zmalloc(sizeof(listTypeIterator), MALLOC_LOCAL);
|
listTypeIterator *li = (listTypeIterator*)zmalloc(sizeof(listTypeIterator), MALLOC_LOCAL);
|
||||||
li->subject = subject;
|
li->subject = subject;
|
||||||
li->encoding = subject->encoding;
|
li->encoding = subject->encoding;
|
||||||
li->direction = direction;
|
li->direction = direction;
|
||||||
@ -92,7 +92,7 @@ listTypeIterator *listTypeInitIterator(robj *subject, long index,
|
|||||||
int iter_direction =
|
int iter_direction =
|
||||||
direction == LIST_HEAD ? AL_START_TAIL : AL_START_HEAD;
|
direction == LIST_HEAD ? AL_START_TAIL : AL_START_HEAD;
|
||||||
if (li->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (li->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
li->iter = quicklistGetIteratorAtIdx(ptrFromObj(li->subject),
|
li->iter = quicklistGetIteratorAtIdx((const quicklist*)ptrFromObj(li->subject),
|
||||||
iter_direction, index);
|
iter_direction, index);
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
@ -141,7 +141,7 @@ robj *listTypeGet(listTypeEntry *entry) {
|
|||||||
void listTypeInsert(listTypeEntry *entry, robj *value, int where) {
|
void listTypeInsert(listTypeEntry *entry, robj *value, int where) {
|
||||||
if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
value = getDecodedObject(value);
|
value = getDecodedObject(value);
|
||||||
sds str = ptrFromObj(value);
|
sds str = szFromObj(value);
|
||||||
size_t len = sdslen(str);
|
size_t len = sdslen(str);
|
||||||
if (where == LIST_TAIL) {
|
if (where == LIST_TAIL) {
|
||||||
quicklistInsertAfter((quicklist *)entry->entry.qlist,
|
quicklistInsertAfter((quicklist *)entry->entry.qlist,
|
||||||
@ -160,7 +160,7 @@ void listTypeInsert(listTypeEntry *entry, robj *value, int where) {
|
|||||||
int listTypeEqual(listTypeEntry *entry, robj *o) {
|
int listTypeEqual(listTypeEntry *entry, robj *o) {
|
||||||
if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
serverAssertWithInfo(NULL,o,sdsEncodedObject(o));
|
serverAssertWithInfo(NULL,o,sdsEncodedObject(o));
|
||||||
return quicklistCompare(entry->entry.zi,ptrFromObj(o),sdslen(ptrFromObj(o)));
|
return quicklistCompare(entry->entry.zi,(unsigned char*)ptrFromObj(o),sdslen(szFromObj(o)));
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ void listTypeConvert(robj *subject, int enc) {
|
|||||||
if (enc == OBJ_ENCODING_QUICKLIST) {
|
if (enc == OBJ_ENCODING_QUICKLIST) {
|
||||||
size_t zlen = server.list_max_ziplist_size;
|
size_t zlen = server.list_max_ziplist_size;
|
||||||
int depth = server.list_compress_depth;
|
int depth = server.list_compress_depth;
|
||||||
subject->m_ptr = quicklistCreateFromZiplist(zlen, depth, ptrFromObj(subject));
|
subject->m_ptr = quicklistCreateFromZiplist(zlen, depth, (unsigned char*)ptrFromObj(subject));
|
||||||
subject->encoding = OBJ_ENCODING_QUICKLIST;
|
subject->encoding = OBJ_ENCODING_QUICKLIST;
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unsupported list conversion");
|
serverPanic("Unsupported list conversion");
|
||||||
@ -206,7 +206,7 @@ void pushGenericCommand(client *c, int where) {
|
|||||||
for (j = 2; j < c->argc; j++) {
|
for (j = 2; j < c->argc; j++) {
|
||||||
if (!lobj) {
|
if (!lobj) {
|
||||||
lobj = createQuicklistObject();
|
lobj = createQuicklistObject();
|
||||||
quicklistSetOptions(ptrFromObj(lobj), server.list_max_ziplist_size,
|
quicklistSetOptions((quicklist*)ptrFromObj(lobj), server.list_max_ziplist_size,
|
||||||
server.list_compress_depth);
|
server.list_compress_depth);
|
||||||
dbAdd(c->db,c->argv[1],lobj);
|
dbAdd(c->db,c->argv[1],lobj);
|
||||||
}
|
}
|
||||||
@ -215,7 +215,7 @@ void pushGenericCommand(client *c, int where) {
|
|||||||
}
|
}
|
||||||
addReplyLongLong(c, (lobj ? listTypeLength(lobj) : 0));
|
addReplyLongLong(c, (lobj ? listTypeLength(lobj) : 0));
|
||||||
if (pushed) {
|
if (pushed) {
|
||||||
char *event = (where == LIST_HEAD) ? "lpush" : "rpush";
|
const char *event = (where == LIST_HEAD) ? "lpush" : "rpush";
|
||||||
|
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);
|
||||||
@ -246,7 +246,7 @@ void pushxGenericCommand(client *c, int where) {
|
|||||||
addReplyLongLong(c,listTypeLength(subject));
|
addReplyLongLong(c,listTypeLength(subject));
|
||||||
|
|
||||||
if (pushed) {
|
if (pushed) {
|
||||||
char *event = (where == LIST_HEAD) ? "lpush" : "rpush";
|
const char *event = (where == LIST_HEAD) ? "lpush" : "rpush";
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);
|
||||||
}
|
}
|
||||||
@ -268,9 +268,9 @@ void linsertCommand(client *c) {
|
|||||||
listTypeEntry entry;
|
listTypeEntry entry;
|
||||||
int inserted = 0;
|
int inserted = 0;
|
||||||
|
|
||||||
if (strcasecmp(ptrFromObj(c->argv[2]),"after") == 0) {
|
if (strcasecmp(szFromObj(c->argv[2]),"after") == 0) {
|
||||||
where = LIST_TAIL;
|
where = LIST_TAIL;
|
||||||
} else if (strcasecmp(ptrFromObj(c->argv[2]),"before") == 0) {
|
} else if (strcasecmp(szFromObj(c->argv[2]),"before") == 0) {
|
||||||
where = LIST_HEAD;
|
where = LIST_HEAD;
|
||||||
} else {
|
} else {
|
||||||
addReply(c,shared.syntaxerr);
|
addReply(c,shared.syntaxerr);
|
||||||
@ -322,7 +322,7 @@ void lindexCommand(client *c) {
|
|||||||
|
|
||||||
if (o->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (o->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
quicklistEntry entry;
|
quicklistEntry entry;
|
||||||
if (quicklistIndex(ptrFromObj(o), index, &entry)) {
|
if (quicklistIndex((quicklist*)ptrFromObj(o), index, &entry)) {
|
||||||
if (entry.value) {
|
if (entry.value) {
|
||||||
value = createStringObject((char*)entry.value,entry.sz);
|
value = createStringObject((char*)entry.value,entry.sz);
|
||||||
} else {
|
} else {
|
||||||
@ -348,9 +348,9 @@ void lsetCommand(client *c) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (o->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (o->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
quicklist *ql = ptrFromObj(o);
|
quicklist *ql = (quicklist*)ptrFromObj(o);
|
||||||
int replaced = quicklistReplaceAtIndex(ql, index,
|
int replaced = quicklistReplaceAtIndex(ql, index,
|
||||||
ptrFromObj(value), sdslen(ptrFromObj(value)));
|
szFromObj(value), sdslen(szFromObj(value)));
|
||||||
if (!replaced) {
|
if (!replaced) {
|
||||||
addReply(c,shared.outofrangeerr);
|
addReply(c,shared.outofrangeerr);
|
||||||
} else {
|
} else {
|
||||||
@ -372,7 +372,7 @@ void popGenericCommand(client *c, int where) {
|
|||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
addReplyNull(c);
|
addReplyNull(c);
|
||||||
} else {
|
} else {
|
||||||
char *event = (where == LIST_HEAD) ? "lpop" : "rpop";
|
const char *event = (where == LIST_HEAD) ? "lpop" : "rpop";
|
||||||
|
|
||||||
addReplyBulk(c,value);
|
addReplyBulk(c,value);
|
||||||
decrRefCount(value);
|
decrRefCount(value);
|
||||||
@ -471,8 +471,8 @@ void ltrimCommand(client *c) {
|
|||||||
|
|
||||||
/* Remove list elements to perform the trim */
|
/* Remove list elements to perform the trim */
|
||||||
if (o->encoding == OBJ_ENCODING_QUICKLIST) {
|
if (o->encoding == OBJ_ENCODING_QUICKLIST) {
|
||||||
quicklistDelRange(ptrFromObj(o),0,ltrim);
|
quicklistDelRange((quicklist*)ptrFromObj(o),0,ltrim);
|
||||||
quicklistDelRange(ptrFromObj(o),-rtrim,rtrim);
|
quicklistDelRange((quicklist*)ptrFromObj(o),-rtrim,rtrim);
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown list encoding");
|
serverPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
@ -551,7 +551,7 @@ static void rpoplpushHandlePush(client *c, robj *dstkey, robj *dstobj, robj *val
|
|||||||
/* Create the list if the key does not exist */
|
/* Create the list if the key does not exist */
|
||||||
if (!dstobj) {
|
if (!dstobj) {
|
||||||
dstobj = createQuicklistObject();
|
dstobj = createQuicklistObject();
|
||||||
quicklistSetOptions(ptrFromObj(dstobj), server.list_max_ziplist_size,
|
quicklistSetOptions((quicklist*)ptrFromObj(dstobj), server.list_max_ziplist_size,
|
||||||
server.list_compress_depth);
|
server.list_compress_depth);
|
||||||
dbAdd(c->db,dstkey,dstobj);
|
dbAdd(c->db,dstkey,dstobj);
|
||||||
}
|
}
|
||||||
@ -645,7 +645,7 @@ int serveClientBlockedOnList(client *receiver, robj *key, robj *dstkey, redisDb
|
|||||||
addReplyBulkAsync(receiver,value);
|
addReplyBulkAsync(receiver,value);
|
||||||
|
|
||||||
/* Notify event. */
|
/* Notify event. */
|
||||||
char *event = (where == LIST_HEAD) ? "lpop" : "rpop";
|
const char *event = (where == LIST_HEAD) ? "lpop" : "rpop";
|
||||||
notifyKeyspaceEvent(NOTIFY_LIST,event,key,receiver->db->id);
|
notifyKeyspaceEvent(NOTIFY_LIST,event,key,receiver->db->id);
|
||||||
fastlock_unlock(&receiver->lock);
|
fastlock_unlock(&receiver->lock);
|
||||||
} else {
|
} else {
|
||||||
@ -705,7 +705,7 @@ void blockingPopGenericCommand(client *c, int where) {
|
|||||||
} else {
|
} else {
|
||||||
if (listTypeLength(o) != 0) {
|
if (listTypeLength(o) != 0) {
|
||||||
/* Non empty list, this is like a non normal [LR]POP. */
|
/* Non empty list, this is like a non normal [LR]POP. */
|
||||||
char *event = (where == LIST_HEAD) ? "lpop" : "rpop";
|
const char *event = (where == LIST_HEAD) ? "lpop" : "rpop";
|
||||||
robj *value = listTypePop(o,where);
|
robj *value = listTypePop(o,where);
|
||||||
serverAssert(value != NULL);
|
serverAssert(value != NULL);
|
||||||
|
|
@ -52,7 +52,7 @@ robj *setTypeCreate(sds value) {
|
|||||||
int setTypeAdd(robj *subject, sds value) {
|
int setTypeAdd(robj *subject, sds value) {
|
||||||
long long llval;
|
long long llval;
|
||||||
if (subject->encoding == OBJ_ENCODING_HT) {
|
if (subject->encoding == OBJ_ENCODING_HT) {
|
||||||
dict *ht = subject->m_ptr;
|
dict *ht = (dict*)subject->m_ptr;
|
||||||
dictEntry *de = dictAddRaw(ht,value,NULL);
|
dictEntry *de = dictAddRaw(ht,value,NULL);
|
||||||
if (de) {
|
if (de) {
|
||||||
dictSetKey(ht,de,sdsdup(value));
|
dictSetKey(ht,de,sdsdup(value));
|
||||||
@ -62,11 +62,11 @@ int setTypeAdd(robj *subject, sds value) {
|
|||||||
} else if (subject->encoding == OBJ_ENCODING_INTSET) {
|
} else if (subject->encoding == OBJ_ENCODING_INTSET) {
|
||||||
if (isSdsRepresentableAsLongLong(value,&llval) == C_OK) {
|
if (isSdsRepresentableAsLongLong(value,&llval) == C_OK) {
|
||||||
uint8_t success = 0;
|
uint8_t success = 0;
|
||||||
subject->m_ptr = intsetAdd(subject->m_ptr,llval,&success);
|
subject->m_ptr = intsetAdd((intset*)subject->m_ptr,llval,&success);
|
||||||
if (success) {
|
if (success) {
|
||||||
/* Convert to regular set when the intset contains
|
/* Convert to regular set when the intset contains
|
||||||
* too many entries. */
|
* too many entries. */
|
||||||
if (intsetLen(subject->m_ptr) > server.set_max_intset_entries)
|
if (intsetLen((intset*)subject->m_ptr) > server.set_max_intset_entries)
|
||||||
setTypeConvert(subject,OBJ_ENCODING_HT);
|
setTypeConvert(subject,OBJ_ENCODING_HT);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ int setTypeAdd(robj *subject, sds value) {
|
|||||||
|
|
||||||
/* The set *was* an intset and this value is not integer
|
/* The set *was* an intset and this value is not integer
|
||||||
* encodable, so dictAdd should always work. */
|
* encodable, so dictAdd should always work. */
|
||||||
serverAssert(dictAdd(subject->m_ptr,sdsdup(value),NULL) == DICT_OK);
|
serverAssert(dictAdd((dict*)subject->m_ptr,sdsdup(value),NULL) == DICT_OK);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -88,14 +88,14 @@ int setTypeAdd(robj *subject, sds value) {
|
|||||||
int setTypeRemove(robj *setobj, sds value) {
|
int setTypeRemove(robj *setobj, sds value) {
|
||||||
long long llval;
|
long long llval;
|
||||||
if (setobj->encoding == OBJ_ENCODING_HT) {
|
if (setobj->encoding == OBJ_ENCODING_HT) {
|
||||||
if (dictDelete(setobj->m_ptr,value) == DICT_OK) {
|
if (dictDelete((dict*)setobj->m_ptr,value) == DICT_OK) {
|
||||||
if (htNeedsResize(setobj->m_ptr)) dictResize(setobj->m_ptr);
|
if (htNeedsResize((dict*)setobj->m_ptr)) dictResize((dict*)setobj->m_ptr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if (setobj->encoding == OBJ_ENCODING_INTSET) {
|
} else if (setobj->encoding == OBJ_ENCODING_INTSET) {
|
||||||
if (isSdsRepresentableAsLongLong(value,&llval) == C_OK) {
|
if (isSdsRepresentableAsLongLong(value,&llval) == C_OK) {
|
||||||
int success;
|
int success;
|
||||||
setobj->m_ptr = intsetRemove(setobj->m_ptr,llval,&success);
|
setobj->m_ptr = intsetRemove((intset*)setobj->m_ptr,llval,&success);
|
||||||
if (success) return 1;
|
if (success) return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -119,11 +119,11 @@ int setTypeIsMember(robj *subject, sds value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTypeIterator *setTypeInitIterator(robj *subject) {
|
setTypeIterator *setTypeInitIterator(robj *subject) {
|
||||||
setTypeIterator *si = zmalloc(sizeof(setTypeIterator), MALLOC_LOCAL);
|
setTypeIterator *si = (setTypeIterator*)zmalloc(sizeof(setTypeIterator), MALLOC_LOCAL);
|
||||||
si->subject = subject;
|
si->subject = subject;
|
||||||
si->encoding = subject->encoding;
|
si->encoding = subject->encoding;
|
||||||
if (si->encoding == OBJ_ENCODING_HT) {
|
if (si->encoding == OBJ_ENCODING_HT) {
|
||||||
si->di = dictGetIterator(subject->m_ptr);
|
si->di = dictGetIterator((dict*)subject->m_ptr);
|
||||||
} else if (si->encoding == OBJ_ENCODING_INTSET) {
|
} else if (si->encoding == OBJ_ENCODING_INTSET) {
|
||||||
si->ii = 0;
|
si->ii = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -155,10 +155,10 @@ int setTypeNext(setTypeIterator *si, sds *sdsele, int64_t *llele) {
|
|||||||
if (si->encoding == OBJ_ENCODING_HT) {
|
if (si->encoding == OBJ_ENCODING_HT) {
|
||||||
dictEntry *de = dictNext(si->di);
|
dictEntry *de = dictNext(si->di);
|
||||||
if (de == NULL) return -1;
|
if (de == NULL) return -1;
|
||||||
*sdsele = dictGetKey(de);
|
*sdsele = (sds)dictGetKey(de);
|
||||||
*llele = -123456789; /* Not needed. Defensive. */
|
*llele = -123456789; /* Not needed. Defensive. */
|
||||||
} else if (si->encoding == OBJ_ENCODING_INTSET) {
|
} else if (si->encoding == OBJ_ENCODING_INTSET) {
|
||||||
if (!intsetGet(si->subject->m_ptr,si->ii++,llele))
|
if (!intsetGet((intset*)si->subject->m_ptr,si->ii++,llele))
|
||||||
return -1;
|
return -1;
|
||||||
*sdsele = NULL; /* Not needed. Defensive. */
|
*sdsele = NULL; /* Not needed. Defensive. */
|
||||||
} else {
|
} else {
|
||||||
@ -207,11 +207,11 @@ sds setTypeNextObject(setTypeIterator *si) {
|
|||||||
* used field with values which are easy to trap if misused. */
|
* used field with values which are easy to trap if misused. */
|
||||||
int setTypeRandomElement(robj *setobj, sds *sdsele, int64_t *llele) {
|
int setTypeRandomElement(robj *setobj, sds *sdsele, int64_t *llele) {
|
||||||
if (setobj->encoding == OBJ_ENCODING_HT) {
|
if (setobj->encoding == OBJ_ENCODING_HT) {
|
||||||
dictEntry *de = dictGetFairRandomKey(setobj->m_ptr);
|
dictEntry *de = dictGetFairRandomKey((dict*)setobj->m_ptr);
|
||||||
*sdsele = dictGetKey(de);
|
*sdsele = (sds)dictGetKey(de);
|
||||||
*llele = -123456789; /* Not needed. Defensive. */
|
*llele = -123456789; /* Not needed. Defensive. */
|
||||||
} else if (setobj->encoding == OBJ_ENCODING_INTSET) {
|
} else if (setobj->encoding == OBJ_ENCODING_INTSET) {
|
||||||
*llele = intsetRandom(setobj->m_ptr);
|
*llele = intsetRandom((intset*)setobj->m_ptr);
|
||||||
*sdsele = NULL; /* Not needed. Defensive. */
|
*sdsele = NULL; /* Not needed. Defensive. */
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
@ -243,7 +243,7 @@ void setTypeConvert(robj *setobj, int enc) {
|
|||||||
sds element;
|
sds element;
|
||||||
|
|
||||||
/* Presize the dict to avoid rehashing */
|
/* Presize the dict to avoid rehashing */
|
||||||
dictExpand(d,intsetLen(setobj->m_ptr));
|
dictExpand(d,intsetLen((intset*)setobj->m_ptr));
|
||||||
|
|
||||||
/* To add the elements we extract integers and create redis objects */
|
/* To add the elements we extract integers and create redis objects */
|
||||||
si = setTypeInitIterator(setobj);
|
si = setTypeInitIterator(setobj);
|
||||||
@ -267,7 +267,7 @@ void saddCommand(client *c) {
|
|||||||
|
|
||||||
set = lookupKeyWrite(c->db,c->argv[1]);
|
set = lookupKeyWrite(c->db,c->argv[1]);
|
||||||
if (set == NULL) {
|
if (set == NULL) {
|
||||||
set = setTypeCreate(ptrFromObj(c->argv[2]));
|
set = setTypeCreate(szFromObj(c->argv[2]));
|
||||||
dbAdd(c->db,c->argv[1],set);
|
dbAdd(c->db,c->argv[1],set);
|
||||||
} else {
|
} else {
|
||||||
if (set->type != OBJ_SET) {
|
if (set->type != OBJ_SET) {
|
||||||
@ -277,7 +277,7 @@ void saddCommand(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (j = 2; j < c->argc; j++) {
|
for (j = 2; j < c->argc; j++) {
|
||||||
if (setTypeAdd(set,ptrFromObj(c->argv[j]))) added++;
|
if (setTypeAdd(set,szFromObj(c->argv[j]))) added++;
|
||||||
}
|
}
|
||||||
if (added) {
|
if (added) {
|
||||||
signalModifiedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
@ -295,7 +295,7 @@ void sremCommand(client *c) {
|
|||||||
checkType(c,set,OBJ_SET)) return;
|
checkType(c,set,OBJ_SET)) return;
|
||||||
|
|
||||||
for (j = 2; j < c->argc; j++) {
|
for (j = 2; j < c->argc; j++) {
|
||||||
if (setTypeRemove(set,ptrFromObj(c->argv[j]))) {
|
if (setTypeRemove(set,szFromObj(c->argv[j]))) {
|
||||||
deleted++;
|
deleted++;
|
||||||
if (setTypeSize(set) == 0) {
|
if (setTypeSize(set) == 0) {
|
||||||
dbDelete(c->db,c->argv[1]);
|
dbDelete(c->db,c->argv[1]);
|
||||||
@ -334,13 +334,13 @@ void smoveCommand(client *c) {
|
|||||||
|
|
||||||
/* If srcset and dstset are equal, SMOVE is a no-op */
|
/* If srcset and dstset are equal, SMOVE is a no-op */
|
||||||
if (srcset == dstset) {
|
if (srcset == dstset) {
|
||||||
addReply(c,setTypeIsMember(srcset,ptrFromObj(ele)) ?
|
addReply(c,setTypeIsMember(srcset,szFromObj(ele)) ?
|
||||||
shared.cone : shared.czero);
|
shared.cone : shared.czero);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the element cannot be removed from the src set, return 0. */
|
/* If the element cannot be removed from the src set, return 0. */
|
||||||
if (!setTypeRemove(srcset,ptrFromObj(ele))) {
|
if (!setTypeRemove(srcset,szFromObj(ele))) {
|
||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@ void smoveCommand(client *c) {
|
|||||||
|
|
||||||
/* Create the destination set when it doesn't exist */
|
/* Create the destination set when it doesn't exist */
|
||||||
if (!dstset) {
|
if (!dstset) {
|
||||||
dstset = setTypeCreate(ptrFromObj(ele));
|
dstset = setTypeCreate(szFromObj(ele));
|
||||||
dbAdd(c->db,c->argv[2],dstset);
|
dbAdd(c->db,c->argv[2],dstset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,7 +363,7 @@ void smoveCommand(client *c) {
|
|||||||
server.dirty++;
|
server.dirty++;
|
||||||
|
|
||||||
/* An extra key has changed when ele was successfully added to dstset */
|
/* An extra key has changed when ele was successfully added to dstset */
|
||||||
if (setTypeAdd(dstset,ptrFromObj(ele))) {
|
if (setTypeAdd(dstset,szFromObj(ele))) {
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
notifyKeyspaceEvent(NOTIFY_SET,"sadd",c->argv[2],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_SET,"sadd",c->argv[2],c->db->id);
|
||||||
}
|
}
|
||||||
@ -376,7 +376,7 @@ void sismemberCommand(client *c) {
|
|||||||
if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
|
if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
|
||||||
checkType(c,set,OBJ_SET)) return;
|
checkType(c,set,OBJ_SET)) return;
|
||||||
|
|
||||||
if (setTypeIsMember(set,ptrFromObj(c->argv[2])))
|
if (setTypeIsMember(set,szFromObj(c->argv[2])))
|
||||||
addReply(c,shared.cone);
|
addReply(c,shared.cone);
|
||||||
else
|
else
|
||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
@ -478,7 +478,7 @@ void spopWithCountCommand(client *c) {
|
|||||||
if (encoding == OBJ_ENCODING_INTSET) {
|
if (encoding == OBJ_ENCODING_INTSET) {
|
||||||
addReplyBulkLongLong(c,llele);
|
addReplyBulkLongLong(c,llele);
|
||||||
objele = createStringObjectFromLongLong(llele);
|
objele = createStringObjectFromLongLong(llele);
|
||||||
set->m_ptr = intsetRemove(set->m_ptr,llele,NULL);
|
set->m_ptr = intsetRemove((intset*)set->m_ptr,llele,NULL);
|
||||||
} else {
|
} else {
|
||||||
addReplyBulkCBuffer(c,sdsele,sdslen(sdsele));
|
addReplyBulkCBuffer(c,sdsele,sdslen(sdsele));
|
||||||
objele = createStringObject(sdsele,sdslen(sdsele));
|
objele = createStringObject(sdsele,sdslen(sdsele));
|
||||||
@ -575,10 +575,10 @@ void spopCommand(client *c) {
|
|||||||
/* Remove the element from the set */
|
/* Remove the element from the set */
|
||||||
if (encoding == OBJ_ENCODING_INTSET) {
|
if (encoding == OBJ_ENCODING_INTSET) {
|
||||||
ele = createStringObjectFromLongLong(llele);
|
ele = createStringObjectFromLongLong(llele);
|
||||||
set->m_ptr = intsetRemove(set->m_ptr,llele,NULL);
|
set->m_ptr = intsetRemove((intset*)set->m_ptr,llele,NULL);
|
||||||
} else {
|
} else {
|
||||||
ele = createStringObject(sdsele,sdslen(sdsele));
|
ele = createStringObject(sdsele,sdslen(sdsele));
|
||||||
setTypeRemove(set,ptrFromObj(ele));
|
setTypeRemove(set,szFromObj(ele));
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyKeyspaceEvent(NOTIFY_SET,"spop",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_SET,"spop",c->argv[1],c->db->id);
|
||||||
@ -740,7 +740,7 @@ void srandmemberWithCountCommand(client *c) {
|
|||||||
addReplySetLen(c,count);
|
addReplySetLen(c,count);
|
||||||
di = dictGetIterator(d);
|
di = dictGetIterator(d);
|
||||||
while((de = dictNext(di)) != NULL)
|
while((de = dictNext(di)) != NULL)
|
||||||
addReplyBulk(c,dictGetKey(de));
|
addReplyBulk(c,(robj*)dictGetKey(de));
|
||||||
dictReleaseIterator(di);
|
dictReleaseIterator(di);
|
||||||
dictRelease(d);
|
dictRelease(d);
|
||||||
}
|
}
|
||||||
@ -791,7 +791,7 @@ int qsortCompareSetsByRevCardinality(const void *s1, const void *s2) {
|
|||||||
|
|
||||||
void sinterGenericCommand(client *c, robj **setkeys,
|
void sinterGenericCommand(client *c, robj **setkeys,
|
||||||
unsigned long setnum, robj *dstkey) {
|
unsigned long setnum, robj *dstkey) {
|
||||||
robj **sets = zmalloc(sizeof(robj*)*setnum, MALLOC_SHARED);
|
robj **sets = (robj**)zmalloc(sizeof(robj*)*setnum, MALLOC_SHARED);
|
||||||
setTypeIterator *si;
|
setTypeIterator *si;
|
||||||
robj *dstset = NULL;
|
robj *dstset = NULL;
|
||||||
sds elesds;
|
sds elesds;
|
||||||
@ -930,7 +930,7 @@ void sinterstoreCommand(client *c) {
|
|||||||
|
|
||||||
void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
void sunionDiffGenericCommand(client *c, robj **setkeys, int setnum,
|
||||||
robj *dstkey, int op) {
|
robj *dstkey, int op) {
|
||||||
robj **sets = zmalloc(sizeof(robj*)*setnum, MALLOC_SHARED);
|
robj **sets = (robj**)zmalloc(sizeof(robj*)*setnum, MALLOC_SHARED);
|
||||||
setTypeIterator *si;
|
setTypeIterator *si;
|
||||||
robj *dstset = NULL;
|
robj *dstset = NULL;
|
||||||
sds ele;
|
sds ele;
|
@ -50,7 +50,7 @@ size_t streamReplyWithRangeFromConsumerPEL(client *c, stream *s, streamID *start
|
|||||||
|
|
||||||
/* Create a new stream data structure. */
|
/* Create a new stream data structure. */
|
||||||
stream *streamNew(void) {
|
stream *streamNew(void) {
|
||||||
stream *s = zmalloc(sizeof(*s), MALLOC_SHARED);
|
stream *s = (stream*)zmalloc(sizeof(*s), MALLOC_SHARED);
|
||||||
s->prax = raxNew();
|
s->prax = raxNew();
|
||||||
s->length = 0;
|
s->length = 0;
|
||||||
s->last_id.ms = 0;
|
s->last_id.ms = 0;
|
||||||
@ -187,7 +187,7 @@ int streamAppendItem(stream *s, robj **argv, int64_t numfields, streamID *added_
|
|||||||
|
|
||||||
/* Get a reference to the tail node listpack. */
|
/* Get a reference to the tail node listpack. */
|
||||||
if (raxNext(&ri)) {
|
if (raxNext(&ri)) {
|
||||||
lp = ri.data;
|
lp = (unsigned char*)ri.data;
|
||||||
lp_bytes = lpBytes(lp);
|
lp_bytes = lpBytes(lp);
|
||||||
}
|
}
|
||||||
raxStop(&ri);
|
raxStop(&ri);
|
||||||
@ -261,7 +261,7 @@ int streamAppendItem(stream *s, robj **argv, int64_t numfields, streamID *added_
|
|||||||
lp = lpAppendInteger(lp,0); /* Zero deleted so far. */
|
lp = lpAppendInteger(lp,0); /* Zero deleted so far. */
|
||||||
lp = lpAppendInteger(lp,numfields);
|
lp = lpAppendInteger(lp,numfields);
|
||||||
for (int64_t i = 0; i < numfields; i++) {
|
for (int64_t i = 0; i < numfields; i++) {
|
||||||
sds field = ptrFromObj(argv[i*2]);
|
sds field = szFromObj(argv[i*2]);
|
||||||
lp = lpAppend(lp,(unsigned char*)field,sdslen(field));
|
lp = lpAppend(lp,(unsigned char*)field,sdslen(field));
|
||||||
}
|
}
|
||||||
lp = lpAppendInteger(lp,0); /* Master entry zero terminator. */
|
lp = lpAppendInteger(lp,0); /* Master entry zero terminator. */
|
||||||
@ -290,7 +290,7 @@ int streamAppendItem(stream *s, robj **argv, int64_t numfields, streamID *added_
|
|||||||
if (numfields == master_fields_count) {
|
if (numfields == master_fields_count) {
|
||||||
int64_t i;
|
int64_t i;
|
||||||
for (i = 0; i < master_fields_count; i++) {
|
for (i = 0; i < master_fields_count; i++) {
|
||||||
sds field = ptrFromObj(argv[i*2]);
|
sds field = szFromObj(argv[i*2]);
|
||||||
int64_t e_len;
|
int64_t e_len;
|
||||||
unsigned char buf[LP_INTBUF_SIZE];
|
unsigned char buf[LP_INTBUF_SIZE];
|
||||||
unsigned char *e = lpGet(lp_ele,&e_len,buf);
|
unsigned char *e = lpGet(lp_ele,&e_len,buf);
|
||||||
@ -333,7 +333,7 @@ int streamAppendItem(stream *s, robj **argv, int64_t numfields, streamID *added_
|
|||||||
if (!(flags & STREAM_ITEM_FLAG_SAMEFIELDS))
|
if (!(flags & STREAM_ITEM_FLAG_SAMEFIELDS))
|
||||||
lp = lpAppendInteger(lp,numfields);
|
lp = lpAppendInteger(lp,numfields);
|
||||||
for (int64_t i = 0; i < numfields; i++) {
|
for (int64_t i = 0; i < numfields; i++) {
|
||||||
sds field = ptrFromObj(argv[i*2]), value = ptrFromObj(argv[i*2+1]);
|
sds field = szFromObj(argv[i*2]), value = szFromObj(argv[i*2+1]);
|
||||||
if (!(flags & STREAM_ITEM_FLAG_SAMEFIELDS))
|
if (!(flags & STREAM_ITEM_FLAG_SAMEFIELDS))
|
||||||
lp = lpAppend(lp,(unsigned char*)field,sdslen(field));
|
lp = lpAppend(lp,(unsigned char*)field,sdslen(field));
|
||||||
lp = lpAppend(lp,(unsigned char*)value,sdslen(value));
|
lp = lpAppend(lp,(unsigned char*)value,sdslen(value));
|
||||||
@ -380,7 +380,7 @@ int64_t streamTrimByLength(stream *s, size_t maxlen, int approx) {
|
|||||||
|
|
||||||
int64_t deleted = 0;
|
int64_t deleted = 0;
|
||||||
while(s->length > maxlen && raxNext(&ri)) {
|
while(s->length > maxlen && raxNext(&ri)) {
|
||||||
unsigned char *lp = ri.data, *p = lpFirst(lp);
|
unsigned char *lp = (unsigned char*)ri.data, *p = lpFirst(lp);
|
||||||
int64_t entries = lpGetInteger(p);
|
int64_t entries = lpGetInteger(p);
|
||||||
|
|
||||||
/* Check if we can remove the whole node, and still have at
|
/* Check if we can remove the whole node, and still have at
|
||||||
@ -542,7 +542,7 @@ int streamIteratorGetID(streamIterator *si, streamID *id, int64_t *numfields) {
|
|||||||
/* Get the master ID. */
|
/* Get the master ID. */
|
||||||
streamDecodeID(si->ri.key,&si->master_id);
|
streamDecodeID(si->ri.key,&si->master_id);
|
||||||
/* Get the master fields count. */
|
/* Get the master fields count. */
|
||||||
si->lp = si->ri.data;
|
si->lp = (unsigned char*)si->ri.data;
|
||||||
si->lp_ele = lpFirst(si->lp); /* Seek items count */
|
si->lp_ele = lpFirst(si->lp); /* Seek items count */
|
||||||
si->lp_ele = lpNext(si->lp,si->lp_ele); /* Seek deleted count. */
|
si->lp_ele = lpNext(si->lp,si->lp_ele); /* Seek deleted count. */
|
||||||
si->lp_ele = lpNext(si->lp,si->lp_ele); /* Seek num fields. */
|
si->lp_ele = lpNext(si->lp,si->lp_ele); /* Seek num fields. */
|
||||||
@ -971,7 +971,7 @@ size_t streamReplyWithRange(client *c, stream *s, streamID *start, streamID *end
|
|||||||
* or update it if the consumer is the same as before. */
|
* or update it if the consumer is the same as before. */
|
||||||
if (group_inserted == 0) {
|
if (group_inserted == 0) {
|
||||||
streamFreeNACK(nack);
|
streamFreeNACK(nack);
|
||||||
nack = raxFind(group->pel,buf,sizeof(buf));
|
nack = (streamNACK*)raxFind(group->pel,buf,sizeof(buf));
|
||||||
serverAssert(nack != raxNotFound);
|
serverAssert(nack != raxNotFound);
|
||||||
raxRemove(nack->consumer->pel,buf,sizeof(buf),NULL);
|
raxRemove(nack->consumer->pel,buf,sizeof(buf),NULL);
|
||||||
/* Update the consumer and NACK metadata. */
|
/* Update the consumer and NACK metadata. */
|
||||||
@ -1044,7 +1044,7 @@ size_t streamReplyWithRangeFromConsumerPEL(client *c, stream *s, streamID *start
|
|||||||
addReplyStreamID(c,&id);
|
addReplyStreamID(c,&id);
|
||||||
addReplyNullArray(c);
|
addReplyNullArray(c);
|
||||||
} else {
|
} else {
|
||||||
streamNACK *nack = ri.data;
|
streamNACK *nack = (streamNACK*)ri.data;
|
||||||
nack->delivery_time = mstime();
|
nack->delivery_time = mstime();
|
||||||
nack->delivery_count++;
|
nack->delivery_count++;
|
||||||
}
|
}
|
||||||
@ -1109,8 +1109,9 @@ int string2ull(const char *s, unsigned long long *value) {
|
|||||||
* If 'c' is set to NULL, no reply is sent to the client. */
|
* If 'c' is set to NULL, no reply is sent to the client. */
|
||||||
int streamGenericParseIDOrReply(client *c, robj *o, streamID *id, uint64_t missing_seq, int strict) {
|
int streamGenericParseIDOrReply(client *c, robj *o, streamID *id, uint64_t missing_seq, int strict) {
|
||||||
char buf[128];
|
char buf[128];
|
||||||
if (sdslen(ptrFromObj(o)) > sizeof(buf)-1) goto invalid;
|
char *dot = nullptr;
|
||||||
memcpy(buf,ptrFromObj(o),sdslen(ptrFromObj(o))+1);
|
if (sdslen(szFromObj(o)) > sizeof(buf)-1) goto invalid;
|
||||||
|
memcpy(buf,ptrFromObj(o),sdslen(szFromObj(o))+1);
|
||||||
|
|
||||||
if (strict && (buf[0] == '-' || buf[0] == '+') && buf[1] == '\0')
|
if (strict && (buf[0] == '-' || buf[0] == '+') && buf[1] == '\0')
|
||||||
goto invalid;
|
goto invalid;
|
||||||
@ -1127,7 +1128,7 @@ int streamGenericParseIDOrReply(client *c, robj *o, streamID *id, uint64_t missi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse <ms>-<seq> form. */
|
/* Parse <ms>-<seq> form. */
|
||||||
char *dot = strchr(buf,'-');
|
dot = strchr(buf,'-');
|
||||||
if (dot) *dot = '\0';
|
if (dot) *dot = '\0';
|
||||||
unsigned long long ms, seq;
|
unsigned long long ms, seq;
|
||||||
if (string2ull(buf,&ms) == 0) goto invalid;
|
if (string2ull(buf,&ms) == 0) goto invalid;
|
||||||
@ -1183,14 +1184,14 @@ void xaddCommand(client *c) {
|
|||||||
find an option, or the ID. */
|
find an option, or the ID. */
|
||||||
for (; i < c->argc; i++) {
|
for (; i < c->argc; i++) {
|
||||||
int moreargs = (c->argc-1) - i; /* Number of additional arguments. */
|
int moreargs = (c->argc-1) - i; /* Number of additional arguments. */
|
||||||
char *opt = ptrFromObj(c->argv[i]);
|
char *opt = szFromObj(c->argv[i]);
|
||||||
if (opt[0] == '*' && opt[1] == '\0') {
|
if (opt[0] == '*' && opt[1] == '\0') {
|
||||||
/* This is just a fast path for the common case of auto-ID
|
/* This is just a fast path for the common case of auto-ID
|
||||||
* creation. */
|
* creation. */
|
||||||
break;
|
break;
|
||||||
} else if (!strcasecmp(opt,"maxlen") && moreargs) {
|
} else if (!strcasecmp(opt,"maxlen") && moreargs) {
|
||||||
approx_maxlen = 0;
|
approx_maxlen = 0;
|
||||||
char *next = ptrFromObj(c->argv[i+1]);
|
char *next = szFromObj(c->argv[i+1]);
|
||||||
/* Check for the form MAXLEN ~ <count>. */
|
/* Check for the form MAXLEN ~ <count>. */
|
||||||
if (moreargs >= 2 && next[0] == '~' && next[1] == '\0') {
|
if (moreargs >= 2 && next[0] == '~' && next[1] == '\0') {
|
||||||
approx_maxlen = 1;
|
approx_maxlen = 1;
|
||||||
@ -1226,7 +1227,7 @@ void xaddCommand(client *c) {
|
|||||||
robj *o;
|
robj *o;
|
||||||
stream *s;
|
stream *s;
|
||||||
if ((o = streamTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
|
if ((o = streamTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
|
||||||
s = ptrFromObj(o);
|
s = (stream*)ptrFromObj(o);
|
||||||
|
|
||||||
/* Append using the low level function and return the ID. */
|
/* Append using the low level function and return the ID. */
|
||||||
if (streamAppendItem(s,c->argv+field_pos,(c->argc-field_pos)/2,
|
if (streamAppendItem(s,c->argv+field_pos,(c->argc-field_pos)/2,
|
||||||
@ -1279,7 +1280,7 @@ void xrangeGenericCommand(client *c, int rev) {
|
|||||||
if (c->argc > 4) {
|
if (c->argc > 4) {
|
||||||
for (int j = 4; j < c->argc; j++) {
|
for (int j = 4; j < c->argc; j++) {
|
||||||
int additional = c->argc-j-1;
|
int additional = c->argc-j-1;
|
||||||
if (strcasecmp(ptrFromObj(c->argv[j]),"COUNT") == 0 && additional >= 1) {
|
if (strcasecmp(szFromObj(c->argv[j]),"COUNT") == 0 && additional >= 1) {
|
||||||
if (getLongLongFromObjectOrReply(c,c->argv[j+1],&count,NULL)
|
if (getLongLongFromObjectOrReply(c,c->argv[j+1],&count,NULL)
|
||||||
!= C_OK) return;
|
!= C_OK) return;
|
||||||
if (count < 0) count = 0;
|
if (count < 0) count = 0;
|
||||||
@ -1295,7 +1296,7 @@ void xrangeGenericCommand(client *c, int rev) {
|
|||||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptyarray)) == NULL ||
|
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptyarray)) == NULL ||
|
||||||
checkType(c,o,OBJ_STREAM)) return;
|
checkType(c,o,OBJ_STREAM)) return;
|
||||||
|
|
||||||
s = ptrFromObj(o);
|
s = (stream*)ptrFromObj(o);
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
addReplyNullArray(c);
|
addReplyNullArray(c);
|
||||||
@ -1320,7 +1321,7 @@ void xlenCommand(client *c) {
|
|||||||
robj *o;
|
robj *o;
|
||||||
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL
|
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL
|
||||||
|| checkType(c,o,OBJ_STREAM)) return;
|
|| checkType(c,o,OBJ_STREAM)) return;
|
||||||
stream *s = ptrFromObj(o);
|
stream *s = (stream*)ptrFromObj(o);
|
||||||
addReplyLongLong(c,s->length);
|
addReplyLongLong(c,s->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1342,14 +1343,16 @@ void xreadCommand(client *c) {
|
|||||||
streamID static_ids[STREAMID_STATIC_VECTOR_LEN];
|
streamID static_ids[STREAMID_STATIC_VECTOR_LEN];
|
||||||
streamID *ids = static_ids;
|
streamID *ids = static_ids;
|
||||||
streamCG **groups = NULL;
|
streamCG **groups = NULL;
|
||||||
int xreadgroup = sdslen(ptrFromObj(c->argv[0])) == 10; /* XREAD or XREADGROUP? */
|
int xreadgroup = sdslen(szFromObj(c->argv[0])) == 10; /* XREAD or XREADGROUP? */
|
||||||
robj *groupname = NULL;
|
robj *groupname = NULL;
|
||||||
robj *consumername = NULL;
|
robj *consumername = NULL;
|
||||||
|
size_t arraylen = 0;
|
||||||
|
void *arraylen_ptr = NULL;
|
||||||
|
|
||||||
/* Parse arguments. */
|
/* Parse arguments. */
|
||||||
for (int i = 1; i < c->argc; i++) {
|
for (int i = 1; i < c->argc; i++) {
|
||||||
int moreargs = c->argc-i-1;
|
int moreargs = c->argc-i-1;
|
||||||
char *o = ptrFromObj(c->argv[i]);
|
char *o = szFromObj(c->argv[i]);
|
||||||
if (!strcasecmp(o,"BLOCK") && moreargs) {
|
if (!strcasecmp(o,"BLOCK") && moreargs) {
|
||||||
i++;
|
i++;
|
||||||
if (getTimeoutFromObjectOrReply(c,c->argv[i],&timeout,
|
if (getTimeoutFromObjectOrReply(c,c->argv[i],&timeout,
|
||||||
@ -1407,8 +1410,8 @@ void xreadCommand(client *c) {
|
|||||||
|
|
||||||
/* Parse the IDs and resolve the group name. */
|
/* Parse the IDs and resolve the group name. */
|
||||||
if (streams_count > STREAMID_STATIC_VECTOR_LEN)
|
if (streams_count > STREAMID_STATIC_VECTOR_LEN)
|
||||||
ids = zmalloc(sizeof(streamID)*streams_count, MALLOC_SHARED);
|
ids = (streamID*)zmalloc(sizeof(streamID)*streams_count, MALLOC_SHARED);
|
||||||
if (groupname) groups = zmalloc(sizeof(streamCG*)*streams_count, MALLOC_SHARED);
|
if (groupname) groups = (streamCG**)zmalloc(sizeof(streamCG*)*streams_count, MALLOC_SHARED);
|
||||||
|
|
||||||
for (int i = streams_arg + streams_count; i < c->argc; i++) {
|
for (int i = streams_arg + streams_count; i < c->argc; i++) {
|
||||||
/* Specifying "$" as last-known-id means that the client wants to be
|
/* Specifying "$" as last-known-id means that the client wants to be
|
||||||
@ -1424,7 +1427,7 @@ void xreadCommand(client *c) {
|
|||||||
* key and group actually exist. */
|
* key and group actually exist. */
|
||||||
if (groupname) {
|
if (groupname) {
|
||||||
if (o == NULL ||
|
if (o == NULL ||
|
||||||
(group = streamLookupCG(ptrFromObj(o),ptrFromObj(groupname))) == NULL)
|
(group = streamLookupCG((stream*)ptrFromObj(o),szFromObj(groupname))) == NULL)
|
||||||
{
|
{
|
||||||
addReplyErrorFormat(c, "-NOGROUP No such key '%s' or consumer "
|
addReplyErrorFormat(c, "-NOGROUP No such key '%s' or consumer "
|
||||||
"group '%s' in XREADGROUP with GROUP "
|
"group '%s' in XREADGROUP with GROUP "
|
||||||
@ -1435,7 +1438,7 @@ void xreadCommand(client *c) {
|
|||||||
groups[id_idx] = group;
|
groups[id_idx] = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(ptrFromObj(c->argv[i]),"$") == 0) {
|
if (strcmp(szFromObj(c->argv[i]),"$") == 0) {
|
||||||
if (xreadgroup) {
|
if (xreadgroup) {
|
||||||
addReplyError(c,"The $ ID is meaningless in the context of "
|
addReplyError(c,"The $ ID is meaningless in the context of "
|
||||||
"XREADGROUP: you want to read the history of "
|
"XREADGROUP: you want to read the history of "
|
||||||
@ -1445,14 +1448,14 @@ void xreadCommand(client *c) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (o) {
|
if (o) {
|
||||||
stream *s = ptrFromObj(o);
|
stream *s = (stream*)ptrFromObj(o);
|
||||||
ids[id_idx] = s->last_id;
|
ids[id_idx] = s->last_id;
|
||||||
} else {
|
} else {
|
||||||
ids[id_idx].ms = 0;
|
ids[id_idx].ms = 0;
|
||||||
ids[id_idx].seq = 0;
|
ids[id_idx].seq = 0;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else if (strcmp(ptrFromObj(c->argv[i]),">") == 0) {
|
} else if (strcmp(szFromObj(c->argv[i]),">") == 0) {
|
||||||
if (!xreadgroup) {
|
if (!xreadgroup) {
|
||||||
addReplyError(c,"The > ID can be specified only when calling "
|
addReplyError(c,"The > ID can be specified only when calling "
|
||||||
"XREADGROUP using the GROUP <group> "
|
"XREADGROUP using the GROUP <group> "
|
||||||
@ -1471,12 +1474,10 @@ void xreadCommand(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Try to serve the client synchronously. */
|
/* Try to serve the client synchronously. */
|
||||||
size_t arraylen = 0;
|
|
||||||
void *arraylen_ptr = NULL;
|
|
||||||
for (int i = 0; i < streams_count; i++) {
|
for (int i = 0; i < streams_count; i++) {
|
||||||
robj *o = lookupKeyRead(c->db,c->argv[streams_arg+i]);
|
robj *o = lookupKeyRead(c->db,c->argv[streams_arg+i]);
|
||||||
if (o == NULL) continue;
|
if (o == NULL) continue;
|
||||||
stream *s = ptrFromObj(o);
|
stream *s = (stream*)ptrFromObj(o);
|
||||||
streamID *gt = ids+i; /* ID must be greater than this. */
|
streamID *gt = ids+i; /* ID must be greater than this. */
|
||||||
int serve_synchronously = 0;
|
int serve_synchronously = 0;
|
||||||
int serve_history = 0; /* True for XREADGROUP with ID != ">". */
|
int serve_history = 0; /* True for XREADGROUP with ID != ">". */
|
||||||
@ -1525,7 +1526,7 @@ void xreadCommand(client *c) {
|
|||||||
addReplyBulk(c,c->argv[streams_arg+i]);
|
addReplyBulk(c,c->argv[streams_arg+i]);
|
||||||
streamConsumer *consumer = NULL;
|
streamConsumer *consumer = NULL;
|
||||||
if (groups) consumer = streamLookupConsumer(groups[i],
|
if (groups) consumer = streamLookupConsumer(groups[i],
|
||||||
ptrFromObj(consumername),1);
|
szFromObj(consumername),1);
|
||||||
streamPropInfo spi = {c->argv[i+streams_arg],groupname};
|
streamPropInfo spi = {c->argv[i+streams_arg],groupname};
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if (noack) flags |= STREAM_RWR_NOACK;
|
if (noack) flags |= STREAM_RWR_NOACK;
|
||||||
@ -1600,7 +1601,7 @@ cleanup: /* Cleanup. */
|
|||||||
* time to the current time. The NACK consumer will be set to the one
|
* time to the current time. The NACK consumer will be set to the one
|
||||||
* specified as argument of the function. */
|
* specified as argument of the function. */
|
||||||
streamNACK *streamCreateNACK(streamConsumer *consumer) {
|
streamNACK *streamCreateNACK(streamConsumer *consumer) {
|
||||||
streamNACK *nack = zmalloc(sizeof(*nack), MALLOC_SHARED);
|
streamNACK *nack = (streamNACK*)zmalloc(sizeof(*nack), MALLOC_SHARED);
|
||||||
nack->delivery_time = mstime();
|
nack->delivery_time = mstime();
|
||||||
nack->delivery_count = 1;
|
nack->delivery_count = 1;
|
||||||
nack->consumer = consumer;
|
nack->consumer = consumer;
|
||||||
@ -1633,7 +1634,7 @@ streamCG *streamCreateCG(stream *s, char *name, size_t namelen, streamID *id) {
|
|||||||
if (raxFind(s->cgroups,(unsigned char*)name,namelen) != raxNotFound)
|
if (raxFind(s->cgroups,(unsigned char*)name,namelen) != raxNotFound)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
streamCG *cg = zmalloc(sizeof(*cg), MALLOC_SHARED);
|
streamCG *cg = (streamCG*)zmalloc(sizeof(*cg), MALLOC_SHARED);
|
||||||
cg->pel = raxNew();
|
cg->pel = raxNew();
|
||||||
cg->consumers = raxNew();
|
cg->consumers = raxNew();
|
||||||
cg->last_id = *id;
|
cg->last_id = *id;
|
||||||
@ -1652,7 +1653,7 @@ void streamFreeCG(streamCG *cg) {
|
|||||||
* pointer, otherwise if there is no such group, NULL is returned. */
|
* pointer, otherwise if there is no such group, NULL is returned. */
|
||||||
streamCG *streamLookupCG(stream *s, sds groupname) {
|
streamCG *streamLookupCG(stream *s, sds groupname) {
|
||||||
if (s->cgroups == NULL) return NULL;
|
if (s->cgroups == NULL) return NULL;
|
||||||
streamCG *cg = raxFind(s->cgroups,(unsigned char*)groupname,
|
streamCG *cg = (streamCG*)raxFind(s->cgroups,(unsigned char*)groupname,
|
||||||
sdslen(groupname));
|
sdslen(groupname));
|
||||||
return (cg == raxNotFound) ? NULL : cg;
|
return (cg == raxNotFound) ? NULL : cg;
|
||||||
}
|
}
|
||||||
@ -1662,11 +1663,11 @@ streamCG *streamLookupCG(stream *s, sds groupname) {
|
|||||||
* of calling this function, otherwise its last seen time is updated and
|
* of calling this function, otherwise its last seen time is updated and
|
||||||
* the existing consumer reference returned. */
|
* the existing consumer reference returned. */
|
||||||
streamConsumer *streamLookupConsumer(streamCG *cg, sds name, int create) {
|
streamConsumer *streamLookupConsumer(streamCG *cg, sds name, int create) {
|
||||||
streamConsumer *consumer = raxFind(cg->consumers,(unsigned char*)name,
|
streamConsumer *consumer = (streamConsumer*)raxFind(cg->consumers,(unsigned char*)name,
|
||||||
sdslen(name));
|
sdslen(name));
|
||||||
if (consumer == raxNotFound) {
|
if (consumer == raxNotFound) {
|
||||||
if (!create) return NULL;
|
if (!create) return NULL;
|
||||||
consumer = zmalloc(sizeof(*consumer), MALLOC_SHARED);
|
consumer = (streamConsumer*)zmalloc(sizeof(*consumer), MALLOC_SHARED);
|
||||||
consumer->name = sdsdup(name);
|
consumer->name = sdsdup(name);
|
||||||
consumer->pel = raxNew();
|
consumer->pel = raxNew();
|
||||||
raxInsert(cg->consumers,(unsigned char*)name,sdslen(name),
|
raxInsert(cg->consumers,(unsigned char*)name,sdslen(name),
|
||||||
@ -1691,7 +1692,7 @@ uint64_t streamDelConsumer(streamCG *cg, sds name) {
|
|||||||
raxStart(&ri,consumer->pel);
|
raxStart(&ri,consumer->pel);
|
||||||
raxSeek(&ri,"^",NULL,0);
|
raxSeek(&ri,"^",NULL,0);
|
||||||
while(raxNext(&ri)) {
|
while(raxNext(&ri)) {
|
||||||
streamNACK *nack = ri.data;
|
streamNACK *nack = (streamNACK*)ri.data;
|
||||||
raxRemove(cg->pel,ri.key,ri.key_len,NULL);
|
raxRemove(cg->pel,ri.key,ri.key_len,NULL);
|
||||||
streamFreeNACK(nack);
|
streamFreeNACK(nack);
|
||||||
}
|
}
|
||||||
@ -1724,19 +1725,19 @@ NULL
|
|||||||
stream *s = NULL;
|
stream *s = NULL;
|
||||||
sds grpname = NULL;
|
sds grpname = NULL;
|
||||||
streamCG *cg = NULL;
|
streamCG *cg = NULL;
|
||||||
char *opt = ptrFromObj(c->argv[1]); /* Subcommand name. */
|
char *opt = szFromObj(c->argv[1]); /* Subcommand name. */
|
||||||
int mkstream = 0;
|
int mkstream = 0;
|
||||||
robj *o;
|
robj *o;
|
||||||
|
|
||||||
/* CREATE has an MKSTREAM option that creates the stream if it
|
/* CREATE has an MKSTREAM option that creates the stream if it
|
||||||
* does not exist. */
|
* does not exist. */
|
||||||
if (c->argc == 6 && !strcasecmp(opt,"CREATE")) {
|
if (c->argc == 6 && !strcasecmp(opt,"CREATE")) {
|
||||||
if (strcasecmp(ptrFromObj(c->argv[5]),"MKSTREAM")) {
|
if (strcasecmp(szFromObj(c->argv[5]),"MKSTREAM")) {
|
||||||
addReplySubcommandSyntaxError(c);
|
addReplySubcommandSyntaxError(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mkstream = 1;
|
mkstream = 1;
|
||||||
grpname = ptrFromObj(c->argv[3]);
|
grpname = szFromObj(c->argv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Everything but the "HELP" option requires a key and group name. */
|
/* Everything but the "HELP" option requires a key and group name. */
|
||||||
@ -1746,7 +1747,7 @@ NULL
|
|||||||
if (checkType(c,o,OBJ_STREAM)) return;
|
if (checkType(c,o,OBJ_STREAM)) return;
|
||||||
s = (stream*)ptrFromObj(o);
|
s = (stream*)ptrFromObj(o);
|
||||||
}
|
}
|
||||||
grpname = ptrFromObj(c->argv[3]);
|
grpname = szFromObj(c->argv[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for missing key/group. */
|
/* Check for missing key/group. */
|
||||||
@ -1775,7 +1776,7 @@ NULL
|
|||||||
/* Dispatch the different subcommands. */
|
/* Dispatch the different subcommands. */
|
||||||
if (!strcasecmp(opt,"CREATE") && (c->argc == 5 || c->argc == 6)) {
|
if (!strcasecmp(opt,"CREATE") && (c->argc == 5 || c->argc == 6)) {
|
||||||
streamID id;
|
streamID id;
|
||||||
if (!strcmp(ptrFromObj(c->argv[4]),"$")) {
|
if (!strcmp(szFromObj(c->argv[4]),"$")) {
|
||||||
if (s) {
|
if (s) {
|
||||||
id = s->last_id;
|
id = s->last_id;
|
||||||
} else {
|
} else {
|
||||||
@ -1791,7 +1792,7 @@ NULL
|
|||||||
serverAssert(mkstream);
|
serverAssert(mkstream);
|
||||||
o = createStreamObject();
|
o = createStreamObject();
|
||||||
dbAdd(c->db,c->argv[2],o);
|
dbAdd(c->db,c->argv[2],o);
|
||||||
s = ptrFromObj(o);
|
s = (stream*)ptrFromObj(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
streamCG *cg = streamCreateCG(s,grpname,sdslen(grpname),&id);
|
streamCG *cg = streamCreateCG(s,grpname,sdslen(grpname),&id);
|
||||||
@ -1806,7 +1807,7 @@ NULL
|
|||||||
}
|
}
|
||||||
} else if (!strcasecmp(opt,"SETID") && c->argc == 5) {
|
} else if (!strcasecmp(opt,"SETID") && c->argc == 5) {
|
||||||
streamID id;
|
streamID id;
|
||||||
if (!strcmp(ptrFromObj(c->argv[4]),"$")) {
|
if (!strcmp(szFromObj(c->argv[4]),"$")) {
|
||||||
id = s->last_id;
|
id = s->last_id;
|
||||||
} else if (streamParseIDOrReply(c,c->argv[4],&id,0) != C_OK) {
|
} else if (streamParseIDOrReply(c,c->argv[4],&id,0) != C_OK) {
|
||||||
return;
|
return;
|
||||||
@ -1829,7 +1830,7 @@ NULL
|
|||||||
} else if (!strcasecmp(opt,"DELCONSUMER") && c->argc == 5) {
|
} else if (!strcasecmp(opt,"DELCONSUMER") && c->argc == 5) {
|
||||||
/* Delete the consumer and returns the number of pending messages
|
/* Delete the consumer and returns the number of pending messages
|
||||||
* that were yet associated with such a consumer. */
|
* that were yet associated with such a consumer. */
|
||||||
long long pending = streamDelConsumer(cg,ptrFromObj(c->argv[4]));
|
long long pending = streamDelConsumer(cg,szFromObj(c->argv[4]));
|
||||||
addReplyLongLong(c,pending);
|
addReplyLongLong(c,pending);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
notifyKeyspaceEvent(NOTIFY_STREAM,"xgroup-delconsumer",
|
notifyKeyspaceEvent(NOTIFY_STREAM,"xgroup-delconsumer",
|
||||||
@ -1848,7 +1849,7 @@ void xsetidCommand(client *c) {
|
|||||||
robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr);
|
robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr);
|
||||||
if (o == NULL || checkType(c,o,OBJ_STREAM)) return;
|
if (o == NULL || checkType(c,o,OBJ_STREAM)) return;
|
||||||
|
|
||||||
stream *s = ptrFromObj(o);
|
stream *s = (stream*)ptrFromObj(o);
|
||||||
streamID id;
|
streamID id;
|
||||||
if (streamParseStrictIDOrReply(c,c->argv[2],&id,0) != C_OK) return;
|
if (streamParseStrictIDOrReply(c,c->argv[2],&id,0) != C_OK) return;
|
||||||
|
|
||||||
@ -1889,7 +1890,7 @@ void xackCommand(client *c) {
|
|||||||
robj *o = lookupKeyRead(c->db,c->argv[1]);
|
robj *o = lookupKeyRead(c->db,c->argv[1]);
|
||||||
if (o) {
|
if (o) {
|
||||||
if (checkType(c,o,OBJ_STREAM)) return; /* Type error. */
|
if (checkType(c,o,OBJ_STREAM)) return; /* Type error. */
|
||||||
group = streamLookupCG(ptrFromObj(o),ptrFromObj(c->argv[2]));
|
group = streamLookupCG((stream*)ptrFromObj(o),szFromObj(c->argv[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No key or group? Nothing to ack. */
|
/* No key or group? Nothing to ack. */
|
||||||
@ -1908,7 +1909,7 @@ void xackCommand(client *c) {
|
|||||||
/* Lookup the ID in the group PEL: it will have a reference to the
|
/* Lookup the ID in the group PEL: it will have a reference to the
|
||||||
* NACK structure that will have a reference to the consumer, so that
|
* NACK structure that will have a reference to the consumer, so that
|
||||||
* we are able to remove the entry from both PELs. */
|
* we are able to remove the entry from both PELs. */
|
||||||
streamNACK *nack = raxFind(group->pel,buf,sizeof(buf));
|
streamNACK *nack = (streamNACK*)raxFind(group->pel,buf,sizeof(buf));
|
||||||
if (nack != raxNotFound) {
|
if (nack != raxNotFound) {
|
||||||
raxRemove(group->pel,buf,sizeof(buf),NULL);
|
raxRemove(group->pel,buf,sizeof(buf),NULL);
|
||||||
raxRemove(nack->consumer->pel,buf,sizeof(buf),NULL);
|
raxRemove(nack->consumer->pel,buf,sizeof(buf),NULL);
|
||||||
@ -1962,7 +1963,7 @@ void xpendingCommand(client *c) {
|
|||||||
|
|
||||||
if (o && checkType(c,o,OBJ_STREAM)) return;
|
if (o && checkType(c,o,OBJ_STREAM)) return;
|
||||||
if (o == NULL ||
|
if (o == NULL ||
|
||||||
(group = streamLookupCG(ptrFromObj(o),ptrFromObj(groupname))) == NULL)
|
(group = streamLookupCG((stream*)ptrFromObj(o),szFromObj(groupname))) == NULL)
|
||||||
{
|
{
|
||||||
addReplyErrorFormat(c, "-NOGROUP No such key '%s' or consumer "
|
addReplyErrorFormat(c, "-NOGROUP No such key '%s' or consumer "
|
||||||
"group '%s'",
|
"group '%s'",
|
||||||
@ -2002,7 +2003,7 @@ void xpendingCommand(client *c) {
|
|||||||
void *arraylen_ptr = addReplyDeferredLen(c);
|
void *arraylen_ptr = addReplyDeferredLen(c);
|
||||||
size_t arraylen = 0;
|
size_t arraylen = 0;
|
||||||
while(raxNext(&ri)) {
|
while(raxNext(&ri)) {
|
||||||
streamConsumer *consumer = ri.data;
|
streamConsumer *consumer = (streamConsumer*)ri.data;
|
||||||
if (raxSize(consumer->pel) == 0) continue;
|
if (raxSize(consumer->pel) == 0) continue;
|
||||||
addReplyArrayLen(c,2);
|
addReplyArrayLen(c,2);
|
||||||
addReplyBulkCBuffer(c,ri.key,ri.key_len);
|
addReplyBulkCBuffer(c,ri.key,ri.key_len);
|
||||||
@ -2016,7 +2017,7 @@ void xpendingCommand(client *c) {
|
|||||||
/* XPENDING <key> <group> <start> <stop> <count> [<consumer>] variant. */
|
/* XPENDING <key> <group> <start> <stop> <count> [<consumer>] variant. */
|
||||||
else {
|
else {
|
||||||
streamConsumer *consumer = consumername ?
|
streamConsumer *consumer = consumername ?
|
||||||
streamLookupConsumer(group,ptrFromObj(consumername),0):
|
streamLookupConsumer(group,szFromObj(consumername),0):
|
||||||
NULL;
|
NULL;
|
||||||
|
|
||||||
/* If a consumer name was mentioned but it does not exist, we can
|
/* If a consumer name was mentioned but it does not exist, we can
|
||||||
@ -2040,7 +2041,7 @@ void xpendingCommand(client *c) {
|
|||||||
size_t arraylen = 0;
|
size_t arraylen = 0;
|
||||||
|
|
||||||
while(count && raxNext(&ri) && memcmp(ri.key,endkey,ri.key_len) <= 0) {
|
while(count && raxNext(&ri) && memcmp(ri.key,endkey,ri.key_len) <= 0) {
|
||||||
streamNACK *nack = ri.data;
|
streamNACK *nack = (streamNACK*)ri.data;
|
||||||
|
|
||||||
arraylen++;
|
arraylen++;
|
||||||
count--;
|
count--;
|
||||||
@ -2145,7 +2146,7 @@ void xclaimCommand(client *c) {
|
|||||||
|
|
||||||
if (o) {
|
if (o) {
|
||||||
if (checkType(c,o,OBJ_STREAM)) return; /* Type error. */
|
if (checkType(c,o,OBJ_STREAM)) return; /* Type error. */
|
||||||
group = streamLookupCG(ptrFromObj(o),ptrFromObj(c->argv[2]));
|
group = streamLookupCG((stream*)ptrFromObj(o),szFromObj(c->argv[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No key or group? Send an error given that the group creation
|
/* No key or group? Send an error given that the group creation
|
||||||
@ -2180,7 +2181,7 @@ void xclaimCommand(client *c) {
|
|||||||
int propagate_last_id = 0;
|
int propagate_last_id = 0;
|
||||||
for (; j < c->argc; j++) {
|
for (; j < c->argc; j++) {
|
||||||
int moreargs = (c->argc-1) - j; /* Number of additional arguments. */
|
int moreargs = (c->argc-1) - j; /* Number of additional arguments. */
|
||||||
char *opt = ptrFromObj(c->argv[j]);
|
char *opt = szFromObj(c->argv[j]);
|
||||||
if (!strcasecmp(opt,"FORCE")) {
|
if (!strcasecmp(opt,"FORCE")) {
|
||||||
force = 1;
|
force = 1;
|
||||||
} else if (!strcasecmp(opt,"JUSTID")) {
|
} else if (!strcasecmp(opt,"JUSTID")) {
|
||||||
@ -2232,7 +2233,7 @@ void xclaimCommand(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do the actual claiming. */
|
/* Do the actual claiming. */
|
||||||
streamConsumer *consumer = streamLookupConsumer(group,ptrFromObj(c->argv[3]),1);
|
streamConsumer *consumer = streamLookupConsumer(group,szFromObj(c->argv[3]),1);
|
||||||
void *arraylenptr = addReplyDeferredLen(c);
|
void *arraylenptr = addReplyDeferredLen(c);
|
||||||
size_t arraylen = 0;
|
size_t arraylen = 0;
|
||||||
for (int j = 5; j <= last_id_arg; j++) {
|
for (int j = 5; j <= last_id_arg; j++) {
|
||||||
@ -2243,7 +2244,7 @@ void xclaimCommand(client *c) {
|
|||||||
streamEncodeID(buf,&id);
|
streamEncodeID(buf,&id);
|
||||||
|
|
||||||
/* Lookup the ID in the group PEL. */
|
/* Lookup the ID in the group PEL. */
|
||||||
streamNACK *nack = raxFind(group->pel,buf,sizeof(buf));
|
streamNACK *nack = (streamNACK*)raxFind(group->pel,buf,sizeof(buf));
|
||||||
|
|
||||||
/* If FORCE is passed, let's check if at least the entry
|
/* If FORCE is passed, let's check if at least the entry
|
||||||
* exists in the Stream. In such case, we'll crate a new
|
* exists in the Stream. In such case, we'll crate a new
|
||||||
@ -2252,7 +2253,7 @@ void xclaimCommand(client *c) {
|
|||||||
* and replication of consumer groups. */
|
* and replication of consumer groups. */
|
||||||
if (force && nack == raxNotFound) {
|
if (force && nack == raxNotFound) {
|
||||||
streamIterator myiterator;
|
streamIterator myiterator;
|
||||||
streamIteratorStart(&myiterator,ptrFromObj(o),&id,&id,0);
|
streamIteratorStart(&myiterator,(stream*)ptrFromObj(o),&id,&id,0);
|
||||||
int64_t numfields;
|
int64_t numfields;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
streamID item_id;
|
streamID item_id;
|
||||||
@ -2299,7 +2300,7 @@ void xclaimCommand(client *c) {
|
|||||||
if (justid) {
|
if (justid) {
|
||||||
addReplyStreamID(c,&id);
|
addReplyStreamID(c,&id);
|
||||||
} else {
|
} else {
|
||||||
size_t emitted = streamReplyWithRange(c,ptrFromObj(o),&id,&id,1,0,
|
size_t emitted = streamReplyWithRange(c,(stream*)ptrFromObj(o),&id,&id,1,0,
|
||||||
NULL,NULL,STREAM_RWR_RAWENTRIES,NULL);
|
NULL,NULL,STREAM_RWR_RAWENTRIES,NULL);
|
||||||
if (!emitted) addReplyNull(c);
|
if (!emitted) addReplyNull(c);
|
||||||
}
|
}
|
||||||
@ -2330,7 +2331,7 @@ void xdelCommand(client *c) {
|
|||||||
|
|
||||||
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL
|
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL
|
||||||
|| checkType(c,o,OBJ_STREAM)) return;
|
|| checkType(c,o,OBJ_STREAM)) return;
|
||||||
stream *s = ptrFromObj(o);
|
stream *s = (stream*)ptrFromObj(o);
|
||||||
|
|
||||||
/* We need to sanity check the IDs passed to start. Even if not
|
/* We need to sanity check the IDs passed to start. Even if not
|
||||||
* a big issue, it is not great that the command is only partially
|
* a big issue, it is not great that the command is only partially
|
||||||
@ -2375,7 +2376,7 @@ void xtrimCommand(client *c) {
|
|||||||
* number of elements removed from the stream. */
|
* number of elements removed from the stream. */
|
||||||
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL
|
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL
|
||||||
|| checkType(c,o,OBJ_STREAM)) return;
|
|| checkType(c,o,OBJ_STREAM)) return;
|
||||||
stream *s = ptrFromObj(o);
|
stream *s = (stream*)ptrFromObj(o);
|
||||||
|
|
||||||
/* Argument parsing. */
|
/* Argument parsing. */
|
||||||
int trim_strategy = TRIM_STRATEGY_NONE;
|
int trim_strategy = TRIM_STRATEGY_NONE;
|
||||||
@ -2388,11 +2389,11 @@ void xtrimCommand(client *c) {
|
|||||||
int i = 2; /* Start of options. */
|
int i = 2; /* Start of options. */
|
||||||
for (; i < c->argc; i++) {
|
for (; i < c->argc; i++) {
|
||||||
int moreargs = (c->argc-1) - i; /* Number of additional arguments. */
|
int moreargs = (c->argc-1) - i; /* Number of additional arguments. */
|
||||||
char *opt = ptrFromObj(c->argv[i]);
|
char *opt = szFromObj(c->argv[i]);
|
||||||
if (!strcasecmp(opt,"maxlen") && moreargs) {
|
if (!strcasecmp(opt,"maxlen") && moreargs) {
|
||||||
approx_maxlen = 0;
|
approx_maxlen = 0;
|
||||||
trim_strategy = TRIM_STRATEGY_MAXLEN;
|
trim_strategy = TRIM_STRATEGY_MAXLEN;
|
||||||
char *next = ptrFromObj(c->argv[i+1]);
|
char *next = szFromObj(c->argv[i+1]);
|
||||||
/* Check for the form MAXLEN ~ <count>. */
|
/* Check for the form MAXLEN ~ <count>. */
|
||||||
if (moreargs >= 2 && next[0] == '~' && next[1] == '\0') {
|
if (moreargs >= 2 && next[0] == '~' && next[1] == '\0') {
|
||||||
approx_maxlen = 1;
|
approx_maxlen = 1;
|
||||||
@ -2451,7 +2452,7 @@ NULL
|
|||||||
robj *key;
|
robj *key;
|
||||||
|
|
||||||
/* HELP is special. Handle it ASAP. */
|
/* HELP is special. Handle it ASAP. */
|
||||||
if (!strcasecmp(ptrFromObj(c->argv[1]),"HELP")) {
|
if (!strcasecmp(szFromObj(c->argv[1]),"HELP")) {
|
||||||
addReplyHelp(c, help);
|
addReplyHelp(c, help);
|
||||||
return;
|
return;
|
||||||
} else if (c->argc < 3) {
|
} else if (c->argc < 3) {
|
||||||
@ -2461,18 +2462,18 @@ NULL
|
|||||||
|
|
||||||
/* With the exception of HELP handled before any other sub commands, all
|
/* With the exception of HELP handled before any other sub commands, all
|
||||||
* the ones are in the form of "<subcommand> <key>". */
|
* the ones are in the form of "<subcommand> <key>". */
|
||||||
opt = ptrFromObj(c->argv[1]);
|
opt = szFromObj(c->argv[1]);
|
||||||
key = c->argv[2];
|
key = c->argv[2];
|
||||||
|
|
||||||
/* Lookup the key now, this is common for all the subcommands but HELP. */
|
/* Lookup the key now, this is common for all the subcommands but HELP. */
|
||||||
robj *o = lookupKeyWriteOrReply(c,key,shared.nokeyerr);
|
robj *o = lookupKeyWriteOrReply(c,key,shared.nokeyerr);
|
||||||
if (o == NULL || checkType(c,o,OBJ_STREAM)) return;
|
if (o == NULL || checkType(c,o,OBJ_STREAM)) return;
|
||||||
s = ptrFromObj(o);
|
s = (stream*)ptrFromObj(o);
|
||||||
|
|
||||||
/* Dispatch the different subcommands. */
|
/* Dispatch the different subcommands. */
|
||||||
if (!strcasecmp(opt,"CONSUMERS") && c->argc == 4) {
|
if (!strcasecmp(opt,"CONSUMERS") && c->argc == 4) {
|
||||||
/* XINFO CONSUMERS <key> <group>. */
|
/* XINFO CONSUMERS <key> <group>. */
|
||||||
streamCG *cg = streamLookupCG(s,ptrFromObj(c->argv[3]));
|
streamCG *cg = streamLookupCG(s,szFromObj(c->argv[3]));
|
||||||
if (cg == NULL) {
|
if (cg == NULL) {
|
||||||
addReplyErrorFormat(c, "-NOGROUP No such consumer group '%s' "
|
addReplyErrorFormat(c, "-NOGROUP No such consumer group '%s' "
|
||||||
"for key name '%s'",
|
"for key name '%s'",
|
||||||
@ -2486,7 +2487,7 @@ NULL
|
|||||||
raxSeek(&ri,"^",NULL,0);
|
raxSeek(&ri,"^",NULL,0);
|
||||||
mstime_t now = mstime();
|
mstime_t now = mstime();
|
||||||
while(raxNext(&ri)) {
|
while(raxNext(&ri)) {
|
||||||
streamConsumer *consumer = ri.data;
|
streamConsumer *consumer = (streamConsumer*)ri.data;
|
||||||
mstime_t idle = now - consumer->seen_time;
|
mstime_t idle = now - consumer->seen_time;
|
||||||
if (idle < 0) idle = 0;
|
if (idle < 0) idle = 0;
|
||||||
|
|
||||||
@ -2511,7 +2512,7 @@ NULL
|
|||||||
raxStart(&ri,s->cgroups);
|
raxStart(&ri,s->cgroups);
|
||||||
raxSeek(&ri,"^",NULL,0);
|
raxSeek(&ri,"^",NULL,0);
|
||||||
while(raxNext(&ri)) {
|
while(raxNext(&ri)) {
|
||||||
streamCG *cg = ri.data;
|
streamCG *cg = (streamCG*)ri.data;
|
||||||
addReplyMapLen(c,4);
|
addReplyMapLen(c,4);
|
||||||
addReplyBulkCString(c,"name");
|
addReplyBulkCString(c,"name");
|
||||||
addReplyBulkCBuffer(c,ri.key,ri.key_len);
|
addReplyBulkCBuffer(c,ri.key,ri.key_len);
|
@ -69,7 +69,7 @@ int zslLexValueLteMax(sds value, zlexrangespec *spec);
|
|||||||
/* Create a skiplist node with the specified number of levels.
|
/* Create a skiplist node with the specified number of levels.
|
||||||
* The SDS string 'ele' is referenced by the node after the call. */
|
* The SDS string 'ele' is referenced by the node after the call. */
|
||||||
zskiplistNode *zslCreateNode(int level, double score, sds ele) {
|
zskiplistNode *zslCreateNode(int level, double score, sds ele) {
|
||||||
zskiplistNode *zn =
|
zskiplistNode *zn = (zskiplistNode*)
|
||||||
zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel), MALLOC_SHARED);
|
zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel), MALLOC_SHARED);
|
||||||
zn->score = score;
|
zn->score = score;
|
||||||
zn->ele = ele;
|
zn->ele = ele;
|
||||||
@ -81,13 +81,13 @@ zskiplist *zslCreate(void) {
|
|||||||
int j;
|
int j;
|
||||||
zskiplist *zsl;
|
zskiplist *zsl;
|
||||||
|
|
||||||
zsl = zmalloc(sizeof(*zsl), MALLOC_SHARED);
|
zsl = (zskiplist*)zmalloc(sizeof(*zsl), MALLOC_SHARED);
|
||||||
zsl->level = 1;
|
zsl->level = 1;
|
||||||
zsl->length = 0;
|
zsl->length = 0;
|
||||||
zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL);
|
zsl->header = zslCreateNode(ZSKIPLIST_MAXLEVEL,0,NULL);
|
||||||
for (j = 0; j < ZSKIPLIST_MAXLEVEL; j++) {
|
for (j = 0; j < ZSKIPLIST_MAXLEVEL; j++) {
|
||||||
zsl->header->level[j].forward = NULL;
|
zsl->header->level(j)->forward = NULL;
|
||||||
zsl->header->level[j].span = 0;
|
zsl->header->level(j)->span = 0;
|
||||||
}
|
}
|
||||||
zsl->header->backward = NULL;
|
zsl->header->backward = NULL;
|
||||||
zsl->tail = NULL;
|
zsl->tail = NULL;
|
||||||
@ -104,11 +104,11 @@ void zslFreeNode(zskiplistNode *node) {
|
|||||||
|
|
||||||
/* Free a whole skiplist. */
|
/* Free a whole skiplist. */
|
||||||
void zslFree(zskiplist *zsl) {
|
void zslFree(zskiplist *zsl) {
|
||||||
zskiplistNode *node = zsl->header->level[0].forward, *next;
|
zskiplistNode *node = zsl->header->level(0)->forward, *next;
|
||||||
|
|
||||||
zfree(zsl->header);
|
zfree(zsl->header);
|
||||||
while(node) {
|
while(node) {
|
||||||
next = node->level[0].forward;
|
next = node->level(0)->forward;
|
||||||
zslFreeNode(node);
|
zslFreeNode(node);
|
||||||
node = next;
|
node = next;
|
||||||
}
|
}
|
||||||
@ -139,13 +139,13 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
|
|||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
/* store rank that is crossed to reach the insert position */
|
/* store rank that is crossed to reach the insert position */
|
||||||
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
|
rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
|
||||||
while (x->level[i].forward &&
|
while (x->level(i)->forward &&
|
||||||
(x->level[i].forward->score < score ||
|
(x->level(i)->forward->score < score ||
|
||||||
(x->level[i].forward->score == score &&
|
(x->level(i)->forward->score == score &&
|
||||||
sdscmp(x->level[i].forward->ele,ele) < 0)))
|
sdscmp(x->level(i)->forward->ele,ele) < 0)))
|
||||||
{
|
{
|
||||||
rank[i] += x->level[i].span;
|
rank[i] += x->level(i)->span;
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
update[i] = x;
|
update[i] = x;
|
||||||
}
|
}
|
||||||
@ -158,28 +158,28 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
|
|||||||
for (i = zsl->level; i < level; i++) {
|
for (i = zsl->level; i < level; i++) {
|
||||||
rank[i] = 0;
|
rank[i] = 0;
|
||||||
update[i] = zsl->header;
|
update[i] = zsl->header;
|
||||||
update[i]->level[i].span = zsl->length;
|
update[i]->level(i)->span = zsl->length;
|
||||||
}
|
}
|
||||||
zsl->level = level;
|
zsl->level = level;
|
||||||
}
|
}
|
||||||
x = zslCreateNode(level,score,ele);
|
x = zslCreateNode(level,score,ele);
|
||||||
for (i = 0; i < level; i++) {
|
for (i = 0; i < level; i++) {
|
||||||
x->level[i].forward = update[i]->level[i].forward;
|
x->level(i)->forward = update[i]->level(i)->forward;
|
||||||
update[i]->level[i].forward = x;
|
update[i]->level(i)->forward = x;
|
||||||
|
|
||||||
/* update span covered by update[i] as x is inserted here */
|
/* update span covered by update[i] as x is inserted here */
|
||||||
x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
|
x->level(i)->span = update[i]->level(i)->span - (rank[0] - rank[i]);
|
||||||
update[i]->level[i].span = (rank[0] - rank[i]) + 1;
|
update[i]->level(i)->span = (rank[0] - rank[i]) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increment span for untouched levels */
|
/* increment span for untouched levels */
|
||||||
for (i = level; i < zsl->level; i++) {
|
for (i = level; i < zsl->level; i++) {
|
||||||
update[i]->level[i].span++;
|
update[i]->level(i)->span++;
|
||||||
}
|
}
|
||||||
|
|
||||||
x->backward = (update[0] == zsl->header) ? NULL : update[0];
|
x->backward = (update[0] == zsl->header) ? NULL : update[0];
|
||||||
if (x->level[0].forward)
|
if (x->level(0)->forward)
|
||||||
x->level[0].forward->backward = x;
|
x->level(0)->forward->backward = x;
|
||||||
else
|
else
|
||||||
zsl->tail = x;
|
zsl->tail = x;
|
||||||
zsl->length++;
|
zsl->length++;
|
||||||
@ -190,19 +190,19 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
|
|||||||
void zslDeleteNode(zskiplist *zsl, zskiplistNode *x, zskiplistNode **update) {
|
void zslDeleteNode(zskiplist *zsl, zskiplistNode *x, zskiplistNode **update) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < zsl->level; i++) {
|
for (i = 0; i < zsl->level; i++) {
|
||||||
if (update[i]->level[i].forward == x) {
|
if (update[i]->level(i)->forward == x) {
|
||||||
update[i]->level[i].span += x->level[i].span - 1;
|
update[i]->level(i)->span += x->level(i)->span - 1;
|
||||||
update[i]->level[i].forward = x->level[i].forward;
|
update[i]->level(i)->forward = x->level(i)->forward;
|
||||||
} else {
|
} else {
|
||||||
update[i]->level[i].span -= 1;
|
update[i]->level(i)->span -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x->level[0].forward) {
|
if (x->level(0)->forward) {
|
||||||
x->level[0].forward->backward = x->backward;
|
x->level(0)->forward->backward = x->backward;
|
||||||
} else {
|
} else {
|
||||||
zsl->tail = x->backward;
|
zsl->tail = x->backward;
|
||||||
}
|
}
|
||||||
while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL)
|
while(zsl->level > 1 && zsl->header->level(zsl->level-1)->forward == NULL)
|
||||||
zsl->level--;
|
zsl->level--;
|
||||||
zsl->length--;
|
zsl->length--;
|
||||||
}
|
}
|
||||||
@ -221,18 +221,18 @@ int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) {
|
|||||||
|
|
||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
while (x->level[i].forward &&
|
while (x->level(i)->forward &&
|
||||||
(x->level[i].forward->score < score ||
|
(x->level(i)->forward->score < score ||
|
||||||
(x->level[i].forward->score == score &&
|
(x->level(i)->forward->score == score &&
|
||||||
sdscmp(x->level[i].forward->ele,ele) < 0)))
|
sdscmp(x->level(i)->forward->ele,ele) < 0)))
|
||||||
{
|
{
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
update[i] = x;
|
update[i] = x;
|
||||||
}
|
}
|
||||||
/* We may have multiple elements with the same score, what we need
|
/* We may have multiple elements with the same score, what we need
|
||||||
* is to find the element with both the right score and object. */
|
* is to find the element with both the right score and object. */
|
||||||
x = x->level[0].forward;
|
x = x->level(0)->forward;
|
||||||
if (x && score == x->score && sdscmp(x->ele,ele) == 0) {
|
if (x && score == x->score && sdscmp(x->ele,ele) == 0) {
|
||||||
zslDeleteNode(zsl, x, update);
|
zslDeleteNode(zsl, x, update);
|
||||||
if (!node)
|
if (!node)
|
||||||
@ -263,26 +263,26 @@ zskiplistNode *zslUpdateScore(zskiplist *zsl, double curscore, sds ele, double n
|
|||||||
* we'll have to update or remove it. */
|
* we'll have to update or remove it. */
|
||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
while (x->level[i].forward &&
|
while (x->level(i)->forward &&
|
||||||
(x->level[i].forward->score < curscore ||
|
(x->level(i)->forward->score < curscore ||
|
||||||
(x->level[i].forward->score == curscore &&
|
(x->level(i)->forward->score == curscore &&
|
||||||
sdscmp(x->level[i].forward->ele,ele) < 0)))
|
sdscmp(x->level(i)->forward->ele,ele) < 0)))
|
||||||
{
|
{
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
update[i] = x;
|
update[i] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Jump to our element: note that this function assumes that the
|
/* Jump to our element: note that this function assumes that the
|
||||||
* element with the matching score exists. */
|
* element with the matching score exists. */
|
||||||
x = x->level[0].forward;
|
x = x->level(0)->forward;
|
||||||
serverAssert(x && curscore == x->score && sdscmp(x->ele,ele) == 0);
|
serverAssert(x && curscore == x->score && sdscmp(x->ele,ele) == 0);
|
||||||
|
|
||||||
/* If the node, after the score update, would be still exactly
|
/* If the node, after the score update, would be still exactly
|
||||||
* at the same position, we can just update the score without
|
* at the same position, we can just update the score without
|
||||||
* actually removing and re-inserting the element in the skiplist. */
|
* actually removing and re-inserting the element in the skiplist. */
|
||||||
if ((x->backward == NULL || x->backward->score < newscore) &&
|
if ((x->backward == NULL || x->backward->score < newscore) &&
|
||||||
(x->level[0].forward == NULL || x->level[0].forward->score > newscore))
|
(x->level(0)->forward == NULL || x->level(0)->forward->score > newscore))
|
||||||
{
|
{
|
||||||
x->score = newscore;
|
x->score = newscore;
|
||||||
return x;
|
return x;
|
||||||
@ -318,7 +318,7 @@ int zslIsInRange(zskiplist *zsl, zrangespec *range) {
|
|||||||
x = zsl->tail;
|
x = zsl->tail;
|
||||||
if (x == NULL || !zslValueGteMin(x->score,range))
|
if (x == NULL || !zslValueGteMin(x->score,range))
|
||||||
return 0;
|
return 0;
|
||||||
x = zsl->header->level[0].forward;
|
x = zsl->header->level(0)->forward;
|
||||||
if (x == NULL || !zslValueLteMax(x->score,range))
|
if (x == NULL || !zslValueLteMax(x->score,range))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
@ -336,13 +336,13 @@ zskiplistNode *zslFirstInRange(zskiplist *zsl, zrangespec *range) {
|
|||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
/* Go forward while *OUT* of range. */
|
/* Go forward while *OUT* of range. */
|
||||||
while (x->level[i].forward &&
|
while (x->level(i)->forward &&
|
||||||
!zslValueGteMin(x->level[i].forward->score,range))
|
!zslValueGteMin(x->level(i)->forward->score,range))
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is an inner range, so the next node cannot be NULL. */
|
/* This is an inner range, so the next node cannot be NULL. */
|
||||||
x = x->level[0].forward;
|
x = x->level(0)->forward;
|
||||||
serverAssert(x != NULL);
|
serverAssert(x != NULL);
|
||||||
|
|
||||||
/* Check if score <= max. */
|
/* Check if score <= max. */
|
||||||
@ -362,9 +362,9 @@ zskiplistNode *zslLastInRange(zskiplist *zsl, zrangespec *range) {
|
|||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
/* Go forward while *IN* range. */
|
/* Go forward while *IN* range. */
|
||||||
while (x->level[i].forward &&
|
while (x->level(i)->forward &&
|
||||||
zslValueLteMax(x->level[i].forward->score,range))
|
zslValueLteMax(x->level(i)->forward->score,range))
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is an inner range, so this node cannot be NULL. */
|
/* This is an inner range, so this node cannot be NULL. */
|
||||||
@ -386,21 +386,21 @@ unsigned long zslDeleteRangeByScore(zskiplist *zsl, zrangespec *range, dict *dic
|
|||||||
|
|
||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
while (x->level[i].forward && (range->minex ?
|
while (x->level(i)->forward && (range->minex ?
|
||||||
x->level[i].forward->score <= range->min :
|
x->level(i)->forward->score <= range->min :
|
||||||
x->level[i].forward->score < range->min))
|
x->level(i)->forward->score < range->min))
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
update[i] = x;
|
update[i] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Current node is the last with score < or <= min. */
|
/* Current node is the last with score < or <= min. */
|
||||||
x = x->level[0].forward;
|
x = x->level(0)->forward;
|
||||||
|
|
||||||
/* Delete nodes while in range. */
|
/* Delete nodes while in range. */
|
||||||
while (x &&
|
while (x &&
|
||||||
(range->maxex ? x->score < range->max : x->score <= range->max))
|
(range->maxex ? x->score < range->max : x->score <= range->max))
|
||||||
{
|
{
|
||||||
zskiplistNode *next = x->level[0].forward;
|
zskiplistNode *next = x->level(0)->forward;
|
||||||
zslDeleteNode(zsl,x,update);
|
zslDeleteNode(zsl,x,update);
|
||||||
dictDelete(dict,x->ele);
|
dictDelete(dict,x->ele);
|
||||||
zslFreeNode(x); /* Here is where x->ele is actually released. */
|
zslFreeNode(x); /* Here is where x->ele is actually released. */
|
||||||
@ -418,18 +418,18 @@ unsigned long zslDeleteRangeByLex(zskiplist *zsl, zlexrangespec *range, dict *di
|
|||||||
|
|
||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
while (x->level[i].forward &&
|
while (x->level(i)->forward &&
|
||||||
!zslLexValueGteMin(x->level[i].forward->ele,range))
|
!zslLexValueGteMin(x->level(i)->forward->ele,range))
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
update[i] = x;
|
update[i] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Current node is the last with score < or <= min. */
|
/* Current node is the last with score < or <= min. */
|
||||||
x = x->level[0].forward;
|
x = x->level(0)->forward;
|
||||||
|
|
||||||
/* Delete nodes while in range. */
|
/* Delete nodes while in range. */
|
||||||
while (x && zslLexValueLteMax(x->ele,range)) {
|
while (x && zslLexValueLteMax(x->ele,range)) {
|
||||||
zskiplistNode *next = x->level[0].forward;
|
zskiplistNode *next = x->level(0)->forward;
|
||||||
zslDeleteNode(zsl,x,update);
|
zslDeleteNode(zsl,x,update);
|
||||||
dictDelete(dict,x->ele);
|
dictDelete(dict,x->ele);
|
||||||
zslFreeNode(x); /* Here is where x->ele is actually released. */
|
zslFreeNode(x); /* Here is where x->ele is actually released. */
|
||||||
@ -448,17 +448,17 @@ unsigned long zslDeleteRangeByRank(zskiplist *zsl, unsigned int start, unsigned
|
|||||||
|
|
||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
while (x->level[i].forward && (traversed + x->level[i].span) < start) {
|
while (x->level(i)->forward && (traversed + x->level(i)->span) < start) {
|
||||||
traversed += x->level[i].span;
|
traversed += x->level(i)->span;
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
update[i] = x;
|
update[i] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
traversed++;
|
traversed++;
|
||||||
x = x->level[0].forward;
|
x = x->level(0)->forward;
|
||||||
while (x && traversed <= end) {
|
while (x && traversed <= end) {
|
||||||
zskiplistNode *next = x->level[0].forward;
|
zskiplistNode *next = x->level(0)->forward;
|
||||||
zslDeleteNode(zsl,x,update);
|
zslDeleteNode(zsl,x,update);
|
||||||
dictDelete(dict,x->ele);
|
dictDelete(dict,x->ele);
|
||||||
zslFreeNode(x);
|
zslFreeNode(x);
|
||||||
@ -480,12 +480,12 @@ unsigned long zslGetRank(zskiplist *zsl, double score, sds ele) {
|
|||||||
|
|
||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
while (x->level[i].forward &&
|
while (x->level(i)->forward &&
|
||||||
(x->level[i].forward->score < score ||
|
(x->level(i)->forward->score < score ||
|
||||||
(x->level[i].forward->score == score &&
|
(x->level(i)->forward->score == score &&
|
||||||
sdscmp(x->level[i].forward->ele,ele) <= 0))) {
|
sdscmp(x->level(i)->forward->ele,ele) <= 0))) {
|
||||||
rank += x->level[i].span;
|
rank += x->level(i)->span;
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* x might be equal to zsl->header, so test if obj is non-NULL */
|
/* x might be equal to zsl->header, so test if obj is non-NULL */
|
||||||
@ -504,10 +504,10 @@ zskiplistNode* zslGetElementByRank(zskiplist *zsl, unsigned long rank) {
|
|||||||
|
|
||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
while (x->level[i].forward && (traversed + x->level[i].span) <= rank)
|
while (x->level(i)->forward && (traversed + x->level(i)->span) <= rank)
|
||||||
{
|
{
|
||||||
traversed += x->level[i].span;
|
traversed += x->level(i)->span;
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
if (traversed == rank) {
|
if (traversed == rank) {
|
||||||
return x;
|
return x;
|
||||||
@ -569,7 +569,7 @@ static int zslParseRange(robj *min, robj *max, zrangespec *spec) {
|
|||||||
* If the string is not a valid range C_ERR is returned, and the value
|
* If the string is not a valid range C_ERR is returned, and the value
|
||||||
* of *dest and *ex is undefined. */
|
* of *dest and *ex is undefined. */
|
||||||
int zslParseLexRangeItem(robj *item, sds *dest, int *ex) {
|
int zslParseLexRangeItem(robj *item, sds *dest, int *ex) {
|
||||||
char *c = ptrFromObj(item);
|
char *c = szFromObj(item);
|
||||||
|
|
||||||
switch(c[0]) {
|
switch(c[0]) {
|
||||||
case '+':
|
case '+':
|
||||||
@ -658,7 +658,7 @@ int zslIsInLexRange(zskiplist *zsl, zlexrangespec *range) {
|
|||||||
x = zsl->tail;
|
x = zsl->tail;
|
||||||
if (x == NULL || !zslLexValueGteMin(x->ele,range))
|
if (x == NULL || !zslLexValueGteMin(x->ele,range))
|
||||||
return 0;
|
return 0;
|
||||||
x = zsl->header->level[0].forward;
|
x = zsl->header->level(0)->forward;
|
||||||
if (x == NULL || !zslLexValueLteMax(x->ele,range))
|
if (x == NULL || !zslLexValueLteMax(x->ele,range))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
@ -676,13 +676,13 @@ zskiplistNode *zslFirstInLexRange(zskiplist *zsl, zlexrangespec *range) {
|
|||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
/* Go forward while *OUT* of range. */
|
/* Go forward while *OUT* of range. */
|
||||||
while (x->level[i].forward &&
|
while (x->level(i)->forward &&
|
||||||
!zslLexValueGteMin(x->level[i].forward->ele,range))
|
!zslLexValueGteMin(x->level(i)->forward->ele,range))
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is an inner range, so the next node cannot be NULL. */
|
/* This is an inner range, so the next node cannot be NULL. */
|
||||||
x = x->level[0].forward;
|
x = x->level(0)->forward;
|
||||||
serverAssert(x != NULL);
|
serverAssert(x != NULL);
|
||||||
|
|
||||||
/* Check if score <= max. */
|
/* Check if score <= max. */
|
||||||
@ -702,9 +702,9 @@ zskiplistNode *zslLastInLexRange(zskiplist *zsl, zlexrangespec *range) {
|
|||||||
x = zsl->header;
|
x = zsl->header;
|
||||||
for (i = zsl->level-1; i >= 0; i--) {
|
for (i = zsl->level-1; i >= 0; i--) {
|
||||||
/* Go forward while *IN* range. */
|
/* Go forward while *IN* range. */
|
||||||
while (x->level[i].forward &&
|
while (x->level(i)->forward &&
|
||||||
zslLexValueLteMax(x->level[i].forward->ele,range))
|
zslLexValueLteMax(x->level(i)->forward->ele,range))
|
||||||
x = x->level[i].forward;
|
x = x->level(i)->forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is an inner range, so this node cannot be NULL. */
|
/* This is an inner range, so this node cannot be NULL. */
|
||||||
@ -1156,7 +1156,7 @@ unsigned char *zzlDeleteRangeByRank(unsigned char *zl, unsigned int start, unsig
|
|||||||
unsigned long zsetLength(const robj *zobj) {
|
unsigned long zsetLength(const robj *zobj) {
|
||||||
unsigned long length = 0;
|
unsigned long length = 0;
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
length = zzlLength(zobj->m_ptr);
|
length = zzlLength((unsigned char*)zobj->m_ptr);
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
length = ((const zset*)zobj->m_ptr)->zsl->length;
|
length = ((const zset*)zobj->m_ptr)->zsl->length;
|
||||||
} else {
|
} else {
|
||||||
@ -1173,7 +1173,7 @@ void zsetConvert(robj *zobj, int encoding) {
|
|||||||
|
|
||||||
if (zobj->encoding == encoding) return;
|
if (zobj->encoding == encoding) return;
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl = zobj->m_ptr;
|
unsigned char *zl = (unsigned char*)zobj->m_ptr;
|
||||||
unsigned char *eptr, *sptr;
|
unsigned char *eptr, *sptr;
|
||||||
unsigned char *vstr;
|
unsigned char *vstr;
|
||||||
unsigned int vlen;
|
unsigned int vlen;
|
||||||
@ -1182,7 +1182,7 @@ void zsetConvert(robj *zobj, int encoding) {
|
|||||||
if (encoding != OBJ_ENCODING_SKIPLIST)
|
if (encoding != OBJ_ENCODING_SKIPLIST)
|
||||||
serverPanic("Unknown target encoding");
|
serverPanic("Unknown target encoding");
|
||||||
|
|
||||||
zs = zmalloc(sizeof(*zs), MALLOC_SHARED);
|
zs = (zset*)zmalloc(sizeof(*zs), MALLOC_SHARED);
|
||||||
zs->pdict = dictCreate(&zsetDictType,NULL);
|
zs->pdict = dictCreate(&zsetDictType,NULL);
|
||||||
zs->zsl = zslCreate();
|
zs->zsl = zslCreate();
|
||||||
|
|
||||||
@ -1215,15 +1215,15 @@ void zsetConvert(robj *zobj, int encoding) {
|
|||||||
|
|
||||||
/* Approach similar to zslFree(), since we want to free the skiplist at
|
/* Approach similar to zslFree(), since we want to free the skiplist at
|
||||||
* the same time as creating the ziplist. */
|
* the same time as creating the ziplist. */
|
||||||
zs = zobj->m_ptr;
|
zs = (zset*)zobj->m_ptr;
|
||||||
dictRelease(zs->pdict);
|
dictRelease(zs->pdict);
|
||||||
node = zs->zsl->header->level[0].forward;
|
node = zs->zsl->header->level(0)->forward;
|
||||||
zfree(zs->zsl->header);
|
zfree(zs->zsl->header);
|
||||||
zfree(zs->zsl);
|
zfree(zs->zsl);
|
||||||
|
|
||||||
while (node) {
|
while (node) {
|
||||||
zl = zzlInsertAt(zl,NULL,node->ele,node->score);
|
zl = zzlInsertAt(zl,NULL,node->ele,node->score);
|
||||||
next = node->level[0].forward;
|
next = node->level(0)->forward;
|
||||||
zslFreeNode(node);
|
zslFreeNode(node);
|
||||||
node = next;
|
node = next;
|
||||||
}
|
}
|
||||||
@ -1241,9 +1241,9 @@ void zsetConvert(robj *zobj, int encoding) {
|
|||||||
* expected ranges. */
|
* expected ranges. */
|
||||||
void zsetConvertToZiplistIfNeeded(robj *zobj, size_t maxelelen) {
|
void zsetConvertToZiplistIfNeeded(robj *zobj, size_t maxelelen) {
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) return;
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) return;
|
||||||
zset *zset = zobj->m_ptr;
|
zset *set = (zset*)zobj->m_ptr;
|
||||||
|
|
||||||
if (zset->zsl->length <= server.zset_max_ziplist_entries &&
|
if (set->zsl->length <= server.zset_max_ziplist_entries &&
|
||||||
maxelelen <= server.zset_max_ziplist_value)
|
maxelelen <= server.zset_max_ziplist_value)
|
||||||
zsetConvert(zobj,OBJ_ENCODING_ZIPLIST);
|
zsetConvert(zobj,OBJ_ENCODING_ZIPLIST);
|
||||||
}
|
}
|
||||||
@ -1256,9 +1256,9 @@ int zsetScore(robj *zobj, sds member, double *score) {
|
|||||||
if (!zobj || !member) return C_ERR;
|
if (!zobj || !member) return C_ERR;
|
||||||
|
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
if (zzlFind(zobj->m_ptr, member, score) == NULL) return C_ERR;
|
if (zzlFind((unsigned char*)zobj->m_ptr, member, score) == NULL) return C_ERR;
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
dictEntry *de = dictFind(zs->pdict, member);
|
dictEntry *de = dictFind(zs->pdict, member);
|
||||||
if (de == NULL) return C_ERR;
|
if (de == NULL) return C_ERR;
|
||||||
*score = *(double*)dictGetVal(de);
|
*score = *(double*)dictGetVal(de);
|
||||||
@ -1329,7 +1329,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) {
|
|||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *eptr;
|
unsigned char *eptr;
|
||||||
|
|
||||||
if ((eptr = zzlFind(zobj->m_ptr,ele,&curscore)) != NULL) {
|
if ((eptr = zzlFind((unsigned char*)zobj->m_ptr,ele,&curscore)) != NULL) {
|
||||||
/* NX? Return, same element already exists. */
|
/* NX? Return, same element already exists. */
|
||||||
if (nx) {
|
if (nx) {
|
||||||
*flags |= ZADD_NOP;
|
*flags |= ZADD_NOP;
|
||||||
@ -1348,16 +1348,16 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) {
|
|||||||
|
|
||||||
/* Remove and re-insert when score changed. */
|
/* Remove and re-insert when score changed. */
|
||||||
if (score != curscore) {
|
if (score != curscore) {
|
||||||
zobj->m_ptr = zzlDelete(zobj->m_ptr,eptr);
|
zobj->m_ptr = zzlDelete((unsigned char*)zobj->m_ptr,eptr);
|
||||||
zobj->m_ptr = zzlInsert(zobj->m_ptr,ele,score);
|
zobj->m_ptr = zzlInsert((unsigned char*)zobj->m_ptr,ele,score);
|
||||||
*flags |= ZADD_UPDATED;
|
*flags |= ZADD_UPDATED;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else if (!xx) {
|
} else if (!xx) {
|
||||||
/* Optimize: check if the element is too large or the list
|
/* Optimize: check if the element is too large or the list
|
||||||
* becomes too long *before* executing zzlInsert. */
|
* becomes too long *before* executing zzlInsert. */
|
||||||
zobj->m_ptr = zzlInsert(zobj->m_ptr,ele,score);
|
zobj->m_ptr = zzlInsert((unsigned char*)zobj->m_ptr,ele,score);
|
||||||
if (zzlLength(zobj->m_ptr) > server.zset_max_ziplist_entries)
|
if (zzlLength((unsigned char*)zobj->m_ptr) > server.zset_max_ziplist_entries)
|
||||||
zsetConvert(zobj,OBJ_ENCODING_SKIPLIST);
|
zsetConvert(zobj,OBJ_ENCODING_SKIPLIST);
|
||||||
if (sdslen(ele) > server.zset_max_ziplist_value)
|
if (sdslen(ele) > server.zset_max_ziplist_value)
|
||||||
zsetConvert(zobj,OBJ_ENCODING_SKIPLIST);
|
zsetConvert(zobj,OBJ_ENCODING_SKIPLIST);
|
||||||
@ -1369,7 +1369,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
zskiplistNode *znode;
|
zskiplistNode *znode;
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
|
|
||||||
@ -1425,12 +1425,12 @@ int zsetDel(robj *zobj, sds ele) {
|
|||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *eptr;
|
unsigned char *eptr;
|
||||||
|
|
||||||
if ((eptr = zzlFind(zobj->m_ptr,ele,NULL)) != NULL) {
|
if ((eptr = zzlFind((unsigned char*)zobj->m_ptr,ele,NULL)) != NULL) {
|
||||||
zobj->m_ptr = zzlDelete(zobj->m_ptr,eptr);
|
zobj->m_ptr = zzlDelete((unsigned char*)zobj->m_ptr,eptr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
double score;
|
double score;
|
||||||
|
|
||||||
@ -1477,7 +1477,7 @@ long zsetRank(robj *zobj, sds ele, int reverse) {
|
|||||||
llen = zsetLength(zobj);
|
llen = zsetLength(zobj);
|
||||||
|
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl = zobj->m_ptr;
|
unsigned char *zl = (unsigned char*)zobj->m_ptr;
|
||||||
unsigned char *eptr, *sptr;
|
unsigned char *eptr, *sptr;
|
||||||
|
|
||||||
eptr = ziplistIndex(zl,0);
|
eptr = ziplistIndex(zl,0);
|
||||||
@ -1502,7 +1502,7 @@ long zsetRank(robj *zobj, sds ele, int reverse) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
zskiplist *zsl = zs->zsl;
|
zskiplist *zsl = zs->zsl;
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
double score;
|
double score;
|
||||||
@ -1531,7 +1531,7 @@ long zsetRank(robj *zobj, sds ele, int reverse) {
|
|||||||
|
|
||||||
/* This generic command implements both ZADD and ZINCRBY. */
|
/* This generic command implements both ZADD and ZINCRBY. */
|
||||||
void zaddGenericCommand(client *c, int flags) {
|
void zaddGenericCommand(client *c, int flags) {
|
||||||
static char *nanerr = "resulting score is not a number (NaN)";
|
static const char *nanerr = "resulting score is not a number (NaN)";
|
||||||
robj *key = c->argv[1];
|
robj *key = c->argv[1];
|
||||||
robj *zobj;
|
robj *zobj;
|
||||||
sds ele;
|
sds ele;
|
||||||
@ -1550,7 +1550,7 @@ void zaddGenericCommand(client *c, int flags) {
|
|||||||
* of the score of the first score-element pair. */
|
* of the score of the first score-element pair. */
|
||||||
scoreidx = 2;
|
scoreidx = 2;
|
||||||
while(scoreidx < c->argc) {
|
while(scoreidx < c->argc) {
|
||||||
char *opt = ptrFromObj(c->argv[scoreidx]);
|
char *opt = szFromObj(c->argv[scoreidx]);
|
||||||
if (!strcasecmp(opt,"nx")) flags |= ZADD_NX;
|
if (!strcasecmp(opt,"nx")) flags |= ZADD_NX;
|
||||||
else if (!strcasecmp(opt,"xx")) flags |= ZADD_XX;
|
else if (!strcasecmp(opt,"xx")) flags |= ZADD_XX;
|
||||||
else if (!strcasecmp(opt,"ch")) flags |= ZADD_CH;
|
else if (!strcasecmp(opt,"ch")) flags |= ZADD_CH;
|
||||||
@ -1590,7 +1590,7 @@ void zaddGenericCommand(client *c, int flags) {
|
|||||||
/* Start parsing all the scores, we need to emit any syntax error
|
/* Start parsing all the scores, we need to emit any syntax error
|
||||||
* before executing additions to the sorted set, as the command should
|
* before executing additions to the sorted set, as the command should
|
||||||
* either execute fully or nothing at all. */
|
* either execute fully or nothing at all. */
|
||||||
scores = zmalloc(sizeof(double)*elements, MALLOC_SHARED);
|
scores = (double*)zmalloc(sizeof(double)*elements, MALLOC_SHARED);
|
||||||
for (j = 0; j < elements; j++) {
|
for (j = 0; j < elements; j++) {
|
||||||
if (getDoubleFromObjectOrReply(c,c->argv[scoreidx+j*2],&scores[j],NULL)
|
if (getDoubleFromObjectOrReply(c,c->argv[scoreidx+j*2],&scores[j],NULL)
|
||||||
!= C_OK) goto cleanup;
|
!= C_OK) goto cleanup;
|
||||||
@ -1601,7 +1601,7 @@ void zaddGenericCommand(client *c, int flags) {
|
|||||||
if (zobj == NULL) {
|
if (zobj == NULL) {
|
||||||
if (xx) goto reply_to_client; /* No key + XX option: nothing to do. */
|
if (xx) goto reply_to_client; /* No key + XX option: nothing to do. */
|
||||||
if (server.zset_max_ziplist_entries == 0 ||
|
if (server.zset_max_ziplist_entries == 0 ||
|
||||||
server.zset_max_ziplist_value < sdslen(ptrFromObj(c->argv[scoreidx+1])))
|
server.zset_max_ziplist_value < sdslen(szFromObj(c->argv[scoreidx+1])))
|
||||||
{
|
{
|
||||||
zobj = createZsetObject();
|
zobj = createZsetObject();
|
||||||
} else {
|
} else {
|
||||||
@ -1620,7 +1620,7 @@ void zaddGenericCommand(client *c, int flags) {
|
|||||||
score = scores[j];
|
score = scores[j];
|
||||||
int retflags = flags;
|
int retflags = flags;
|
||||||
|
|
||||||
ele = ptrFromObj(c->argv[scoreidx+1+j*2]);
|
ele = szFromObj(c->argv[scoreidx+1+j*2]);
|
||||||
int retval = zsetAdd(zobj, score, ele, &retflags, &newscore);
|
int retval = zsetAdd(zobj, score, ele, &retflags, &newscore);
|
||||||
if (retval == 0) {
|
if (retval == 0) {
|
||||||
addReplyError(c,nanerr);
|
addReplyError(c,nanerr);
|
||||||
@ -1669,7 +1669,7 @@ void zremCommand(client *c) {
|
|||||||
checkType(c,zobj,OBJ_ZSET)) return;
|
checkType(c,zobj,OBJ_ZSET)) return;
|
||||||
|
|
||||||
for (j = 2; j < c->argc; j++) {
|
for (j = 2; j < c->argc; j++) {
|
||||||
if (zsetDel(zobj,ptrFromObj(c->argv[j]))) deleted++;
|
if (zsetDel(zobj,szFromObj(c->argv[j]))) deleted++;
|
||||||
if (zsetLength(zobj) == 0) {
|
if (zsetLength(zobj) == 0) {
|
||||||
dbDelete(c->db,key);
|
dbDelete(c->db,key);
|
||||||
keyremoved = 1;
|
keyremoved = 1;
|
||||||
@ -1741,21 +1741,21 @@ void zremrangeGenericCommand(client *c, int rangetype) {
|
|||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
switch(rangetype) {
|
switch(rangetype) {
|
||||||
case ZRANGE_RANK:
|
case ZRANGE_RANK:
|
||||||
zobj->m_ptr = zzlDeleteRangeByRank(zobj->m_ptr,start+1,end+1,&deleted);
|
zobj->m_ptr = zzlDeleteRangeByRank((unsigned char*)zobj->m_ptr,start+1,end+1,&deleted);
|
||||||
break;
|
break;
|
||||||
case ZRANGE_SCORE:
|
case ZRANGE_SCORE:
|
||||||
zobj->m_ptr = zzlDeleteRangeByScore(zobj->m_ptr,&range,&deleted);
|
zobj->m_ptr = zzlDeleteRangeByScore((unsigned char*)zobj->m_ptr,&range,&deleted);
|
||||||
break;
|
break;
|
||||||
case ZRANGE_LEX:
|
case ZRANGE_LEX:
|
||||||
zobj->m_ptr = zzlDeleteRangeByLex(zobj->m_ptr,&lexrange,&deleted);
|
zobj->m_ptr = zzlDeleteRangeByLex((unsigned char*)zobj->m_ptr,&lexrange,&deleted);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (zzlLength(zobj->m_ptr) == 0) {
|
if (zzlLength((unsigned char*)zobj->m_ptr) == 0) {
|
||||||
dbDelete(c->db,key);
|
dbDelete(c->db,key);
|
||||||
keyremoved = 1;
|
keyremoved = 1;
|
||||||
}
|
}
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
switch(rangetype) {
|
switch(rangetype) {
|
||||||
case ZRANGE_RANK:
|
case ZRANGE_RANK:
|
||||||
deleted = zslDeleteRangeByRank(zs->zsl,start+1,end+1,zs->pdict);
|
deleted = zslDeleteRangeByRank(zs->zsl,start+1,end+1,zs->pdict);
|
||||||
@ -1778,7 +1778,7 @@ void zremrangeGenericCommand(client *c, int rangetype) {
|
|||||||
|
|
||||||
/* Step 4: Notifications and reply. */
|
/* Step 4: Notifications and reply. */
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
char *event[3] = {"zremrangebyrank","zremrangebyscore","zremrangebylex"};
|
const char *event[3] = {"zremrangebyrank","zremrangebyscore","zremrangebylex"};
|
||||||
signalModifiedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
notifyKeyspaceEvent(NOTIFY_ZSET,event[rangetype],key,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_ZSET,event[rangetype],key,c->db->id);
|
||||||
if (keyremoved)
|
if (keyremoved)
|
||||||
@ -1803,13 +1803,13 @@ void zremrangebylexCommand(client *c) {
|
|||||||
zremrangeGenericCommand(c,ZRANGE_LEX);
|
zremrangeGenericCommand(c,ZRANGE_LEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
struct zsetopsrc {
|
||||||
robj *subject;
|
robj *subject;
|
||||||
int type; /* Set, sorted set */
|
int type; /* Set, sorted set */
|
||||||
int encoding;
|
int encoding;
|
||||||
double weight;
|
double weight;
|
||||||
|
|
||||||
union {
|
union _uT {
|
||||||
/* Set iterators. */
|
/* Set iterators. */
|
||||||
union _iterset {
|
union _iterset {
|
||||||
struct {
|
struct {
|
||||||
@ -1817,7 +1817,7 @@ typedef struct {
|
|||||||
int ii;
|
int ii;
|
||||||
} is;
|
} is;
|
||||||
struct {
|
struct {
|
||||||
dict *dict;
|
dict *pdict;
|
||||||
dictIterator *di;
|
dictIterator *di;
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
} ht;
|
} ht;
|
||||||
@ -1835,7 +1835,7 @@ typedef struct {
|
|||||||
} sl;
|
} sl;
|
||||||
} zset;
|
} zset;
|
||||||
} iter;
|
} iter;
|
||||||
} zsetopsrc;
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Use dirty flags for pointers that need to be cleaned up in the next
|
/* Use dirty flags for pointers that need to be cleaned up in the next
|
||||||
@ -1859,37 +1859,37 @@ typedef struct {
|
|||||||
double score;
|
double score;
|
||||||
} zsetopval;
|
} zsetopval;
|
||||||
|
|
||||||
typedef union _iterset iterset;
|
typedef union zsetopsrc::_uT::_iterset iterset;
|
||||||
typedef union _iterzset iterzset;
|
typedef union zsetopsrc::_uT::_iterzset iterzset;
|
||||||
|
|
||||||
void zuiInitIterator(zsetopsrc *op) {
|
void zuiInitIterator(zsetopsrc *op) {
|
||||||
if (op->subject == NULL)
|
if (op->subject == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (op->type == OBJ_SET) {
|
if (op->type == OBJ_SET) {
|
||||||
iterset *it = &op->iter.set;
|
iterset *it = (iterset*)&op->iter.set;
|
||||||
if (op->encoding == OBJ_ENCODING_INTSET) {
|
if (op->encoding == OBJ_ENCODING_INTSET) {
|
||||||
it->is.is = op->subject->m_ptr;
|
it->is.is = (intset*)op->subject->m_ptr;
|
||||||
it->is.ii = 0;
|
it->is.ii = 0;
|
||||||
} else if (op->encoding == OBJ_ENCODING_HT) {
|
} else if (op->encoding == OBJ_ENCODING_HT) {
|
||||||
it->ht.dict = op->subject->m_ptr;
|
it->ht.pdict = (dict*)op->subject->m_ptr;
|
||||||
it->ht.di = dictGetIterator(op->subject->m_ptr);
|
it->ht.di = dictGetIterator((dict*)op->subject->m_ptr);
|
||||||
it->ht.de = dictNext(it->ht.di);
|
it->ht.de = dictNext(it->ht.di);
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
} else if (op->type == OBJ_ZSET) {
|
} else if (op->type == OBJ_ZSET) {
|
||||||
iterzset *it = &op->iter.zset;
|
iterzset *it = (iterzset*)&op->iter.zset;
|
||||||
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
it->zl.zl = op->subject->m_ptr;
|
it->zl.zl = (unsigned char*)op->subject->m_ptr;
|
||||||
it->zl.eptr = ziplistIndex(it->zl.zl,0);
|
it->zl.eptr = ziplistIndex(it->zl.zl,0);
|
||||||
if (it->zl.eptr != NULL) {
|
if (it->zl.eptr != NULL) {
|
||||||
it->zl.sptr = ziplistNext(it->zl.zl,it->zl.eptr);
|
it->zl.sptr = ziplistNext(it->zl.zl,it->zl.eptr);
|
||||||
serverAssert(it->zl.sptr != NULL);
|
serverAssert(it->zl.sptr != NULL);
|
||||||
}
|
}
|
||||||
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
it->sl.zs = op->subject->m_ptr;
|
it->sl.zs = (zset*)op->subject->m_ptr;
|
||||||
it->sl.node = it->sl.zs->zsl->header->level[0].forward;
|
it->sl.node = it->sl.zs->zsl->header->level(0)->forward;
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
@ -1931,18 +1931,18 @@ unsigned long zuiLength(zsetopsrc *op) {
|
|||||||
|
|
||||||
if (op->type == OBJ_SET) {
|
if (op->type == OBJ_SET) {
|
||||||
if (op->encoding == OBJ_ENCODING_INTSET) {
|
if (op->encoding == OBJ_ENCODING_INTSET) {
|
||||||
return intsetLen(op->subject->m_ptr);
|
return intsetLen((const intset*)op->subject->m_ptr);
|
||||||
} else if (op->encoding == OBJ_ENCODING_HT) {
|
} else if (op->encoding == OBJ_ENCODING_HT) {
|
||||||
dict *ht = op->subject->m_ptr;
|
dict *ht = (dict*)op->subject->m_ptr;
|
||||||
return dictSize(ht);
|
return dictSize(ht);
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown set encoding");
|
serverPanic("Unknown set encoding");
|
||||||
}
|
}
|
||||||
} else if (op->type == OBJ_ZSET) {
|
} else if (op->type == OBJ_ZSET) {
|
||||||
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
return zzlLength(op->subject->m_ptr);
|
return zzlLength((unsigned char*)op->subject->m_ptr);
|
||||||
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = op->subject->m_ptr;
|
zset *zs = (zset*)op->subject->m_ptr;
|
||||||
return zs->zsl->length;
|
return zs->zsl->length;
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
@ -1979,7 +1979,7 @@ int zuiNext(zsetopsrc *op, zsetopval *val) {
|
|||||||
} else if (op->encoding == OBJ_ENCODING_HT) {
|
} else if (op->encoding == OBJ_ENCODING_HT) {
|
||||||
if (it->ht.de == NULL)
|
if (it->ht.de == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
val->ele = dictGetKey(it->ht.de);
|
val->ele = (sds)dictGetKey(it->ht.de);
|
||||||
val->score = 1.0;
|
val->score = 1.0;
|
||||||
|
|
||||||
/* Move to next element. */
|
/* Move to next element. */
|
||||||
@ -2005,7 +2005,7 @@ int zuiNext(zsetopsrc *op, zsetopval *val) {
|
|||||||
val->score = it->sl.node->score;
|
val->score = it->sl.node->score;
|
||||||
|
|
||||||
/* Move to next element. */
|
/* Move to next element. */
|
||||||
it->sl.node = it->sl.node->level[0].forward;
|
it->sl.node = it->sl.node->level(0)->forward;
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
}
|
}
|
||||||
@ -2085,7 +2085,7 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) {
|
|||||||
if (op->type == OBJ_SET) {
|
if (op->type == OBJ_SET) {
|
||||||
if (op->encoding == OBJ_ENCODING_INTSET) {
|
if (op->encoding == OBJ_ENCODING_INTSET) {
|
||||||
if (zuiLongLongFromValue(val) &&
|
if (zuiLongLongFromValue(val) &&
|
||||||
intsetFind(op->subject->m_ptr,val->ell))
|
intsetFind((intset*)op->subject->m_ptr,val->ell))
|
||||||
{
|
{
|
||||||
*score = 1.0;
|
*score = 1.0;
|
||||||
return 1;
|
return 1;
|
||||||
@ -2093,7 +2093,7 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (op->encoding == OBJ_ENCODING_HT) {
|
} else if (op->encoding == OBJ_ENCODING_HT) {
|
||||||
dict *ht = op->subject->m_ptr;
|
dict *ht = (dict*)op->subject->m_ptr;
|
||||||
zuiSdsFromValue(val);
|
zuiSdsFromValue(val);
|
||||||
if (dictFind(ht,val->ele) != NULL) {
|
if (dictFind(ht,val->ele) != NULL) {
|
||||||
*score = 1.0;
|
*score = 1.0;
|
||||||
@ -2108,14 +2108,14 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) {
|
|||||||
zuiSdsFromValue(val);
|
zuiSdsFromValue(val);
|
||||||
|
|
||||||
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
if (zzlFind(op->subject->m_ptr,val->ele,score) != NULL) {
|
if (zzlFind((unsigned char*)op->subject->m_ptr,val->ele,score) != NULL) {
|
||||||
/* Score is already set by zzlFind. */
|
/* Score is already set by zzlFind. */
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = op->subject->m_ptr;
|
zset *zs = (zset*)op->subject->m_ptr;
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
if ((de = dictFind(zs->pdict,val->ele)) != NULL) {
|
if ((de = dictFind(zs->pdict,val->ele)) != NULL) {
|
||||||
*score = *(double*)dictGetVal(de);
|
*score = *(double*)dictGetVal(de);
|
||||||
@ -2203,7 +2203,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read keys to be used for input */
|
/* read keys to be used for input */
|
||||||
src = zcalloc(sizeof(zsetopsrc) * setnum, MALLOC_SHARED);
|
src = (zsetopsrc*)zcalloc(sizeof(zsetopsrc) * setnum, MALLOC_SHARED);
|
||||||
for (i = 0, j = 3; i < setnum; i++, j++) {
|
for (i = 0, j = 3; i < setnum; i++, j++) {
|
||||||
robj *obj = lookupKeyWrite(c->db,c->argv[j]);
|
robj *obj = lookupKeyWrite(c->db,c->argv[j]);
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
@ -2230,7 +2230,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
|||||||
|
|
||||||
while (remaining) {
|
while (remaining) {
|
||||||
if (remaining >= (setnum + 1) &&
|
if (remaining >= (setnum + 1) &&
|
||||||
!strcasecmp(ptrFromObj(c->argv[j]),"weights"))
|
!strcasecmp(szFromObj(c->argv[j]),"weights"))
|
||||||
{
|
{
|
||||||
j++; remaining--;
|
j++; remaining--;
|
||||||
for (i = 0; i < setnum; i++, j++, remaining--) {
|
for (i = 0; i < setnum; i++, j++, remaining--) {
|
||||||
@ -2242,14 +2242,14 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (remaining >= 2 &&
|
} else if (remaining >= 2 &&
|
||||||
!strcasecmp(ptrFromObj(c->argv[j]),"aggregate"))
|
!strcasecmp(szFromObj(c->argv[j]),"aggregate"))
|
||||||
{
|
{
|
||||||
j++; remaining--;
|
j++; remaining--;
|
||||||
if (!strcasecmp(ptrFromObj(c->argv[j]),"sum")) {
|
if (!strcasecmp(szFromObj(c->argv[j]),"sum")) {
|
||||||
aggregate = REDIS_AGGR_SUM;
|
aggregate = REDIS_AGGR_SUM;
|
||||||
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"min")) {
|
} else if (!strcasecmp(szFromObj(c->argv[j]),"min")) {
|
||||||
aggregate = REDIS_AGGR_MIN;
|
aggregate = REDIS_AGGR_MIN;
|
||||||
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"max")) {
|
} else if (!strcasecmp(szFromObj(c->argv[j]),"max")) {
|
||||||
aggregate = REDIS_AGGR_MAX;
|
aggregate = REDIS_AGGR_MAX;
|
||||||
} else {
|
} else {
|
||||||
zfree(src);
|
zfree(src);
|
||||||
@ -2270,7 +2270,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
|||||||
qsort(src,setnum,sizeof(zsetopsrc),zuiCompareByCardinality);
|
qsort(src,setnum,sizeof(zsetopsrc),zuiCompareByCardinality);
|
||||||
|
|
||||||
dstobj = createZsetObject();
|
dstobj = createZsetObject();
|
||||||
dstzset = ptrFromObj(dstobj);
|
dstzset = (zset*)ptrFromObj(dstobj);
|
||||||
memset(&zval, 0, sizeof(zval));
|
memset(&zval, 0, sizeof(zval));
|
||||||
|
|
||||||
if (op == SET_OP_INTER) {
|
if (op == SET_OP_INTER) {
|
||||||
@ -2366,7 +2366,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
|
|||||||
dictExpand(dstzset->pdict,dictSize(accumulator));
|
dictExpand(dstzset->pdict,dictSize(accumulator));
|
||||||
|
|
||||||
while((de = dictNext(di)) != NULL) {
|
while((de = dictNext(di)) != NULL) {
|
||||||
sds ele = dictGetKey(de);
|
sds ele = (sds)dictGetKey(de);
|
||||||
score = dictGetDoubleVal(de);
|
score = dictGetDoubleVal(de);
|
||||||
znode = zslInsert(dstzset->zsl,score,ele);
|
znode = zslInsert(dstzset->zsl,score,ele);
|
||||||
dictAdd(dstzset->pdict,ele,&znode->score);
|
dictAdd(dstzset->pdict,ele,&znode->score);
|
||||||
@ -2420,7 +2420,7 @@ void zrangeGenericCommand(client *c, int reverse) {
|
|||||||
if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) ||
|
if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) ||
|
||||||
(getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK)) return;
|
(getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK)) return;
|
||||||
|
|
||||||
if (c->argc == 5 && !strcasecmp(ptrFromObj(c->argv[4]),"withscores")) {
|
if (c->argc == 5 && !strcasecmp(szFromObj(c->argv[4]),"withscores")) {
|
||||||
withscores = 1;
|
withscores = 1;
|
||||||
} else if (c->argc >= 5) {
|
} else if (c->argc >= 5) {
|
||||||
addReply(c,shared.syntaxerr);
|
addReply(c,shared.syntaxerr);
|
||||||
@ -2454,7 +2454,7 @@ void zrangeGenericCommand(client *c, int reverse) {
|
|||||||
addReplyArrayLen(c, rangelen);
|
addReplyArrayLen(c, rangelen);
|
||||||
|
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl = zobj->m_ptr;
|
unsigned char *zl = (unsigned char*)zobj->m_ptr;
|
||||||
unsigned char *eptr, *sptr;
|
unsigned char *eptr, *sptr;
|
||||||
unsigned char *vstr;
|
unsigned char *vstr;
|
||||||
unsigned int vlen;
|
unsigned int vlen;
|
||||||
@ -2486,7 +2486,7 @@ void zrangeGenericCommand(client *c, int reverse) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
zskiplist *zsl = zs->zsl;
|
zskiplist *zsl = zs->zsl;
|
||||||
zskiplistNode *ln;
|
zskiplistNode *ln;
|
||||||
sds ele;
|
sds ele;
|
||||||
@ -2497,7 +2497,7 @@ void zrangeGenericCommand(client *c, int reverse) {
|
|||||||
if (start > 0)
|
if (start > 0)
|
||||||
ln = zslGetElementByRank(zsl,llen-start);
|
ln = zslGetElementByRank(zsl,llen-start);
|
||||||
} else {
|
} else {
|
||||||
ln = zsl->header->level[0].forward;
|
ln = zsl->header->level(0)->forward;
|
||||||
if (start > 0)
|
if (start > 0)
|
||||||
ln = zslGetElementByRank(zsl,start+1);
|
ln = zslGetElementByRank(zsl,start+1);
|
||||||
}
|
}
|
||||||
@ -2508,7 +2508,7 @@ void zrangeGenericCommand(client *c, int reverse) {
|
|||||||
if (withscores && c->resp > 2) addReplyArrayLen(c,2);
|
if (withscores && c->resp > 2) addReplyArrayLen(c,2);
|
||||||
addReplyBulkCBuffer(c,ele,sdslen(ele));
|
addReplyBulkCBuffer(c,ele,sdslen(ele));
|
||||||
if (withscores) addReplyDouble(c,ln->score);
|
if (withscores) addReplyDouble(c,ln->score);
|
||||||
ln = reverse ? ln->backward : ln->level[0].forward;
|
ln = reverse ? ln->backward : ln->level(0)->forward;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
serverPanic("Unknown sorted set encoding");
|
serverPanic("Unknown sorted set encoding");
|
||||||
@ -2555,10 +2555,10 @@ void genericZrangebyscoreCommand(client *c, int reverse) {
|
|||||||
int pos = 4;
|
int pos = 4;
|
||||||
|
|
||||||
while (remaining) {
|
while (remaining) {
|
||||||
if (remaining >= 1 && !strcasecmp(ptrFromObj(c->argv[pos]),"withscores")) {
|
if (remaining >= 1 && !strcasecmp(szFromObj(c->argv[pos]),"withscores")) {
|
||||||
pos++; remaining--;
|
pos++; remaining--;
|
||||||
withscores = 1;
|
withscores = 1;
|
||||||
} else if (remaining >= 3 && !strcasecmp(ptrFromObj(c->argv[pos]),"limit")) {
|
} else if (remaining >= 3 && !strcasecmp(szFromObj(c->argv[pos]),"limit")) {
|
||||||
if ((getLongFromObjectOrReply(c, c->argv[pos+1], &offset, NULL)
|
if ((getLongFromObjectOrReply(c, c->argv[pos+1], &offset, NULL)
|
||||||
!= C_OK) ||
|
!= C_OK) ||
|
||||||
(getLongFromObjectOrReply(c, c->argv[pos+2], &limit, NULL)
|
(getLongFromObjectOrReply(c, c->argv[pos+2], &limit, NULL)
|
||||||
@ -2579,7 +2579,7 @@ void genericZrangebyscoreCommand(client *c, int reverse) {
|
|||||||
checkType(c,zobj,OBJ_ZSET)) return;
|
checkType(c,zobj,OBJ_ZSET)) return;
|
||||||
|
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl = zobj->m_ptr;
|
unsigned char *zl = (unsigned char*)zobj->m_ptr;
|
||||||
unsigned char *eptr, *sptr;
|
unsigned char *eptr, *sptr;
|
||||||
unsigned char *vstr;
|
unsigned char *vstr;
|
||||||
unsigned int vlen;
|
unsigned int vlen;
|
||||||
@ -2649,7 +2649,7 @@ void genericZrangebyscoreCommand(client *c, int reverse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
zskiplist *zsl = zs->zsl;
|
zskiplist *zsl = zs->zsl;
|
||||||
zskiplistNode *ln;
|
zskiplistNode *ln;
|
||||||
|
|
||||||
@ -2677,7 +2677,7 @@ void genericZrangebyscoreCommand(client *c, int reverse) {
|
|||||||
if (reverse) {
|
if (reverse) {
|
||||||
ln = ln->backward;
|
ln = ln->backward;
|
||||||
} else {
|
} else {
|
||||||
ln = ln->level[0].forward;
|
ln = ln->level(0)->forward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2698,7 +2698,7 @@ void genericZrangebyscoreCommand(client *c, int reverse) {
|
|||||||
if (reverse) {
|
if (reverse) {
|
||||||
ln = ln->backward;
|
ln = ln->backward;
|
||||||
} else {
|
} else {
|
||||||
ln = ln->level[0].forward;
|
ln = ln->level(0)->forward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2734,7 +2734,7 @@ void zcountCommand(client *c) {
|
|||||||
checkType(c, zobj, OBJ_ZSET)) return;
|
checkType(c, zobj, OBJ_ZSET)) return;
|
||||||
|
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl = zobj->m_ptr;
|
unsigned char *zl = (unsigned char*)zobj->m_ptr;
|
||||||
unsigned char *eptr, *sptr;
|
unsigned char *eptr, *sptr;
|
||||||
double score;
|
double score;
|
||||||
|
|
||||||
@ -2765,7 +2765,7 @@ void zcountCommand(client *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
zskiplist *zsl = zs->zsl;
|
zskiplist *zsl = zs->zsl;
|
||||||
zskiplistNode *zn;
|
zskiplistNode *zn;
|
||||||
unsigned long rank;
|
unsigned long rank;
|
||||||
@ -2815,7 +2815,7 @@ void zlexcountCommand(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl = zobj->m_ptr;
|
unsigned char *zl = (unsigned char*)zobj->m_ptr;
|
||||||
unsigned char *eptr, *sptr;
|
unsigned char *eptr, *sptr;
|
||||||
|
|
||||||
/* Use the first element in range as the starting point */
|
/* Use the first element in range as the starting point */
|
||||||
@ -2843,7 +2843,7 @@ void zlexcountCommand(client *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
zskiplist *zsl = zs->zsl;
|
zskiplist *zsl = zs->zsl;
|
||||||
zskiplistNode *zn;
|
zskiplistNode *zn;
|
||||||
unsigned long rank;
|
unsigned long rank;
|
||||||
@ -2904,7 +2904,7 @@ void genericZrangebylexCommand(client *c, int reverse) {
|
|||||||
int pos = 4;
|
int pos = 4;
|
||||||
|
|
||||||
while (remaining) {
|
while (remaining) {
|
||||||
if (remaining >= 3 && !strcasecmp(ptrFromObj(c->argv[pos]),"limit")) {
|
if (remaining >= 3 && !strcasecmp(szFromObj(c->argv[pos]),"limit")) {
|
||||||
if ((getLongFromObjectOrReply(c, c->argv[pos+1], &offset, NULL) != C_OK) ||
|
if ((getLongFromObjectOrReply(c, c->argv[pos+1], &offset, NULL) != C_OK) ||
|
||||||
(getLongFromObjectOrReply(c, c->argv[pos+2], &limit, NULL) != C_OK)) {
|
(getLongFromObjectOrReply(c, c->argv[pos+2], &limit, NULL) != C_OK)) {
|
||||||
zslFreeLexRange(&range);
|
zslFreeLexRange(&range);
|
||||||
@ -2928,7 +2928,7 @@ void genericZrangebylexCommand(client *c, int reverse) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl = zobj->m_ptr;
|
unsigned char *zl = (unsigned char*)zobj->m_ptr;
|
||||||
unsigned char *eptr, *sptr;
|
unsigned char *eptr, *sptr;
|
||||||
unsigned char *vstr;
|
unsigned char *vstr;
|
||||||
unsigned int vlen;
|
unsigned int vlen;
|
||||||
@ -2994,7 +2994,7 @@ void genericZrangebylexCommand(client *c, int reverse) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
zskiplist *zsl = zs->zsl;
|
zskiplist *zsl = zs->zsl;
|
||||||
zskiplistNode *ln;
|
zskiplistNode *ln;
|
||||||
|
|
||||||
@ -3023,7 +3023,7 @@ void genericZrangebylexCommand(client *c, int reverse) {
|
|||||||
if (reverse) {
|
if (reverse) {
|
||||||
ln = ln->backward;
|
ln = ln->backward;
|
||||||
} else {
|
} else {
|
||||||
ln = ln->level[0].forward;
|
ln = ln->level(0)->forward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3042,7 +3042,7 @@ void genericZrangebylexCommand(client *c, int reverse) {
|
|||||||
if (reverse) {
|
if (reverse) {
|
||||||
ln = ln->backward;
|
ln = ln->backward;
|
||||||
} else {
|
} else {
|
||||||
ln = ln->level[0].forward;
|
ln = ln->level(0)->forward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3079,7 +3079,7 @@ void zscoreCommand(client *c) {
|
|||||||
if ((zobj = lookupKeyReadOrReply(c,key,shared.null[c->resp])) == NULL ||
|
if ((zobj = lookupKeyReadOrReply(c,key,shared.null[c->resp])) == NULL ||
|
||||||
checkType(c,zobj,OBJ_ZSET)) return;
|
checkType(c,zobj,OBJ_ZSET)) return;
|
||||||
|
|
||||||
if (zsetScore(zobj,ptrFromObj(c->argv[2]),&score) == C_ERR) {
|
if (zsetScore(zobj,szFromObj(c->argv[2]),&score) == C_ERR) {
|
||||||
addReplyNull(c);
|
addReplyNull(c);
|
||||||
} else {
|
} else {
|
||||||
addReplyDouble(c,score);
|
addReplyDouble(c,score);
|
||||||
@ -3096,7 +3096,7 @@ void zrankGenericCommand(client *c, int reverse) {
|
|||||||
checkType(c,zobj,OBJ_ZSET)) return;
|
checkType(c,zobj,OBJ_ZSET)) return;
|
||||||
|
|
||||||
serverAssertWithInfo(c,ele,sdsEncodedObject(ele));
|
serverAssertWithInfo(c,ele,sdsEncodedObject(ele));
|
||||||
rank = zsetRank(zobj,ptrFromObj(ele),reverse);
|
rank = zsetRank(zobj,szFromObj(ele),reverse);
|
||||||
if (rank >= 0) {
|
if (rank >= 0) {
|
||||||
addReplyLongLong(c,rank);
|
addReplyLongLong(c,rank);
|
||||||
} else {
|
} else {
|
||||||
@ -3174,7 +3174,7 @@ void genericZpopCommand(client *c, robj **keyv, int keyc, int where, int emitkey
|
|||||||
/* Remove the element. */
|
/* Remove the element. */
|
||||||
do {
|
do {
|
||||||
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||||
unsigned char *zl = zobj->m_ptr;
|
unsigned char *zl = (unsigned char*)zobj->m_ptr;
|
||||||
unsigned char *eptr, *sptr;
|
unsigned char *eptr, *sptr;
|
||||||
unsigned char *vstr;
|
unsigned char *vstr;
|
||||||
unsigned int vlen;
|
unsigned int vlen;
|
||||||
@ -3194,13 +3194,13 @@ void genericZpopCommand(client *c, robj **keyv, int keyc, int where, int emitkey
|
|||||||
serverAssertWithInfo(c,zobj,sptr != NULL);
|
serverAssertWithInfo(c,zobj,sptr != NULL);
|
||||||
score = zzlGetScore(sptr);
|
score = zzlGetScore(sptr);
|
||||||
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||||
zset *zs = zobj->m_ptr;
|
zset *zs = (zset*)zobj->m_ptr;
|
||||||
zskiplist *zsl = zs->zsl;
|
zskiplist *zsl = zs->zsl;
|
||||||
zskiplistNode *zln;
|
zskiplistNode *zln;
|
||||||
|
|
||||||
/* Get the first or last element in the sorted set. */
|
/* Get the first or last element in the sorted set. */
|
||||||
zln = (where == ZSET_MAX ? zsl->tail :
|
zln = (where == ZSET_MAX ? zsl->tail :
|
||||||
zsl->header->level[0].forward);
|
zsl->header->level(0)->forward);
|
||||||
|
|
||||||
/* There must be an element in the sorted set. */
|
/* There must be an element in the sorted set. */
|
||||||
serverAssertWithInfo(c,zobj,zln != NULL);
|
serverAssertWithInfo(c,zobj,zln != NULL);
|
||||||
@ -3214,7 +3214,7 @@ void genericZpopCommand(client *c, robj **keyv, int keyc, int where, int emitkey
|
|||||||
server.dirty++;
|
server.dirty++;
|
||||||
|
|
||||||
if (arraylen == 0) { /* Do this only for the first iteration. */
|
if (arraylen == 0) { /* Do this only for the first iteration. */
|
||||||
char *events[2] = {"zpopmin","zpopmax"};
|
const char *events[2] = {"zpopmin","zpopmax"};
|
||||||
notifyKeyspaceEvent(NOTIFY_ZSET,events[where],key,c->db->id);
|
notifyKeyspaceEvent(NOTIFY_ZSET,events[where],key,c->db->id);
|
||||||
signalModifiedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
}
|
}
|
@ -34,6 +34,10 @@
|
|||||||
#define ZIPLIST_HEAD 0
|
#define ZIPLIST_HEAD 0
|
||||||
#define ZIPLIST_TAIL 1
|
#define ZIPLIST_TAIL 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned char *ziplistNew(void);
|
unsigned char *ziplistNew(void);
|
||||||
unsigned char *ziplistMerge(unsigned char **first, unsigned char **second);
|
unsigned char *ziplistMerge(unsigned char **first, unsigned char **second);
|
||||||
unsigned char *ziplistPush(unsigned char *zl, unsigned char *s, unsigned int slen, int where);
|
unsigned char *ziplistPush(unsigned char *zl, unsigned char *s, unsigned int slen, int where);
|
||||||
@ -54,4 +58,8 @@ void ziplistRepr(unsigned char *zl);
|
|||||||
int ziplistTest(int argc, char *argv[]);
|
int ziplistTest(int argc, char *argv[]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _ZIPLIST_H */
|
#endif /* _ZIPLIST_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user