Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
68ceb466
Unverified
Commit
68ceb466
authored
Jul 20, 2018
by
chendianqiang
Committed by
GitHub
Jul 20, 2018
Browse files
Merge pull request #1 from antirez/unstable
update
parents
3d5e2c62
1c95c075
Changes
89
Expand all
Hide whitespace changes
Inline
Side-by-side
src/sort.c
View file @
68ceb466
...
...
@@ -193,7 +193,7 @@ void sortCommand(client *c) {
long
limit_start
=
0
,
limit_count
=
-
1
,
start
,
end
;
int
j
,
dontsort
=
0
,
vectorlen
;
int
getop
=
0
;
/* GET operation counter */
int
int_conver
t
ion_error
=
0
;
int
int_conver
s
ion_error
=
0
;
int
syntax_error
=
0
;
robj
*
sortval
,
*
sortby
=
NULL
,
*
storekey
=
NULL
;
redisSortObject
*
vector
;
/* Resulting vector to sort */
...
...
@@ -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
)
{
...
...
@@ -469,7 +469,7 @@ void sortCommand(client *c) {
if
(
eptr
[
0
]
!=
'\0'
||
errno
==
ERANGE
||
isnan
(
vector
[
j
].
u
.
score
))
{
int_conver
t
ion_error
=
1
;
int_conver
s
ion_error
=
1
;
}
}
else
if
(
byval
->
encoding
==
OBJ_ENCODING_INT
)
{
/* Don't need to decode the object if it's
...
...
@@ -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
;
...
...
@@ -503,7 +501,7 @@ void sortCommand(client *c) {
/* Send command output to the output buffer, performing the specified
* GET/DEL/INCR/DECR operations if any. */
outputlen
=
getop
?
getop
*
(
end
-
start
+
1
)
:
end
-
start
+
1
;
if
(
int_conver
t
ion_error
)
{
if
(
int_conver
s
ion_error
)
{
addReplyError
(
c
,
"One or more scores can't be converted into double"
);
}
else
if
(
storekey
==
NULL
)
{
/* STORE option not specified, sent the sorting result to client */
...
...
src/stream.h
View file @
68ceb466
...
...
@@ -108,5 +108,6 @@ streamConsumer *streamLookupConsumer(streamCG *cg, sds name, int create);
streamCG
*
streamCreateCG
(
stream
*
s
,
char
*
name
,
size_t
namelen
,
streamID
*
id
);
streamNACK
*
streamCreateNACK
(
streamConsumer
*
consumer
);
void
streamDecodeID
(
void
*
buf
,
streamID
*
id
);
int
streamCompareID
(
streamID
*
a
,
streamID
*
b
);
#endif
src/t_stream.c
View file @
68ceb466
This diff is collapsed.
Click to expand it.
src/t_string.c
View file @
68ceb466
...
...
@@ -361,7 +361,7 @@ void incrDecrCommand(client *c, long long incr) {
new
=
o
;
o
->
ptr
=
(
void
*
)((
long
)
value
);
}
else
{
new
=
createStringObjectFromLongLong
(
value
);
new
=
createStringObjectFromLongLong
ForValue
(
value
);
if
(
o
)
{
dbOverwrite
(
c
->
db
,
c
->
argv
[
1
],
new
);
}
else
{
...
...
src/t_zset.c
View file @
68ceb466
...
...
@@ -507,7 +507,7 @@ static int zslParseRange(robj *min, robj *max, zrangespec *spec) {
* + means the max string possible
*
* If the string is valid the *dest pointer is set to the redis object
* that will be used for the comparis
i
on, and ex will be set to 0 or 1
* that will be used for the comparison, and ex will be set to 0 or 1
* respectively if the item is exclusive or inclusive. C_OK will be
* returned.
*
...
...
@@ -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
in
t
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 Z
POP[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 Z
POP[MIN|MAX]
instead of BZ
POP[MIN|MAX]
. */
rewriteClientCommandVector
(
c
,
2
,
where
==
ZSET_MAX
?
shared
.
zpopmax
:
shared
.
zpopmin
,
c
->
argv
[
j
]);
...
...
src/util.c
View file @
68ceb466
...
...
@@ -451,7 +451,7 @@ int string2ld(const char *s, size_t slen, long double *dp) {
/* Convert a double to a string representation. Returns the number of bytes
* required. The representation should always be parsable by strtod(3).
* This function does not support human-friendly formatting like ld2string
* does. It is inten
t
ed mainly to be used inside t_zset.c when writing scores
* does. It is inten
d
ed mainly to be used inside t_zset.c when writing scores
* into a ziplist representing a sorted set. */
int
d2string
(
char
*
buf
,
size_t
len
,
double
value
)
{
if
(
isnan
(
value
))
{
...
...
src/ziplist.c
View file @
68ceb466
...
...
@@ -27,7 +27,7 @@
* traversal.
*
* <uint16_t zllen> is the number of entries. When there are more than
* 2^16-2 ent
i
res, this value is set to 2^16-1 and we need to traverse the
* 2^16-2 entr
i
es, 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 ent
i
res are
* macro should never overflow the unsigned 16 bit integer, since entr
i
es 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. */
...
...
@@ -269,7 +269,7 @@
* Note that this is not how the data is actually encoded, is just what we
* get filled by a function in order to operate more easily. */
typedef
struct
zlentry
{
unsigned
int
prevrawlensize
;
/* Bytes used to encode the previos entry len*/
unsigned
int
prevrawlensize
;
/* Bytes used to encode the previo
u
s entry len*/
unsigned
int
prevrawlen
;
/* Previous entry len. */
unsigned
int
lensize
;
/* Bytes used to encode this entry type/len.
For example strings have a 1, 2 or 5 bytes
...
...
@@ -431,7 +431,7 @@ unsigned int zipStorePrevEntryLength(unsigned char *p, unsigned int len) {
/* Return the length of the previous element, and the number of bytes that
* are used in order to encode the previous element length.
* 'ptr' must point to the prevlen prefix of an entry (that encodes the
* length of the previos entry in order to navigate the elements backward).
* length of the previo
u
s entry in order to navigate the elements backward).
* The length of the previous entry is stored in 'prevlen', the number of
* bytes needed to encode the previous entry length are stored in
* 'prevlensize'. */
...
...
src/zmalloc.c
View file @
68ceb466
...
...
@@ -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
}
...
...
@@ -181,6 +182,9 @@ size_t zmalloc_size(void *ptr) {
if
(
size
&
(
sizeof
(
long
)
-
1
))
size
+=
sizeof
(
long
)
-
(
size
&
(
sizeof
(
long
)
-
1
));
return
size
+
PREFIX_SIZE
;
}
size_t
zmalloc_usable
(
void
*
ptr
)
{
return
zmalloc_usable
(
ptr
)
-
PREFIX_SIZE
;
}
#endif
void
zfree
(
void
*
ptr
)
{
...
...
@@ -379,7 +383,7 @@ size_t zmalloc_get_private_dirty(long pid) {
}
/* Returns the size of physical memory (RAM) in bytes.
* It looks ugly, but this is the cleanest way to achive cross platform results.
* It looks ugly, but this is the cleanest way to achi
e
ve cross platform results.
* Cleaned up from:
*
* http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system
...
...
@@ -418,7 +422,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_P
H
YSMEM)
mib
[
1
]
=
HW_PHYSMEM
;
/* Others. ------------------ */
#endif
unsigned
int
size
=
0
;
/* 32-bit */
...
...
src/zmalloc.h
View file @
68ceb466
...
...
@@ -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
...
...
@@ -93,6 +98,9 @@ void *zmalloc_no_tcache(size_t size);
#ifndef HAVE_MALLOC_SIZE
size_t
zmalloc_size
(
void
*
ptr
);
size_t
zmalloc_usable
(
void
*
ptr
);
#else
#define zmalloc_usable(p) zmalloc_size(p)
#endif
#endif
/* __ZMALLOC_H */
tests/cluster/tests/05-slave-selection.tcl
View file @
68ceb466
...
...
@@ -92,3 +92,80 @@ test "Node #10 should eventually replicate node #5" {
fail
"#10 didn't became slave of #5"
}
}
source
"../tests/includes/init-tests.tcl"
# Create a cluster with 3 master and 15 slaves, so that we have 5
# slaves for eatch master.
test
"Create a 3 nodes cluster"
{
create_cluster 3 15
}
test
"Cluster is up"
{
assert_cluster_state ok
}
test
"The first master has actually 5 slaves"
{
assert
{[
llength
[
lindex
[
R 0 role
]
2
]]
== 5
}
}
test
{
Slaves of #0 are instance #3, #6, #9, #12 and #15 as expected
}
{
set port0
[
get_instance_attrib redis 0 port
]
assert
{[
lindex
[
R 3 role
]
2
]
== $port0
}
assert
{[
lindex
[
R 6 role
]
2
]
== $port0
}
assert
{[
lindex
[
R 9 role
]
2
]
== $port0
}
assert
{[
lindex
[
R 12 role
]
2
]
== $port0
}
assert
{[
lindex
[
R 15 role
]
2
]
== $port0
}
}
test
{
Instance #3, #6, #9, #12 and #15 synced with the master
}
{
wait_for_condition 1000 50
{
[
RI 3 master_link_status
]
eq
{
up
}
&&
[
RI 6 master_link_status
]
eq
{
up
}
&&
[
RI 9 master_link_status
]
eq
{
up
}
&&
[
RI 12 master_link_status
]
eq
{
up
}
&&
[
RI 15 master_link_status
]
eq
{
up
}
}
else
{
fail
"Instance #3 or #6 or #9 or #12 or #15 master link status is not up"
}
}
proc master_detected
{
instances
}
{
foreach instance
[
dict keys $instances
]
{
if
{[
RI $instance role
]
eq
{
master
}}
{
return true
}
}
return false
}
test
"New Master down consecutively"
{
set instances
[
dict create 0 1 3 1 6 1 9 1 12 1 15 1
]
set loops
[
expr
{[
dict size $instances
]
-1
}]
for
{
set i 0
}
{
$i
< $loops
}
{
incr i
}
{
set master_id -1
foreach instance
[
dict keys $instances
]
{
if
{[
RI $instance role
]
eq
{
master
}}
{
set master_id $instance
break
;
}
}
if
{
$master
_id eq -1
}
{
fail
"no master detected, #loop
$i
"
}
set instances
[
dict remove $instances $master_id
]
kill_instance redis $master_id
wait_for_condition 1000 50
{
[
master_detected $instances
]
}
else
{
failover
"No failover detected when master
$master
_id fails"
}
assert_cluster_state ok
}
}
tests/integration/rdb.tcl
View file @
68ceb466
...
...
@@ -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
{}
...
...
tests/integration/replication-psync.tcl
View file @
68ceb466
...
...
@@ -11,7 +11,7 @@ proc stop_bg_complex_data {handle} {
# partial resyncs attempts, all this while flooding the master with
# write queries.
#
# You can specif
i
y backlog size, ttl, delay before reconnection, test duration
# You can specify backlog size, ttl, delay before reconnection, test duration
# in seconds, and an additional condition to verify at the end.
#
# If reconnect is > 0, the test actually try to break the connection and
...
...
tests/sentinel/tests/07-down-conditions.tcl
View file @
68ceb466
...
...
@@ -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
}
tests/support/server.tcl
View file @
68ceb466
...
...
@@ -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
}
{
...
...
tests/support/util.tcl
View file @
68ceb466
...
...
@@ -375,3 +375,19 @@ proc start_write_load {host port seconds} {
proc stop_write_load
{
handle
}
{
catch
{
exec /bin/kill -9 $handle
}
}
proc K
{
x y
}
{
set x
}
# Shuffle a list. From Tcl wiki. Originally from Steve Cohen that improved
# other versions. Code should be under public domain.
proc lshuffle
{
list
}
{
set n
[
llength $list
]
while
{
$n
>0
}
{
set j
[
expr
{
int
(
rand
()
*$n
)}]
lappend slist
[
lindex $list $j
]
incr n -1
set temp
[
lindex $list $n
]
set list
[
lreplace
[
K $list
[
set list
{}]]
$j $j $temp
]
}
return $slist
}
tests/test_helper.tcl
View file @
68ceb466
...
...
@@ -61,6 +61,7 @@ set ::all_tests {
unit/hyperloglog
unit/lazyfree
unit/wait
unit/pendingquerybuf
}
# Index to the next test to run in the ::all_tests list.
set ::next_test 0
...
...
@@ -82,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
...
...
@@ -175,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.*
]}
...
...
@@ -224,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
...
...
@@ -410,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
"
]
}
...
...
@@ -463,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
...
...
tests/unit/dump.tcl
View file @
68ceb466
This diff is collapsed.
Click to expand it.
tests/unit/expire.tcl
View file @
68ceb466
...
...
@@ -121,7 +121,7 @@ start_server {tags {"expire"}} {
list $a $b
}
{
somevalue
{}}
test
{
TTL returns ti
e
m to live in seconds
}
{
test
{
TTL returns tim
e
to live in seconds
}
{
r del x
r setex x 10 somevalue
set ttl
[
r ttl x
]
...
...
tests/unit/maxmemory.tcl
View file @
68ceb466
This diff is collapsed.
Click to expand it.
tests/unit/memefficiency.tcl
View file @
68ceb466
This diff is collapsed.
Click to expand it.
Prev
1
2
3
4
5
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment