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. */
#define CONFIG_DEFAULT_AOF_USE_RDB_PREAMBLE 1
#define CONFIG_DEFAULT_ACTIVE_REHASHING 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_MAX_LAG 10
#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. */
#define PROTO_INLINE_MAX_SIZE (1024*64) /* Max size of inline reads */
#define PROTO_MBULK_BIG_ARG (1024*32)
#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 */
/* 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. */
/* Anti-warning macro... */
#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 */
/* Append only defines */
......@@ -349,12 +351,14 @@ typedef long long mstime_t; /* millisecond time type. */
#define AOF_FSYNC_EVERYSEC 2
#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_VALUE 64
#define OBJ_SET_MAX_INTSET_ENTRIES 512
#define OBJ_ZSET_MAX_ZIPLIST_ENTRIES 128
#define OBJ_ZSET_MAX_ZIPLIST_VALUE 64
#define OBJ_STREAM_NODE_MAX_BYTES 4096
#define OBJ_STREAM_NODE_MAX_ENTRIES 100
/* List defaults */
#define OBJ_LIST_MAX_ZIPLIST_SIZE -2
......@@ -781,7 +785,7 @@ typedef struct zskiplistNode {
struct zskiplistNode *backward;
struct zskiplistLevel {
struct zskiplistNode *forward;
unsigned int span;
unsigned long span;
} level[];
} zskiplistNode;
......@@ -880,13 +884,13 @@ typedef struct rdbSaveInfo {
#define RDB_SAVE_INFO_INIT {-1,0,"000000000000000000000000000000",-1}
typedef struct malloc_stats {
struct malloc_stats {
size_t zmalloc_used;
size_t process_rss;
size_t allocator_allocated;
size_t allocator_active;
size_t allocator_resident;
} malloc_stats;
};
/*-----------------------------------------------------------------------------
* Global server state
......@@ -950,6 +954,7 @@ struct redisServer {
list *clients_pending_write; /* There is to write or install handler. */
list *slaves, *monitors; /* List of slaves and MONITORs */
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 */
mstime_t clients_pause_end_time; /* Time when we undo clients_paused */
char neterr[ANET_ERR_LEN]; /* Error buffer for anet.c */
......@@ -993,7 +998,7 @@ struct redisServer {
long long slowlog_entry_id; /* SLOWLOG current entry ID */
long long slowlog_log_slower_than; /* SLOWLOG time limit (to get 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_output_bytes; /* Bytes written to network. */
size_t stat_rdb_cow_bytes; /* Copy on write bytes during RDB saving. */
......@@ -1045,7 +1050,8 @@ struct redisServer {
time_t aof_rewrite_time_start; /* Current AOF rewrite start time. */
int aof_lastbgrewrite_status; /* C_OK or C_ERR */
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_errno; /* Valid if aof_last_write_status is ERR */
int aof_load_truncated; /* Don't stop on unexpected AOF EOF. */
......@@ -1178,6 +1184,8 @@ struct redisServer {
size_t zset_max_ziplist_entries;
size_t zset_max_ziplist_value;
size_t hll_sparse_max_bytes;
size_t stream_node_max_bytes;
int64_t stream_node_max_entries;
/* List parameters */
int list_max_ziplist_size;
int list_compress_depth;
......@@ -1407,6 +1415,7 @@ void addReplyHumanLongDouble(client *c, long double d);
void addReplyLongLong(client *c, long long ll);
void addReplyMultiBulkLen(client *c, long length);
void addReplyHelp(client *c, const char **help);
void addReplySubcommandSyntaxError(client *c);
void copyClientOutputBuffer(client *dst, client *src);
size_t sdsZmallocSize(sds s);
size_t getStringObjectSdsUsedMemory(robj *o);
......@@ -1415,7 +1424,7 @@ void getClientsMaxBuffers(unsigned long *longest_output_list,
unsigned long *biggest_input_buffer);
char *getClientPeerId(client *client);
sds catClientInfoString(sds s, client *client);
sds getAllClientsInfoString(void);
sds getAllClientsInfoString(int type);
void rewriteClientCommandVector(client *c, int argc, ...);
void rewriteClientCommandArgument(client *c, int i, robj *newval);
void replaceClientCommandVector(client *c, int argc, robj **argv);
......@@ -1496,6 +1505,7 @@ robj *tryObjectEncoding(robj *o);
robj *getDecodedObject(robj *o);
size_t stringObjectLen(robj *o);
robj *createStringObjectFromLongLong(long long value);
robj *createStringObjectFromLongLongForValue(long long value);
robj *createStringObjectFromLongDouble(long double value, int humanfriendly);
robj *createQuicklistObject(void);
robj *createZiplistObject(void);
......@@ -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);
unsigned char *zzlFirstInRange(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 zsetConvertToZiplistIfNeeded(robj *zobj, size_t maxelelen);
int zsetScore(robj *zobj, sds member, double *score);
......@@ -1766,6 +1776,8 @@ robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply);
robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags);
robj *objectCommandLookup(client *c, robj *key);
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_NOTOUCH (1<<0)
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) {
}
switch (left) {
case 7: b |= ((uint64_t)in[6]) << 48;
case 6: b |= ((uint64_t)in[5]) << 40;
case 5: b |= ((uint64_t)in[4]) << 32;
case 4: b |= ((uint64_t)in[3]) << 24;
case 3: b |= ((uint64_t)in[2]) << 16;
case 2: b |= ((uint64_t)in[1]) << 8;
case 7: b |= ((uint64_t)in[6]) << 48; /* fall-thru */
case 6: b |= ((uint64_t)in[5]) << 40; /* fall-thru */
case 5: b |= ((uint64_t)in[4]) << 32; /* fall-thru */
case 4: b |= ((uint64_t)in[3]) << 24; /* fall-thru */
case 3: b |= ((uint64_t)in[2]) << 16; /* fall-thru */
case 2: b |= ((uint64_t)in[1]) << 8; /* fall-thru */
case 1: b |= ((uint64_t)in[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)
}
switch (left) {
case 7: b |= ((uint64_t)siptlw(in[6])) << 48;
case 6: b |= ((uint64_t)siptlw(in[5])) << 40;
case 5: b |= ((uint64_t)siptlw(in[4])) << 32;
case 4: b |= ((uint64_t)siptlw(in[3])) << 24;
case 3: b |= ((uint64_t)siptlw(in[2])) << 16;
case 2: b |= ((uint64_t)siptlw(in[1])) << 8;
case 7: b |= ((uint64_t)siptlw(in[6])) << 48; /* fall-thru */
case 6: b |= ((uint64_t)siptlw(in[5])) << 40; /* fall-thru */
case 5: b |= ((uint64_t)siptlw(in[4])) << 32; /* fall-thru */
case 4: b |= ((uint64_t)siptlw(in[3])) << 24; /* fall-thru */
case 3: b |= ((uint64_t)siptlw(in[2])) << 16; /* fall-thru */
case 2: b |= ((uint64_t)siptlw(in[1])) << 8; /* fall-thru */
case 1: b |= ((uint64_t)siptlw(in[0])); break;
case 0: break;
}
......
......@@ -142,11 +142,11 @@ void slowlogReset(void) {
void slowlogCommand(client *c) {
if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"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:",
" id, timestamp, time in microseconds, arguments array, client IP and port, client name",
"len -- Return the length of the slowlog.",
"reset -- Reset the slowlog.",
"LEN -- Return the length of the slowlog.",
"RESET -- Reset the slowlog.",
NULL
};
addReplyHelp(c, help);
......@@ -187,6 +187,6 @@ NULL
}
setDeferredMultiBulkLength(c,totentries,sent);
} 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) {
serverAssertWithInfo(c,sortval,j == vectorlen);
/* Now it's time to load the right scores in the sorting vector */
if (dontsort == 0) {
if (!dontsort) {
for (j = 0; j < vectorlen; j++) {
robj *byval;
if (sortby) {
......@@ -487,9 +487,7 @@ void sortCommand(client *c) {
decrRefCount(byval);
}
}
}
if (dontsort == 0) {
server.sort_desc = desc;
server.sort_alpha = alpha;
server.sort_bypattern = sortby ? 1 : 0;
......
This diff is collapsed.
......@@ -361,7 +361,7 @@ void incrDecrCommand(client *c, long long incr) {
new = o;
o->ptr = (void*)((long)value);
} else {
new = createStringObjectFromLongLong(value);
new = createStringObjectFromLongLongForValue(value);
if (o) {
dbOverwrite(c->db,c->argv[1],new);
} else {
......
......@@ -1100,8 +1100,8 @@ unsigned char *zzlDeleteRangeByRank(unsigned char *zl, unsigned int start, unsig
* Common sorted set API
*----------------------------------------------------------------------------*/
unsigned int zsetLength(const robj *zobj) {
int length = -1;
unsigned long zsetLength(const robj *zobj) {
unsigned long length = 0;
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
length = zzlLength(zobj->ptr);
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
......@@ -1878,7 +1878,7 @@ void zuiClearIterator(zsetopsrc *op) {
}
}
int zuiLength(zsetopsrc *op) {
unsigned long zuiLength(zsetopsrc *op) {
if (op->subject == NULL)
return 0;
......@@ -2085,7 +2085,11 @@ int zuiFind(zsetopsrc *op, zsetopval *val, double *score) {
}
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
......@@ -2129,7 +2133,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) {
zsetopsrc *src;
zsetopval zval;
sds tmp;
unsigned int maxelelen = 0;
size_t maxelelen = 0;
robj *dstobj;
zset *dstzset;
zskiplistNode *znode;
......@@ -2363,8 +2367,8 @@ void zrangeGenericCommand(client *c, int reverse) {
int withscores = 0;
long start;
long end;
int llen;
int rangelen;
long llen;
long rangelen;
if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) ||
(getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != C_OK)) return;
......@@ -2671,7 +2675,7 @@ void zcountCommand(client *c) {
robj *key = c->argv[1];
robj *zobj;
zrangespec range;
int count = 0;
unsigned long count = 0;
/* Parse the range arguments */
if (zslParseRange(c->argv[2],c->argv[3],&range) != C_OK) {
......@@ -2748,7 +2752,7 @@ void zlexcountCommand(client *c) {
robj *key = c->argv[1];
robj *zobj;
zlexrangespec range;
int count = 0;
unsigned long count = 0;
/* Parse the range arguments */
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
signalModifiedKey(c->db,key);
}
addReplyDouble(c,score);
addReplyBulkCBuffer(c,ele,sdslen(ele));
addReplyDouble(c,score);
sdsfree(ele);
arraylen += 2;
......@@ -3216,9 +3220,9 @@ void blockingGenericZpopCommand(client *c, int where) {
return;
} else {
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);
/* 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,
where == ZSET_MAX ? shared.zpopmax : shared.zpopmin,
c->argv[j]);
......
......@@ -27,7 +27,7 @@
* traversal.
*
* <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.
*
* <uint8_t zlend> is a special entry representing the end of the ziplist.
......@@ -256,7 +256,7 @@
#define ZIPLIST_ENTRY_END(zl) ((zl)+intrev32ifbe(ZIPLIST_BYTES(zl))-1)
/* 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
* to stay there to signal that a full scan is needed to get the number of
* items inside the ziplist. */
......
......@@ -30,6 +30,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
/* This function provide us access to the original libc free(). This is useful
* for instance to free results obtained by backtrace_symbols(). We need
......@@ -164,7 +165,7 @@ void *zrealloc(void *ptr, size_t size) {
*((size_t*)newptr) = size;
update_zmalloc_stat_free(oldsize);
update_zmalloc_stat_alloc(size);
update_zmalloc_stat_alloc(size+PREFIX_SIZE);
return (char*)newptr+PREFIX_SIZE;
#endif
}
......@@ -418,7 +419,7 @@ size_t zmalloc_get_memory_size(void) {
mib[0] = CTL_HW;
#if defined(HW_REALMEM)
mib[1] = HW_REALMEM; /* FreeBSD. ----------------- */
#elif defined(HW_PYSMEM)
#elif defined(HW_PHYSMEM)
mib[1] = HW_PHYSMEM; /* Others. ------------------ */
#endif
unsigned int size = 0; /* 32-bit */
......
......@@ -63,6 +63,11 @@
#ifndef ZMALLOC_LIB
#define ZMALLOC_LIB "libc"
#ifdef __GLIBC__
#include <malloc.h>
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) malloc_usable_size(p)
#endif
#endif
/* 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]] {
} {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
# logged.
set defaults {}
......
......@@ -66,3 +66,13 @@ test "SDOWN is triggered by misconfigured instance repling with errors" {
R 0 bgsave
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}} {
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 {
# check that the server actually started and is ready for connections
if {[exec grep -i "Ready to accept" | wc -l < $stdout] > 0} {
......
......@@ -83,6 +83,8 @@ set ::force_failure 0
set ::timeout 600; # 10 minutes without progresses will quit the test.
set ::last_progress [clock seconds]
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
# server-client model to run tests simultaneously. The server instance
......@@ -176,6 +178,9 @@ proc s {args} {
}
proc cleanup {} {
if {$::dont_clean} {
return
}
if {!$::quiet} {puts -nonewline "Cleanup: may take some time... "}
flush stdout
catch {exec rm -rf {*}[glob tests/tmp/redis.conf.*]}
......@@ -225,6 +230,7 @@ proc test_server_cron {} {
if {$elapsed > $::timeout} {
set err "\[[colorstr red TIMEOUT]\]: clients state report follows."
puts $err
lappend ::failed_tests $err
show_clients_state
kill_clients
force_kill_all_servers
......@@ -411,6 +417,8 @@ proc print_help_screen {} {
"--clients <num> Number of test clients (default 16)."
"--timeout <sec> Test timeout in seconds (default 10 min)."
"--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."
} "\n"]
}
......@@ -464,6 +472,10 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
} elseif {$opt eq {--clients}} {
set ::numclients $arg
incr j
} elseif {$opt eq {--dont-clean}} {
set ::dont_clean 1
} elseif {$opt eq {--wait-server}} {
set ::wait_server 1
} elseif {$opt eq {--timeout}} {
set ::timeout $arg
incr j
......
......@@ -25,6 +25,39 @@ start_server {tags {"dump"}} {
assert {$ttl >= (2569591501-3000) && $ttl <= 2569591501}
r get foo
} {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} {
r set foo bar
......
......@@ -121,7 +121,7 @@ start_server {tags {"expire"}} {
list $a $b
} {somevalue {}}
test {TTL returns tiem to live in seconds} {
test {TTL returns time to live in seconds} {
r del x
r setex x 10 somevalue
set ttl [r ttl x]
......
......@@ -97,10 +97,15 @@ start_server {tags {"defrag"}} {
r config set active-defrag-ignore-bytes 2mb
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 stream-node-max-entries 5
r hmset hash h1 v1 h2 v2 h3 v3
r lpush list a b c d
r zadd zset 0 a 1 b 2 c 3 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
set rd [redis_deferring_client]
......@@ -109,8 +114,9 @@ start_server {tags {"defrag"}} {
$rd lpush biglist [concat "asdfasdfasdf" $j]
$rd zadd bigzset $j [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
}
......@@ -134,7 +140,7 @@ start_server {tags {"defrag"}} {
for {set j 0} {$j < 500000} {incr j} {
$rd read ; # Discard replies
}
assert {[r dbsize] == 500008}
assert {[r dbsize] == 500010}
# create some fragmentation
for {set j 0} {$j < 500000} {incr j 2} {
......@@ -143,7 +149,7 @@ start_server {tags {"defrag"}} {
for {set j 0} {$j < 500000} {incr j 2} {
$rd read ; # Discard replies
}
assert {[r dbsize] == 250008}
assert {[r dbsize] == 250010}
# start defrag
after 120 ;# serverCron only updates the info once in 100ms
......@@ -155,6 +161,7 @@ start_server {tags {"defrag"}} {
r config set latency-monitor-threshold 5
r latency reset
set digest [r debug digest]
catch {r config set activedefrag yes} e
if {![string match {DISABLED*} $e]} {
# wait for the active defrag to start working (decision once a second)
......@@ -193,9 +200,11 @@ start_server {tags {"defrag"}} {
# due to high fragmentation, 10hz, and active-defrag-cycle-max set to 75,
# we expect max latency to be not much higher than 75ms
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"}} {
set first_score [lindex $res 1]
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 {
}
}
}
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"}} {
r del zset
assert_equal {} [r zpopmin zset]
create_zset zset {-1 a 1 b 2 c 3 d 4 e}
assert_equal {-1 a} [r zpopmin zset]
assert_equal {1 b} [r zpopmin zset]
assert_equal {4 e} [r zpopmax zset]
assert_equal {3 d} [r zpopmax zset]
assert_equal {2 c} [r zpopmin zset]
assert_equal {a -1} [r zpopmin zset]
assert_equal {b 1} [r zpopmin zset]
assert_equal {e 4} [r zpopmax zset]
assert_equal {d 3} [r zpopmax zset]
assert_equal {c 2} [r zpopmin zset]
assert_equal 0 [r exists zset]
r set foo bar
assert_error "*WRONGTYPE*" {r zpopmin foo}
......@@ -669,8 +669,8 @@ start_server {tags {"zset"}} {
assert_equal {} [r zpopmin z1 2]
assert_error "*WRONGTYPE*" {r zpopmin foo 2}
create_zset z1 {0 a 1 b 2 c 3 d}
assert_equal {0 a 1 b} [r zpopmin z1 2]
assert_equal {3 d 2 c} [r zpopmax z1 2]
assert_equal {a 0 b 1} [r zpopmin z1 2]
assert_equal {d 3 c 2} [r zpopmax z1 2]
}
test "BZPOP with a single existing sorted set - $encoding" {
......@@ -678,11 +678,11 @@ start_server {tags {"zset"}} {
create_zset zset {0 a 1 b 2 c}
$rd bzpopmin zset 5
assert_equal {zset 0 a} [$rd read]
assert_equal {zset a 0} [$rd read]
$rd bzpopmin zset 5
assert_equal {zset 1 b} [$rd read]
assert_equal {zset b 1} [$rd read]
$rd bzpopmax zset 5
assert_equal {zset 2 c} [$rd read]
assert_equal {zset c 2} [$rd read]
assert_equal 0 [r exists zset]
}
......@@ -692,16 +692,16 @@ start_server {tags {"zset"}} {
create_zset z2 {3 d 4 e 5 f}
$rd bzpopmin z1 z2 5
assert_equal {z1 0 a} [$rd read]
assert_equal {z1 a 0} [$rd read]
$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 3 [r zcard z2]
$rd bzpopmax z2 z1 5
assert_equal {z2 5 f} [$rd read]
assert_equal {z2 f 5} [$rd read]
$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 z2]
}
......@@ -711,9 +711,9 @@ start_server {tags {"zset"}} {
r del z1
create_zset z2 {3 d 4 e 5 f}
$rd bzpopmax z1 z2 5
assert_equal {z2 5 f} [$rd read]
assert_equal {z2 f 5} [$rd read]
$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 1 [r zcard z2]
}
......@@ -1107,7 +1107,7 @@ start_server {tags {"zset"}} {
r del zset
r zadd zset 1 bar
$rd read
} {zset 1 bar}
} {zset bar 1}
test "BZPOPMIN, ZADD + DEL + SET should not awake blocked client" {
set rd [redis_deferring_client]
......@@ -1124,7 +1124,7 @@ start_server {tags {"zset"}} {
r del zset
r zadd zset 1 bar
$rd read
} {zset 1 bar}
} {zset bar 1}
test "BZPOPMIN with same key multiple times should work" {
set rd [redis_deferring_client]
......@@ -1133,18 +1133,18 @@ start_server {tags {"zset"}} {
# Data arriving after the BZPOPMIN.
$rd bzpopmin z1 z2 z2 z1 0
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
r zadd z2 1 b
assert_equal [$rd read] {z2 1 b}
assert_equal [$rd read] {z2 b 1}
# Data already there.
r zadd z1 0 a
r zadd z2 1 b
$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
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" {
......@@ -1157,7 +1157,7 @@ start_server {tags {"zset"}} {
r zadd zset 2 c
r exec
$rd read
} {zset 0 a}
} {zset a 0}
test "BZPOPMIN with variadic ZADD" {
set rd [redis_deferring_client]
......@@ -1167,7 +1167,7 @@ start_server {tags {"zset"}} {
if {$::valgrind} {after 100}
assert_equal 2 [r zadd zset -1 foo 1 bar]
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]
}
......@@ -1177,7 +1177,7 @@ start_server {tags {"zset"}} {
$rd bzpopmin zset 0
after 1000
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