Unverified Commit cbb2ac07 authored by chendianqiang's avatar chendianqiang Committed by GitHub
Browse files

Merge branch 'unstable' into pending-querybuf

parents 7de1ada0 2edcafb3
...@@ -142,6 +142,7 @@ typedef long long mstime_t; /* millisecond time type. */ ...@@ -142,6 +142,7 @@ typedef long long mstime_t; /* millisecond time type. */
#define CONFIG_DEFAULT_AOF_USE_RDB_PREAMBLE 1 #define CONFIG_DEFAULT_AOF_USE_RDB_PREAMBLE 1
#define CONFIG_DEFAULT_ACTIVE_REHASHING 1 #define CONFIG_DEFAULT_ACTIVE_REHASHING 1
#define CONFIG_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC 1 #define CONFIG_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC 1
#define CONFIG_DEFAULT_RDB_SAVE_INCREMENTAL_FSYNC 1
#define CONFIG_DEFAULT_MIN_SLAVES_TO_WRITE 0 #define CONFIG_DEFAULT_MIN_SLAVES_TO_WRITE 0
#define CONFIG_DEFAULT_MIN_SLAVES_MAX_LAG 10 #define CONFIG_DEFAULT_MIN_SLAVES_MAX_LAG 10
#define NET_IP_STR_LEN 46 /* INET6_ADDRSTRLEN is 46, but we need to be sure */ #define NET_IP_STR_LEN 46 /* INET6_ADDRSTRLEN is 46, but we need to be sure */
...@@ -183,7 +184,8 @@ typedef long long mstime_t; /* millisecond time type. */ ...@@ -183,7 +184,8 @@ typedef long long mstime_t; /* millisecond time type. */
#define PROTO_INLINE_MAX_SIZE (1024*64) /* Max size of inline reads */ #define PROTO_INLINE_MAX_SIZE (1024*64) /* Max size of inline reads */
#define PROTO_MBULK_BIG_ARG (1024*32) #define PROTO_MBULK_BIG_ARG (1024*32)
#define LONG_STR_SIZE 21 /* Bytes needed for long -> str + '\0' */ #define LONG_STR_SIZE 21 /* Bytes needed for long -> str + '\0' */
#define AOF_AUTOSYNC_BYTES (1024*1024*32) /* fdatasync every 32MB */ #define REDIS_AUTOSYNC_BYTES (1024*1024*32) /* fdatasync every 32MB */
#define LIMIT_PENDING_QUERYBUF (4*1024*1024) /* 4mb */ #define LIMIT_PENDING_QUERYBUF (4*1024*1024) /* 4mb */
/* When configuring the server eventloop, we setup it so that the total number /* When configuring the server eventloop, we setup it so that the total number
...@@ -340,7 +342,7 @@ typedef long long mstime_t; /* millisecond time type. */ ...@@ -340,7 +342,7 @@ typedef long long mstime_t; /* millisecond time type. */
/* Anti-warning macro... */ /* Anti-warning macro... */
#define UNUSED(V) ((void) V) #define UNUSED(V) ((void) V)
#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^32 elements */ #define ZSKIPLIST_MAXLEVEL 64 /* Should be enough for 2^64 elements */
#define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */ #define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */
/* Append only defines */ /* Append only defines */
...@@ -349,12 +351,14 @@ typedef long long mstime_t; /* millisecond time type. */ ...@@ -349,12 +351,14 @@ typedef long long mstime_t; /* millisecond time type. */
#define AOF_FSYNC_EVERYSEC 2 #define AOF_FSYNC_EVERYSEC 2
#define CONFIG_DEFAULT_AOF_FSYNC AOF_FSYNC_EVERYSEC #define CONFIG_DEFAULT_AOF_FSYNC AOF_FSYNC_EVERYSEC
/* Zip structure related defaults */ /* Zipped structures related defaults */
#define OBJ_HASH_MAX_ZIPLIST_ENTRIES 512 #define OBJ_HASH_MAX_ZIPLIST_ENTRIES 512
#define OBJ_HASH_MAX_ZIPLIST_VALUE 64 #define OBJ_HASH_MAX_ZIPLIST_VALUE 64
#define OBJ_SET_MAX_INTSET_ENTRIES 512 #define OBJ_SET_MAX_INTSET_ENTRIES 512
#define OBJ_ZSET_MAX_ZIPLIST_ENTRIES 128 #define OBJ_ZSET_MAX_ZIPLIST_ENTRIES 128
#define OBJ_ZSET_MAX_ZIPLIST_VALUE 64 #define OBJ_ZSET_MAX_ZIPLIST_VALUE 64
#define OBJ_STREAM_NODE_MAX_BYTES 4096
#define OBJ_STREAM_NODE_MAX_ENTRIES 100
/* List defaults */ /* List defaults */
#define OBJ_LIST_MAX_ZIPLIST_SIZE -2 #define OBJ_LIST_MAX_ZIPLIST_SIZE -2
...@@ -781,7 +785,7 @@ typedef struct zskiplistNode { ...@@ -781,7 +785,7 @@ typedef struct zskiplistNode {
struct zskiplistNode *backward; struct zskiplistNode *backward;
struct zskiplistLevel { struct zskiplistLevel {
struct zskiplistNode *forward; struct zskiplistNode *forward;
unsigned int span; unsigned long span;
} level[]; } level[];
} zskiplistNode; } zskiplistNode;
...@@ -880,13 +884,13 @@ typedef struct rdbSaveInfo { ...@@ -880,13 +884,13 @@ typedef struct rdbSaveInfo {
#define RDB_SAVE_INFO_INIT {-1,0,"000000000000000000000000000000",-1} #define RDB_SAVE_INFO_INIT {-1,0,"000000000000000000000000000000",-1}
typedef struct malloc_stats { struct malloc_stats {
size_t zmalloc_used; size_t zmalloc_used;
size_t process_rss; size_t process_rss;
size_t allocator_allocated; size_t allocator_allocated;
size_t allocator_active; size_t allocator_active;
size_t allocator_resident; size_t allocator_resident;
} malloc_stats; };
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
* Global server state * Global server state
...@@ -950,6 +954,7 @@ struct redisServer { ...@@ -950,6 +954,7 @@ struct redisServer {
list *clients_pending_write; /* There is to write or install handler. */ list *clients_pending_write; /* There is to write or install handler. */
list *slaves, *monitors; /* List of slaves and MONITORs */ list *slaves, *monitors; /* List of slaves and MONITORs */
client *current_client; /* Current client, only used on crash report */ client *current_client; /* Current client, only used on crash report */
rax *clients_index; /* Active clients dictionary by client ID. */
int clients_paused; /* True if clients are currently paused */ int clients_paused; /* True if clients are currently paused */
mstime_t clients_pause_end_time; /* Time when we undo clients_paused */ mstime_t clients_pause_end_time; /* Time when we undo clients_paused */
char neterr[ANET_ERR_LEN]; /* Error buffer for anet.c */ char neterr[ANET_ERR_LEN]; /* Error buffer for anet.c */
...@@ -993,7 +998,7 @@ struct redisServer { ...@@ -993,7 +998,7 @@ struct redisServer {
long long slowlog_entry_id; /* SLOWLOG current entry ID */ long long slowlog_entry_id; /* SLOWLOG current entry ID */
long long slowlog_log_slower_than; /* SLOWLOG time limit (to get logged) */ long long slowlog_log_slower_than; /* SLOWLOG time limit (to get logged) */
unsigned long slowlog_max_len; /* SLOWLOG max number of items logged */ unsigned long slowlog_max_len; /* SLOWLOG max number of items logged */
malloc_stats cron_malloc_stats; /* sampled in serverCron(). */ struct malloc_stats cron_malloc_stats; /* sampled in serverCron(). */
long long stat_net_input_bytes; /* Bytes read from network. */ long long stat_net_input_bytes; /* Bytes read from network. */
long long stat_net_output_bytes; /* Bytes written to network. */ long long stat_net_output_bytes; /* Bytes written to network. */
size_t stat_rdb_cow_bytes; /* Copy on write bytes during RDB saving. */ size_t stat_rdb_cow_bytes; /* Copy on write bytes during RDB saving. */
...@@ -1045,7 +1050,8 @@ struct redisServer { ...@@ -1045,7 +1050,8 @@ struct redisServer {
time_t aof_rewrite_time_start; /* Current AOF rewrite start time. */ time_t aof_rewrite_time_start; /* Current AOF rewrite start time. */
int aof_lastbgrewrite_status; /* C_OK or C_ERR */ int aof_lastbgrewrite_status; /* C_OK or C_ERR */
unsigned long aof_delayed_fsync; /* delayed AOF fsync() counter */ unsigned long aof_delayed_fsync; /* delayed AOF fsync() counter */
int aof_rewrite_incremental_fsync;/* fsync incrementally while rewriting? */ int aof_rewrite_incremental_fsync;/* fsync incrementally while aof rewriting? */
int rdb_save_incremental_fsync; /* fsync incrementally while rdb saving? */
int aof_last_write_status; /* C_OK or C_ERR */ int aof_last_write_status; /* C_OK or C_ERR */
int aof_last_write_errno; /* Valid if aof_last_write_status is ERR */ int aof_last_write_errno; /* Valid if aof_last_write_status is ERR */
int aof_load_truncated; /* Don't stop on unexpected AOF EOF. */ int aof_load_truncated; /* Don't stop on unexpected AOF EOF. */
...@@ -1178,6 +1184,8 @@ struct redisServer { ...@@ -1178,6 +1184,8 @@ struct redisServer {
size_t zset_max_ziplist_entries; size_t zset_max_ziplist_entries;
size_t zset_max_ziplist_value; size_t zset_max_ziplist_value;
size_t hll_sparse_max_bytes; size_t hll_sparse_max_bytes;
size_t stream_node_max_bytes;
int64_t stream_node_max_entries;
/* List parameters */ /* List parameters */
int list_max_ziplist_size; int list_max_ziplist_size;
int list_compress_depth; int list_compress_depth;
...@@ -1407,6 +1415,7 @@ void addReplyHumanLongDouble(client *c, long double d); ...@@ -1407,6 +1415,7 @@ void addReplyHumanLongDouble(client *c, long double d);
void addReplyLongLong(client *c, long long ll); void addReplyLongLong(client *c, long long ll);
void addReplyMultiBulkLen(client *c, long length); void addReplyMultiBulkLen(client *c, long length);
void addReplyHelp(client *c, const char **help); void addReplyHelp(client *c, const char **help);
void addReplySubcommandSyntaxError(client *c);
void copyClientOutputBuffer(client *dst, client *src); void copyClientOutputBuffer(client *dst, client *src);
size_t sdsZmallocSize(sds s); size_t sdsZmallocSize(sds s);
size_t getStringObjectSdsUsedMemory(robj *o); size_t getStringObjectSdsUsedMemory(robj *o);
...@@ -1415,7 +1424,7 @@ void getClientsMaxBuffers(unsigned long *longest_output_list, ...@@ -1415,7 +1424,7 @@ void getClientsMaxBuffers(unsigned long *longest_output_list,
unsigned long *biggest_input_buffer); unsigned long *biggest_input_buffer);
char *getClientPeerId(client *client); char *getClientPeerId(client *client);
sds catClientInfoString(sds s, client *client); sds catClientInfoString(sds s, client *client);
sds getAllClientsInfoString(void); sds getAllClientsInfoString(int type);
void rewriteClientCommandVector(client *c, int argc, ...); void rewriteClientCommandVector(client *c, int argc, ...);
void rewriteClientCommandArgument(client *c, int i, robj *newval); void rewriteClientCommandArgument(client *c, int i, robj *newval);
void replaceClientCommandVector(client *c, int argc, robj **argv); void replaceClientCommandVector(client *c, int argc, robj **argv);
...@@ -1496,6 +1505,7 @@ robj *tryObjectEncoding(robj *o); ...@@ -1496,6 +1505,7 @@ robj *tryObjectEncoding(robj *o);
robj *getDecodedObject(robj *o); robj *getDecodedObject(robj *o);
size_t stringObjectLen(robj *o); size_t stringObjectLen(robj *o);
robj *createStringObjectFromLongLong(long long value); robj *createStringObjectFromLongLong(long long value);
robj *createStringObjectFromLongLongForValue(long long value);
robj *createStringObjectFromLongDouble(long double value, int humanfriendly); robj *createStringObjectFromLongDouble(long double value, int humanfriendly);
robj *createQuicklistObject(void); robj *createQuicklistObject(void);
robj *createZiplistObject(void); robj *createZiplistObject(void);
...@@ -1625,7 +1635,7 @@ void zzlNext(unsigned char *zl, unsigned char **eptr, unsigned char **sptr); ...@@ -1625,7 +1635,7 @@ void zzlNext(unsigned char *zl, unsigned char **eptr, unsigned char **sptr);
void zzlPrev(unsigned char *zl, unsigned char **eptr, unsigned char **sptr); void zzlPrev(unsigned char *zl, unsigned char **eptr, unsigned char **sptr);
unsigned char *zzlFirstInRange(unsigned char *zl, zrangespec *range); unsigned char *zzlFirstInRange(unsigned char *zl, zrangespec *range);
unsigned char *zzlLastInRange(unsigned char *zl, zrangespec *range); unsigned char *zzlLastInRange(unsigned char *zl, zrangespec *range);
unsigned int zsetLength(const robj *zobj); unsigned long zsetLength(const robj *zobj);
void zsetConvert(robj *zobj, int encoding); void zsetConvert(robj *zobj, int encoding);
void zsetConvertToZiplistIfNeeded(robj *zobj, size_t maxelelen); void zsetConvertToZiplistIfNeeded(robj *zobj, size_t maxelelen);
int zsetScore(robj *zobj, sds member, double *score); int zsetScore(robj *zobj, sds member, double *score);
...@@ -1766,6 +1776,8 @@ robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply); ...@@ -1766,6 +1776,8 @@ robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply);
robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags); robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags);
robj *objectCommandLookup(client *c, robj *key); robj *objectCommandLookup(client *c, robj *key);
robj *objectCommandLookupOrReply(client *c, robj *key, robj *reply); robj *objectCommandLookupOrReply(client *c, robj *key, robj *reply);
void objectSetLRUOrLFU(robj *val, long long lfu_freq, long long lru_idle,
long long lru_clock);
#define LOOKUP_NONE 0 #define LOOKUP_NONE 0
#define LOOKUP_NOTOUCH (1<<0) #define LOOKUP_NOTOUCH (1<<0)
void dbAdd(redisDb *db, robj *key, robj *val); void dbAdd(redisDb *db, robj *key, robj *val);
......
...@@ -142,12 +142,12 @@ uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k) { ...@@ -142,12 +142,12 @@ uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k) {
} }
switch (left) { switch (left) {
case 7: b |= ((uint64_t)in[6]) << 48; case 7: b |= ((uint64_t)in[6]) << 48; /* fall-thru */
case 6: b |= ((uint64_t)in[5]) << 40; case 6: b |= ((uint64_t)in[5]) << 40; /* fall-thru */
case 5: b |= ((uint64_t)in[4]) << 32; case 5: b |= ((uint64_t)in[4]) << 32; /* fall-thru */
case 4: b |= ((uint64_t)in[3]) << 24; case 4: b |= ((uint64_t)in[3]) << 24; /* fall-thru */
case 3: b |= ((uint64_t)in[2]) << 16; case 3: b |= ((uint64_t)in[2]) << 16; /* fall-thru */
case 2: b |= ((uint64_t)in[1]) << 8; case 2: b |= ((uint64_t)in[1]) << 8; /* fall-thru */
case 1: b |= ((uint64_t)in[0]); break; case 1: b |= ((uint64_t)in[0]); break;
case 0: break; case 0: break;
} }
...@@ -202,12 +202,12 @@ uint64_t siphash_nocase(const uint8_t *in, const size_t inlen, const uint8_t *k) ...@@ -202,12 +202,12 @@ uint64_t siphash_nocase(const uint8_t *in, const size_t inlen, const uint8_t *k)
} }
switch (left) { switch (left) {
case 7: b |= ((uint64_t)siptlw(in[6])) << 48; case 7: b |= ((uint64_t)siptlw(in[6])) << 48; /* fall-thru */
case 6: b |= ((uint64_t)siptlw(in[5])) << 40; case 6: b |= ((uint64_t)siptlw(in[5])) << 40; /* fall-thru */
case 5: b |= ((uint64_t)siptlw(in[4])) << 32; case 5: b |= ((uint64_t)siptlw(in[4])) << 32; /* fall-thru */
case 4: b |= ((uint64_t)siptlw(in[3])) << 24; case 4: b |= ((uint64_t)siptlw(in[3])) << 24; /* fall-thru */
case 3: b |= ((uint64_t)siptlw(in[2])) << 16; case 3: b |= ((uint64_t)siptlw(in[2])) << 16; /* fall-thru */
case 2: b |= ((uint64_t)siptlw(in[1])) << 8; case 2: b |= ((uint64_t)siptlw(in[1])) << 8; /* fall-thru */
case 1: b |= ((uint64_t)siptlw(in[0])); break; case 1: b |= ((uint64_t)siptlw(in[0])); break;
case 0: break; case 0: break;
} }
......
...@@ -142,11 +142,11 @@ void slowlogReset(void) { ...@@ -142,11 +142,11 @@ void slowlogReset(void) {
void slowlogCommand(client *c) { void slowlogCommand(client *c) {
if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) { if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"help")) {
const char *help[] = { const char *help[] = {
"get [count] -- Return top entries from the slowlog (default: 10)." "GET [count] -- Return top entries from the slowlog (default: 10)."
" Entries are made of:", " Entries are made of:",
" id, timestamp, time in microseconds, arguments array, client IP and port, client name", " id, timestamp, time in microseconds, arguments array, client IP and port, client name",
"len -- Return the length of the slowlog.", "LEN -- Return the length of the slowlog.",
"reset -- Reset the slowlog.", "RESET -- Reset the slowlog.",
NULL NULL
}; };
addReplyHelp(c, help); addReplyHelp(c, help);
...@@ -187,6 +187,6 @@ NULL ...@@ -187,6 +187,6 @@ NULL
} }
setDeferredMultiBulkLength(c,totentries,sent); setDeferredMultiBulkLength(c,totentries,sent);
} else { } else {
addReplyErrorFormat(c, "Unknown subcommand or wrong number of arguments for '%s'. Try SLOWLOG HELP", (char*)c->argv[1]->ptr); addReplySubcommandSyntaxError(c);
} }
} }
...@@ -447,7 +447,7 @@ void sortCommand(client *c) { ...@@ -447,7 +447,7 @@ void sortCommand(client *c) {
serverAssertWithInfo(c,sortval,j == vectorlen); serverAssertWithInfo(c,sortval,j == vectorlen);
/* Now it's time to load the right scores in the sorting vector */ /* Now it's time to load the right scores in the sorting vector */
if (dontsort == 0) { if (!dontsort) {
for (j = 0; j < vectorlen; j++) { for (j = 0; j < vectorlen; j++) {
robj *byval; robj *byval;
if (sortby) { if (sortby) {
...@@ -487,9 +487,7 @@ void sortCommand(client *c) { ...@@ -487,9 +487,7 @@ void sortCommand(client *c) {
decrRefCount(byval); decrRefCount(byval);
} }
} }
}
if (dontsort == 0) {
server.sort_desc = desc; server.sort_desc = desc;
server.sort_alpha = alpha; server.sort_alpha = alpha;
server.sort_bypattern = sortby ? 1 : 0; server.sort_bypattern = sortby ? 1 : 0;
......
This diff is collapsed.
...@@ -361,7 +361,7 @@ void incrDecrCommand(client *c, long long incr) { ...@@ -361,7 +361,7 @@ void incrDecrCommand(client *c, long long incr) {
new = o; new = o;
o->ptr = (void*)((long)value); o->ptr = (void*)((long)value);
} else { } else {
new = createStringObjectFromLongLong(value); new = createStringObjectFromLongLongForValue(value);
if (o) { if (o) {
dbOverwrite(c->db,c->argv[1],new); dbOverwrite(c->db,c->argv[1],new);
} else { } else {
......
...@@ -1100,8 +1100,8 @@ unsigned char *zzlDeleteRangeByRank(unsigned char *zl, unsigned int start, unsig ...@@ -1100,8 +1100,8 @@ unsigned char *zzlDeleteRangeByRank(unsigned char *zl, unsigned int start, unsig
* Common sorted set API * Common sorted set API
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
unsigned int zsetLength(const robj *zobj) { unsigned long zsetLength(const robj *zobj) {
int length = -1; unsigned long length = 0;
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
length = zzlLength(zobj->ptr); length = zzlLength(zobj->ptr);
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
...@@ -1878,7 +1878,7 @@ void zuiClearIterator(zsetopsrc *op) { ...@@ -1878,7 +1878,7 @@ void zuiClearIterator(zsetopsrc *op) {
} }
} }
int zuiLength(zsetopsrc *op) { unsigned long zuiLength(zsetopsrc *op) {
if (op->subject == NULL) if (op->subject == NULL)
return 0; return 0;
...@@ -2085,7 +2085,11 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) { ...@@ -2085,7 +2085,11 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) {
} }
int zuiCompareByCardinality(const void *s1, const void *s2) { int zuiCompareByCardinality(const void *s1, const void *s2) {
return zuiLength((zsetopsrc*)s1) - zuiLength((zsetopsrc*)s2); unsigned long first = zuiLength((zsetopsrc*)s1);
unsigned long second = zuiLength((zsetopsrc*)s2);
if (first > second) return 1;
if (first < second) return -1;
return 0;
} }
#define REDIS_AGGR_SUM 1 #define REDIS_AGGR_SUM 1
...@@ -2129,7 +2133,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) { ...@@ -2129,7 +2133,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
zsetopsrc *src; zsetopsrc *src;
zsetopval zval; zsetopval zval;
sds tmp; sds tmp;
unsigned int maxelelen = 0; size_t maxelelen = 0;
robj *dstobj; robj *dstobj;
zset *dstzset; zset *dstzset;
zskiplistNode *znode; zskiplistNode *znode;
...@@ -2363,8 +2367,8 @@ void zrangeGenericCommand(client *c, int reverse) { ...@@ -2363,8 +2367,8 @@ void zrangeGenericCommand(client *c, int reverse) {
int withscores = 0; int withscores = 0;
long start; long start;
long end; long end;
int llen; long llen;
int rangelen; long rangelen;
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;
...@@ -2671,7 +2675,7 @@ void zcountCommand(client *c) { ...@@ -2671,7 +2675,7 @@ void zcountCommand(client *c) {
robj *key = c->argv[1]; robj *key = c->argv[1];
robj *zobj; robj *zobj;
zrangespec range; zrangespec range;
int count = 0; unsigned long count = 0;
/* Parse the range arguments */ /* Parse the range arguments */
if (zslParseRange(c->argv[2],c->argv[3],&range) != C_OK) { if (zslParseRange(c->argv[2],c->argv[3],&range) != C_OK) {
...@@ -2748,7 +2752,7 @@ void zlexcountCommand(client *c) { ...@@ -2748,7 +2752,7 @@ void zlexcountCommand(client *c) {
robj *key = c->argv[1]; robj *key = c->argv[1];
robj *zobj; robj *zobj;
zlexrangespec range; zlexrangespec range;
int count = 0; unsigned long count = 0;
/* Parse the range arguments */ /* Parse the range arguments */
if (zslParseLexRange(c->argv[2],c->argv[3],&range) != C_OK) { if (zslParseLexRange(c->argv[2],c->argv[3],&range) != C_OK) {
...@@ -3163,8 +3167,8 @@ void genericZpopCommand(client *c, robj **keyv, int keyc, int where, int emitkey ...@@ -3163,8 +3167,8 @@ void genericZpopCommand(client *c, robj **keyv, int keyc, int where, int emitkey
signalModifiedKey(c->db,key); signalModifiedKey(c->db,key);
} }
addReplyDouble(c,score);
addReplyBulkCBuffer(c,ele,sdslen(ele)); addReplyBulkCBuffer(c,ele,sdslen(ele));
addReplyDouble(c,score);
sdsfree(ele); sdsfree(ele);
arraylen += 2; arraylen += 2;
...@@ -3216,9 +3220,9 @@ void blockingGenericZpopCommand(client *c, int where) { ...@@ -3216,9 +3220,9 @@ void blockingGenericZpopCommand(client *c, int where) {
return; return;
} else { } else {
if (zsetLength(o) != 0) { if (zsetLength(o) != 0) {
/* Non empty zset, this is like a normal Z[REV]POP. */ /* Non empty zset, this is like a normal ZPOP[MIN|MAX]. */
genericZpopCommand(c,&c->argv[j],1,where,1,NULL); genericZpopCommand(c,&c->argv[j],1,where,1,NULL);
/* Replicate it as an Z[REV]POP instead of BZ[REV]POP. */ /* Replicate it as an ZPOP[MIN|MAX] instead of BZPOP[MIN|MAX]. */
rewriteClientCommandVector(c,2, rewriteClientCommandVector(c,2,
where == ZSET_MAX ? shared.zpopmax : shared.zpopmin, where == ZSET_MAX ? shared.zpopmax : shared.zpopmin,
c->argv[j]); c->argv[j]);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* traversal. * traversal.
* *
* <uint16_t zllen> is the number of entries. When there are more than * <uint16_t zllen> is the number of entries. When there are more than
* 2^16-2 entires, this value is set to 2^16-1 and we need to traverse the * 2^16-2 entries, this value is set to 2^16-1 and we need to traverse the
* entire list to know how many items it holds. * entire list to know how many items it holds.
* *
* <uint8_t zlend> is a special entry representing the end of the ziplist. * <uint8_t zlend> is a special entry representing the end of the ziplist.
...@@ -256,7 +256,7 @@ ...@@ -256,7 +256,7 @@
#define ZIPLIST_ENTRY_END(zl) ((zl)+intrev32ifbe(ZIPLIST_BYTES(zl))-1) #define ZIPLIST_ENTRY_END(zl) ((zl)+intrev32ifbe(ZIPLIST_BYTES(zl))-1)
/* Increment the number of items field in the ziplist header. Note that this /* Increment the number of items field in the ziplist header. Note that this
* macro should never overflow the unsigned 16 bit integer, since entires are * macro should never overflow the unsigned 16 bit integer, since entries are
* always pushed one at a time. When UINT16_MAX is reached we want the count * always pushed one at a time. When UINT16_MAX is reached we want the count
* to stay there to signal that a full scan is needed to get the number of * to stay there to signal that a full scan is needed to get the number of
* items inside the ziplist. */ * items inside the ziplist. */
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
/* This function provide us access to the original libc free(). This is useful /* This function provide us access to the original libc free(). This is useful
* for instance to free results obtained by backtrace_symbols(). We need * for instance to free results obtained by backtrace_symbols(). We need
...@@ -164,7 +165,7 @@ void *zrealloc(void *ptr, size_t size) { ...@@ -164,7 +165,7 @@ void *zrealloc(void *ptr, size_t size) {
*((size_t*)newptr) = size; *((size_t*)newptr) = size;
update_zmalloc_stat_free(oldsize); update_zmalloc_stat_free(oldsize);
update_zmalloc_stat_alloc(size); update_zmalloc_stat_alloc(size+PREFIX_SIZE);
return (char*)newptr+PREFIX_SIZE; return (char*)newptr+PREFIX_SIZE;
#endif #endif
} }
...@@ -418,7 +419,7 @@ size_t zmalloc_get_memory_size(void) { ...@@ -418,7 +419,7 @@ size_t zmalloc_get_memory_size(void) {
mib[0] = CTL_HW; mib[0] = CTL_HW;
#if defined(HW_REALMEM) #if defined(HW_REALMEM)
mib[1] = HW_REALMEM; /* FreeBSD. ----------------- */ mib[1] = HW_REALMEM; /* FreeBSD. ----------------- */
#elif defined(HW_PYSMEM) #elif defined(HW_PHYSMEM)
mib[1] = HW_PHYSMEM; /* Others. ------------------ */ mib[1] = HW_PHYSMEM; /* Others. ------------------ */
#endif #endif
unsigned int size = 0; /* 32-bit */ unsigned int size = 0; /* 32-bit */
......
...@@ -63,6 +63,11 @@ ...@@ -63,6 +63,11 @@
#ifndef ZMALLOC_LIB #ifndef ZMALLOC_LIB
#define ZMALLOC_LIB "libc" #define ZMALLOC_LIB "libc"
#ifdef __GLIBC__
#include <malloc.h>
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) malloc_usable_size(p)
#endif
#endif #endif
/* We can enable the Redis defrag capabilities only if we are using Jemalloc /* We can enable the Redis defrag capabilities only if we are using Jemalloc
......
...@@ -39,6 +39,25 @@ start_server [list overrides [list "dir" $server_path]] { ...@@ -39,6 +39,25 @@ start_server [list overrides [list "dir" $server_path]] {
} {0000000000000000000000000000000000000000} } {0000000000000000000000000000000000000000}
} }
start_server [list overrides [list "dir" $server_path]] {
test {Test RDB stream encoding} {
for {set j 0} {$j < 1000} {incr j} {
if {rand() < 0.9} {
r xadd stream * foo $j
} else {
r xadd stream * bar $j
}
}
r xgroup create stream mygroup 0
r xreadgroup GROUP mygroup Alice COUNT 1 STREAMS stream >
set digest [r debug digest]
r debug reload
set newdigest [r debug digest]
assert {$digest eq $newdigest}
r del stream
}
}
# Helper function to start a server and kill it, just to check the error # Helper function to start a server and kill it, just to check the error
# logged. # logged.
set defaults {} set defaults {}
......
...@@ -66,3 +66,13 @@ test "SDOWN is triggered by misconfigured instance repling with errors" { ...@@ -66,3 +66,13 @@ test "SDOWN is triggered by misconfigured instance repling with errors" {
R 0 bgsave R 0 bgsave
ensure_master_up ensure_master_up
} }
# We use this test setup to also test command renaming, as a side
# effect of the master going down if we send PONG instead of PING
test "SDOWN is triggered if we rename PING to PONG" {
ensure_master_up
S 4 SENTINEL SET mymaster rename-command PING PONG
ensure_master_down
S 4 SENTINEL SET mymaster rename-command PING PING
ensure_master_up
}
...@@ -276,6 +276,12 @@ proc start_server {options {code undefined}} { ...@@ -276,6 +276,12 @@ proc start_server {options {code undefined}} {
error_and_quit $config_file $line error_and_quit $config_file $line
} }
if {$::wait_server} {
set msg "server started PID: [dict get $srv "pid"]. press any key to continue..."
puts $msg
read stdin 1
}
while 1 { while 1 {
# check that the server actually started and is ready for connections # check that the server actually started and is ready for connections
if {[exec grep -i "Ready to accept" | wc -l < $stdout] > 0} { if {[exec grep -i "Ready to accept" | wc -l < $stdout] > 0} {
......
...@@ -83,6 +83,8 @@ set ::force_failure 0 ...@@ -83,6 +83,8 @@ set ::force_failure 0
set ::timeout 600; # 10 minutes without progresses will quit the test. set ::timeout 600; # 10 minutes without progresses will quit the test.
set ::last_progress [clock seconds] set ::last_progress [clock seconds]
set ::active_servers {} ; # Pids of active Redis instances. set ::active_servers {} ; # Pids of active Redis instances.
set ::dont_clean 0
set ::wait_server 0
# Set to 1 when we are running in client mode. The Redis test uses a # Set to 1 when we are running in client mode. The Redis test uses a
# server-client model to run tests simultaneously. The server instance # server-client model to run tests simultaneously. The server instance
...@@ -176,6 +178,9 @@ proc s {args} { ...@@ -176,6 +178,9 @@ proc s {args} {
} }
proc cleanup {} { proc cleanup {} {
if {$::dont_clean} {
return
}
if {!$::quiet} {puts -nonewline "Cleanup: may take some time... "} if {!$::quiet} {puts -nonewline "Cleanup: may take some time... "}
flush stdout flush stdout
catch {exec rm -rf {*}[glob tests/tmp/redis.conf.*]} catch {exec rm -rf {*}[glob tests/tmp/redis.conf.*]}
...@@ -225,6 +230,7 @@ proc test_server_cron {} { ...@@ -225,6 +230,7 @@ proc test_server_cron {} {
if {$elapsed > $::timeout} { if {$elapsed > $::timeout} {
set err "\[[colorstr red TIMEOUT]\]: clients state report follows." set err "\[[colorstr red TIMEOUT]\]: clients state report follows."
puts $err puts $err
lappend ::failed_tests $err
show_clients_state show_clients_state
kill_clients kill_clients
force_kill_all_servers force_kill_all_servers
...@@ -411,6 +417,8 @@ proc print_help_screen {} { ...@@ -411,6 +417,8 @@ proc print_help_screen {} {
"--clients <num> Number of test clients (default 16)." "--clients <num> Number of test clients (default 16)."
"--timeout <sec> Test timeout in seconds (default 10 min)." "--timeout <sec> Test timeout in seconds (default 10 min)."
"--force-failure Force the execution of a test that always fails." "--force-failure Force the execution of a test that always fails."
"--dont-clean don't delete redis log files after the run"
"--wait-server wait after server is started (so that you can attach a debugger)"
"--help Print this help screen." "--help Print this help screen."
} "\n"] } "\n"]
} }
...@@ -464,6 +472,10 @@ for {set j 0} {$j < [llength $argv]} {incr j} { ...@@ -464,6 +472,10 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
} elseif {$opt eq {--clients}} { } elseif {$opt eq {--clients}} {
set ::numclients $arg set ::numclients $arg
incr j incr j
} elseif {$opt eq {--dont-clean}} {
set ::dont_clean 1
} elseif {$opt eq {--wait-server}} {
set ::wait_server 1
} elseif {$opt eq {--timeout}} { } elseif {$opt eq {--timeout}} {
set ::timeout $arg set ::timeout $arg
incr j incr j
......
...@@ -25,6 +25,39 @@ start_server {tags {"dump"}} { ...@@ -25,6 +25,39 @@ start_server {tags {"dump"}} {
assert {$ttl >= (2569591501-3000) && $ttl <= 2569591501} assert {$ttl >= (2569591501-3000) && $ttl <= 2569591501}
r get foo r get foo
} {bar} } {bar}
test {RESTORE can set an absolute expire} {
r set foo bar
set encoded [r dump foo]
r del foo
set now [clock milliseconds]
r restore foo [expr $now+3000] $encoded absttl
set ttl [r pttl foo]
assert {$ttl >= 2998 && $ttl <= 3000}
r get foo
} {bar}
test {RESTORE can set LRU} {
r set foo bar
set encoded [r dump foo]
r del foo
r config set maxmemory-policy allkeys-lru
r restore foo 0 $encoded idletime 1000
set idle [r object idletime foo]
assert {$idle >= 1000 && $idle <= 1002}
r get foo
} {bar}
test {RESTORE can set LFU} {
r set foo bar
set encoded [r dump foo]
r del foo
r config set maxmemory-policy allkeys-lfu
r restore foo 0 $encoded freq 100
set freq [r object freq foo]
assert {$freq == 100}
r get foo
} {bar}
test {RESTORE returns an error of the key already exists} { test {RESTORE returns an error of the key already exists} {
r set foo bar r set foo bar
......
...@@ -121,7 +121,7 @@ start_server {tags {"expire"}} { ...@@ -121,7 +121,7 @@ start_server {tags {"expire"}} {
list $a $b list $a $b
} {somevalue {}} } {somevalue {}}
test {TTL returns tiem to live in seconds} { test {TTL returns time to live in seconds} {
r del x r del x
r setex x 10 somevalue r setex x 10 somevalue
set ttl [r ttl x] set ttl [r ttl x]
......
...@@ -97,10 +97,15 @@ start_server {tags {"defrag"}} { ...@@ -97,10 +97,15 @@ start_server {tags {"defrag"}} {
r config set active-defrag-ignore-bytes 2mb r config set active-defrag-ignore-bytes 2mb
r config set maxmemory 0 r config set maxmemory 0
r config set list-max-ziplist-size 5 ;# list of 10k items will have 2000 quicklist nodes r config set list-max-ziplist-size 5 ;# list of 10k items will have 2000 quicklist nodes
r config set stream-node-max-entries 5
r hmset hash h1 v1 h2 v2 h3 v3 r hmset hash h1 v1 h2 v2 h3 v3
r lpush list a b c d r lpush list a b c d
r zadd zset 0 a 1 b 2 c 3 d r zadd zset 0 a 1 b 2 c 3 d
r sadd set a b c d r sadd set a b c d
r xadd stream * item 1 value a
r xadd stream * item 2 value b
r xgroup create stream mygroup 0
r xreadgroup GROUP mygroup Alice COUNT 1 STREAMS stream >
# create big keys with 10k items # create big keys with 10k items
set rd [redis_deferring_client] set rd [redis_deferring_client]
...@@ -109,8 +114,9 @@ start_server {tags {"defrag"}} { ...@@ -109,8 +114,9 @@ start_server {tags {"defrag"}} {
$rd lpush biglist [concat "asdfasdfasdf" $j] $rd lpush biglist [concat "asdfasdfasdf" $j]
$rd zadd bigzset $j [concat "asdfasdfasdf" $j] $rd zadd bigzset $j [concat "asdfasdfasdf" $j]
$rd sadd bigset [concat "asdfasdfasdf" $j] $rd sadd bigset [concat "asdfasdfasdf" $j]
$rd xadd bigstream * item 1 value a
} }
for {set j 0} {$j < 40000} {incr j} { for {set j 0} {$j < 50000} {incr j} {
$rd read ; # Discard replies $rd read ; # Discard replies
} }
...@@ -134,7 +140,7 @@ start_server {tags {"defrag"}} { ...@@ -134,7 +140,7 @@ start_server {tags {"defrag"}} {
for {set j 0} {$j < 500000} {incr j} { for {set j 0} {$j < 500000} {incr j} {
$rd read ; # Discard replies $rd read ; # Discard replies
} }
assert {[r dbsize] == 500008} assert {[r dbsize] == 500010}
# create some fragmentation # create some fragmentation
for {set j 0} {$j < 500000} {incr j 2} { for {set j 0} {$j < 500000} {incr j 2} {
...@@ -143,7 +149,7 @@ start_server {tags {"defrag"}} { ...@@ -143,7 +149,7 @@ start_server {tags {"defrag"}} {
for {set j 0} {$j < 500000} {incr j 2} { for {set j 0} {$j < 500000} {incr j 2} {
$rd read ; # Discard replies $rd read ; # Discard replies
} }
assert {[r dbsize] == 250008} assert {[r dbsize] == 250010}
# start defrag # start defrag
after 120 ;# serverCron only updates the info once in 100ms after 120 ;# serverCron only updates the info once in 100ms
...@@ -155,6 +161,7 @@ start_server {tags {"defrag"}} { ...@@ -155,6 +161,7 @@ start_server {tags {"defrag"}} {
r config set latency-monitor-threshold 5 r config set latency-monitor-threshold 5
r latency reset r latency reset
set digest [r debug digest]
catch {r config set activedefrag yes} e catch {r config set activedefrag yes} e
if {![string match {DISABLED*} $e]} { if {![string match {DISABLED*} $e]} {
# wait for the active defrag to start working (decision once a second) # wait for the active defrag to start working (decision once a second)
...@@ -193,9 +200,11 @@ start_server {tags {"defrag"}} { ...@@ -193,9 +200,11 @@ start_server {tags {"defrag"}} {
# due to high fragmentation, 10hz, and active-defrag-cycle-max set to 75, # due to high fragmentation, 10hz, and active-defrag-cycle-max set to 75,
# we expect max latency to be not much higher than 75ms # we expect max latency to be not much higher than 75ms
assert {$max_latency <= 80} assert {$max_latency <= 80}
} else {
set _ ""
} }
} {} # verify the data isn't corrupted or changed
set newdigest [r debug digest]
assert {$digest eq $newdigest}
r save ;# saving an rdb iterates over all the data / pointers
} {OK}
} }
} }
...@@ -236,4 +236,50 @@ start_server {tags {"scan"}} { ...@@ -236,4 +236,50 @@ start_server {tags {"scan"}} {
set first_score [lindex $res 1] set first_score [lindex $res 1]
assert {$first_score != 0} assert {$first_score != 0}
} }
test "SCAN regression test for issue #4906" {
for {set k 0} {$k < 100} {incr k} {
r del set
r sadd set x; # Make sure it's not intset encoded
set toremove {}
unset -nocomplain found
array set found {}
# Populate the set
set numele [expr {101+[randomInt 1000]}]
for {set j 0} {$j < $numele} {incr j} {
r sadd set $j
if {$j >= 100} {
lappend toremove $j
}
}
# Start scanning
set cursor 0
set iteration 0
set del_iteration [randomInt 10]
while {!($cursor == 0 && $iteration != 0)} {
lassign [r sscan set $cursor] cursor items
# Mark found items. We expect to find from 0 to 99 at the end
# since those elements will never be removed during the scanning.
foreach i $items {
set found($i) 1
}
incr iteration
# At some point remove most of the items to trigger the
# rehashing to a smaller hash table.
if {$iteration == $del_iteration} {
r srem set {*}$toremove
}
}
# Verify that SSCAN reported everything from 0 to 99
for {set j 0} {$j < 100} {incr j} {
if {![info exists found($j)]} {
fail "SSCAN element missing $j"
}
}
}
}
} }
...@@ -253,4 +253,20 @@ start_server { ...@@ -253,4 +253,20 @@ start_server {
} }
} }
} }
test {XREVRANGE regression test for issue #5006} {
# Add non compressed entries
r xadd teststream 1234567891230 key1 value1
r xadd teststream 1234567891240 key2 value2
r xadd teststream 1234567891250 key3 value3
# Add SAMEFIELD compressed entries
r xadd teststream2 1234567891230 key1 value1
r xadd teststream2 1234567891240 key1 value2
r xadd teststream2 1234567891250 key1 value3
assert_equal [r xrevrange teststream 1234567891245 -] {{1234567891240-0 {key2 value2}} {1234567891230-0 {key1 value1}}}
assert_equal [r xrevrange teststream2 1234567891245 -] {{1234567891240-0 {key1 value2}} {1234567891230-0 {key1 value1}}}
}
} }
...@@ -653,11 +653,11 @@ start_server {tags {"zset"}} { ...@@ -653,11 +653,11 @@ start_server {tags {"zset"}} {
r del zset r del zset
assert_equal {} [r zpopmin zset] assert_equal {} [r zpopmin zset]
create_zset zset {-1 a 1 b 2 c 3 d 4 e} create_zset zset {-1 a 1 b 2 c 3 d 4 e}
assert_equal {-1 a} [r zpopmin zset] assert_equal {a -1} [r zpopmin zset]
assert_equal {1 b} [r zpopmin zset] assert_equal {b 1} [r zpopmin zset]
assert_equal {4 e} [r zpopmax zset] assert_equal {e 4} [r zpopmax zset]
assert_equal {3 d} [r zpopmax zset] assert_equal {d 3} [r zpopmax zset]
assert_equal {2 c} [r zpopmin zset] assert_equal {c 2} [r zpopmin zset]
assert_equal 0 [r exists zset] assert_equal 0 [r exists zset]
r set foo bar r set foo bar
assert_error "*WRONGTYPE*" {r zpopmin foo} assert_error "*WRONGTYPE*" {r zpopmin foo}
...@@ -669,8 +669,8 @@ start_server {tags {"zset"}} { ...@@ -669,8 +669,8 @@ start_server {tags {"zset"}} {
assert_equal {} [r zpopmin z1 2] assert_equal {} [r zpopmin z1 2]
assert_error "*WRONGTYPE*" {r zpopmin foo 2} assert_error "*WRONGTYPE*" {r zpopmin foo 2}
create_zset z1 {0 a 1 b 2 c 3 d} create_zset z1 {0 a 1 b 2 c 3 d}
assert_equal {0 a 1 b} [r zpopmin z1 2] assert_equal {a 0 b 1} [r zpopmin z1 2]
assert_equal {3 d 2 c} [r zpopmax z1 2] assert_equal {d 3 c 2} [r zpopmax z1 2]
} }
test "BZPOP with a single existing sorted set - $encoding" { test "BZPOP with a single existing sorted set - $encoding" {
...@@ -678,11 +678,11 @@ start_server {tags {"zset"}} { ...@@ -678,11 +678,11 @@ start_server {tags {"zset"}} {
create_zset zset {0 a 1 b 2 c} create_zset zset {0 a 1 b 2 c}
$rd bzpopmin zset 5 $rd bzpopmin zset 5
assert_equal {zset 0 a} [$rd read] assert_equal {zset a 0} [$rd read]
$rd bzpopmin zset 5 $rd bzpopmin zset 5
assert_equal {zset 1 b} [$rd read] assert_equal {zset b 1} [$rd read]
$rd bzpopmax zset 5 $rd bzpopmax zset 5
assert_equal {zset 2 c} [$rd read] assert_equal {zset c 2} [$rd read]
assert_equal 0 [r exists zset] assert_equal 0 [r exists zset]
} }
...@@ -692,16 +692,16 @@ start_server {tags {"zset"}} { ...@@ -692,16 +692,16 @@ start_server {tags {"zset"}} {
create_zset z2 {3 d 4 e 5 f} create_zset z2 {3 d 4 e 5 f}
$rd bzpopmin z1 z2 5 $rd bzpopmin z1 z2 5
assert_equal {z1 0 a} [$rd read] assert_equal {z1 a 0} [$rd read]
$rd bzpopmax z1 z2 5 $rd bzpopmax z1 z2 5
assert_equal {z1 2 c} [$rd read] assert_equal {z1 c 2} [$rd read]
assert_equal 1 [r zcard z1] assert_equal 1 [r zcard z1]
assert_equal 3 [r zcard z2] assert_equal 3 [r zcard z2]
$rd bzpopmax z2 z1 5 $rd bzpopmax z2 z1 5
assert_equal {z2 5 f} [$rd read] assert_equal {z2 f 5} [$rd read]
$rd bzpopmin z2 z1 5 $rd bzpopmin z2 z1 5
assert_equal {z2 3 d} [$rd read] assert_equal {z2 d 3} [$rd read]
assert_equal 1 [r zcard z1] assert_equal 1 [r zcard z1]
assert_equal 1 [r zcard z2] assert_equal 1 [r zcard z2]
} }
...@@ -711,9 +711,9 @@ start_server {tags {"zset"}} { ...@@ -711,9 +711,9 @@ start_server {tags {"zset"}} {
r del z1 r del z1
create_zset z2 {3 d 4 e 5 f} create_zset z2 {3 d 4 e 5 f}
$rd bzpopmax z1 z2 5 $rd bzpopmax z1 z2 5
assert_equal {z2 5 f} [$rd read] assert_equal {z2 f 5} [$rd read]
$rd bzpopmin z2 z1 5 $rd bzpopmin z2 z1 5
assert_equal {z2 3 d} [$rd read] assert_equal {z2 d 3} [$rd read]
assert_equal 0 [r zcard z1] assert_equal 0 [r zcard z1]
assert_equal 1 [r zcard z2] assert_equal 1 [r zcard z2]
} }
...@@ -1107,7 +1107,7 @@ start_server {tags {"zset"}} { ...@@ -1107,7 +1107,7 @@ start_server {tags {"zset"}} {
r del zset r del zset
r zadd zset 1 bar r zadd zset 1 bar
$rd read $rd read
} {zset 1 bar} } {zset bar 1}
test "BZPOPMIN, ZADD + DEL + SET should not awake blocked client" { test "BZPOPMIN, ZADD + DEL + SET should not awake blocked client" {
set rd [redis_deferring_client] set rd [redis_deferring_client]
...@@ -1124,7 +1124,7 @@ start_server {tags {"zset"}} { ...@@ -1124,7 +1124,7 @@ start_server {tags {"zset"}} {
r del zset r del zset
r zadd zset 1 bar r zadd zset 1 bar
$rd read $rd read
} {zset 1 bar} } {zset bar 1}
test "BZPOPMIN with same key multiple times should work" { test "BZPOPMIN with same key multiple times should work" {
set rd [redis_deferring_client] set rd [redis_deferring_client]
...@@ -1133,18 +1133,18 @@ start_server {tags {"zset"}} { ...@@ -1133,18 +1133,18 @@ start_server {tags {"zset"}} {
# Data arriving after the BZPOPMIN. # Data arriving after the BZPOPMIN.
$rd bzpopmin z1 z2 z2 z1 0 $rd bzpopmin z1 z2 z2 z1 0
r zadd z1 0 a r zadd z1 0 a
assert_equal [$rd read] {z1 0 a} assert_equal [$rd read] {z1 a 0}
$rd bzpopmin z1 z2 z2 z1 0 $rd bzpopmin z1 z2 z2 z1 0
r zadd z2 1 b r zadd z2 1 b
assert_equal [$rd read] {z2 1 b} assert_equal [$rd read] {z2 b 1}
# Data already there. # Data already there.
r zadd z1 0 a r zadd z1 0 a
r zadd z2 1 b r zadd z2 1 b
$rd bzpopmin z1 z2 z2 z1 0 $rd bzpopmin z1 z2 z2 z1 0
assert_equal [$rd read] {z1 0 a} assert_equal [$rd read] {z1 a 0}
$rd bzpopmin z1 z2 z2 z1 0 $rd bzpopmin z1 z2 z2 z1 0
assert_equal [$rd read] {z2 1 b} assert_equal [$rd read] {z2 b 1}
} }
test "MULTI/EXEC is isolated from the point of view of BZPOPMIN" { test "MULTI/EXEC is isolated from the point of view of BZPOPMIN" {
...@@ -1157,7 +1157,7 @@ start_server {tags {"zset"}} { ...@@ -1157,7 +1157,7 @@ start_server {tags {"zset"}} {
r zadd zset 2 c r zadd zset 2 c
r exec r exec
$rd read $rd read
} {zset 0 a} } {zset a 0}
test "BZPOPMIN with variadic ZADD" { test "BZPOPMIN with variadic ZADD" {
set rd [redis_deferring_client] set rd [redis_deferring_client]
...@@ -1167,7 +1167,7 @@ start_server {tags {"zset"}} { ...@@ -1167,7 +1167,7 @@ start_server {tags {"zset"}} {
if {$::valgrind} {after 100} if {$::valgrind} {after 100}
assert_equal 2 [r zadd zset -1 foo 1 bar] assert_equal 2 [r zadd zset -1 foo 1 bar]
if {$::valgrind} {after 100} if {$::valgrind} {after 100}
assert_equal {zset -1 foo} [$rd read] assert_equal {zset foo -1} [$rd read]
assert_equal {bar} [r zrange zset 0 -1] assert_equal {bar} [r zrange zset 0 -1]
} }
...@@ -1177,7 +1177,7 @@ start_server {tags {"zset"}} { ...@@ -1177,7 +1177,7 @@ start_server {tags {"zset"}} {
$rd bzpopmin zset 0 $rd bzpopmin zset 0
after 1000 after 1000
r zadd zset 0 foo r zadd zset 0 foo
assert_equal {zset 0 foo} [$rd read] assert_equal {zset foo 0} [$rd read]
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment