Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
d52e5888
Commit
d52e5888
authored
Jun 14, 2010
by
antirez
Browse files
Merge branch 'ltrim-tests' of
git://github.com/pietern/redis
parents
7d04fc75
7e79de54
Changes
3
Hide whitespace changes
Inline
Side-by-side
redis.c
View file @
d52e5888
...
...
@@ -129,11 +129,11 @@
#define REDIS_ENCODING_INT 1
/* Encoded as integer */
#define REDIS_ENCODING_HT 2
/* Encoded as hash table */
#define REDIS_ENCODING_ZIPMAP 3
/* Encoded as zipmap */
#define REDIS_ENCODING_LIST 4
/* Encoded as
zipmap
*/
#define REDIS_ENCODING_
LINKED
LIST 4
/* Encoded as
regular linked list
*/
#define REDIS_ENCODING_ZIPLIST 5
/* Encoded as ziplist */
static
char
*
strencoding
[]
=
{
"raw"
,
"int"
,
"hashtable"
,
"zipmap"
,
"list"
,
"ziplist"
"raw"
,
"int"
,
"hashtable"
,
"zipmap"
,
"
linked
list"
,
"ziplist"
};
/* Object types only used for dumping to disk */
...
...
@@ -3059,7 +3059,7 @@ static robj *createListObject(void) {
list
*
l
=
listCreate
();
robj
*
o
=
createObject
(
REDIS_LIST
,
l
);
listSetFreeMethod
(
l
,
decrRefCount
);
o
->
encoding
=
REDIS_ENCODING_LIST
;
o
->
encoding
=
REDIS_ENCODING_
LINKED
LIST
;
return
o
;
}
...
...
@@ -3101,7 +3101,7 @@ static void freeStringObject(robj *o) {
static
void
freeListObject
(
robj
*
o
)
{
switch
(
o
->
encoding
)
{
case
REDIS_ENCODING_LIST
:
case
REDIS_ENCODING_
LINKED
LIST
:
listRelease
((
list
*
)
o
->
ptr
);
break
;
case
REDIS_ENCODING_ZIPLIST
:
...
...
@@ -3777,7 +3777,7 @@ static int rdbSaveObject(FILE *fp, robj *o) {
}
p
=
ziplistNext
(
o
->
ptr
,
p
);
}
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
list
*
list
=
o
->
ptr
;
listIter
li
;
listNode
*
ln
;
...
...
@@ -4187,7 +4187,7 @@ static robj *rdbLoadObject(int type, FILE *fp) {
if
(
o
->
encoding
==
REDIS_ENCODING_ZIPLIST
&&
ele
->
encoding
==
REDIS_ENCODING_RAW
&&
sdslen
(
ele
->
ptr
)
>
server
.
list_max_ziplist_value
)
listTypeConvert
(
o
,
REDIS_ENCODING_LIST
);
listTypeConvert
(
o
,
REDIS_ENCODING_
LINKED
LIST
);
if
(
o
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
dec
=
getDecodedObject
(
ele
);
...
...
@@ -4927,7 +4927,7 @@ static void listTypeTryConversion(robj *subject, robj *value) {
if
(
subject
->
encoding
!=
REDIS_ENCODING_ZIPLIST
)
return
;
if
(
value
->
encoding
==
REDIS_ENCODING_RAW
&&
sdslen
(
value
->
ptr
)
>
server
.
list_max_ziplist_value
)
listTypeConvert
(
subject
,
REDIS_ENCODING_LIST
);
listTypeConvert
(
subject
,
REDIS_ENCODING_
LINKED
LIST
);
}
static
void
listTypePush
(
robj
*
subject
,
robj
*
value
,
int
where
)
{
...
...
@@ -4935,14 +4935,14 @@ static void listTypePush(robj *subject, robj *value, int where) {
listTypeTryConversion
(
subject
,
value
);
if
(
subject
->
encoding
==
REDIS_ENCODING_ZIPLIST
&&
ziplistLen
(
subject
->
ptr
)
>=
server
.
list_max_ziplist_entries
)
listTypeConvert
(
subject
,
REDIS_ENCODING_LIST
);
listTypeConvert
(
subject
,
REDIS_ENCODING_
LINKED
LIST
);
if
(
subject
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
int
pos
=
(
where
==
REDIS_HEAD
)
?
ZIPLIST_HEAD
:
ZIPLIST_TAIL
;
value
=
getDecodedObject
(
value
);
subject
->
ptr
=
ziplistPush
(
subject
->
ptr
,
value
->
ptr
,
sdslen
(
value
->
ptr
),
pos
);
decrRefCount
(
value
);
}
else
if
(
subject
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
subject
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
if
(
where
==
REDIS_HEAD
)
{
listAddNodeHead
(
subject
->
ptr
,
value
);
}
else
{
...
...
@@ -4972,7 +4972,7 @@ static robj *listTypePop(robj *subject, int where) {
/* We only need to delete an element when it exists */
subject
->
ptr
=
ziplistDelete
(
subject
->
ptr
,
&
p
);
}
}
else
if
(
subject
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
subject
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
list
*
list
=
subject
->
ptr
;
listNode
*
ln
;
if
(
where
==
REDIS_HEAD
)
{
...
...
@@ -4994,7 +4994,7 @@ static robj *listTypePop(robj *subject, int where) {
static
unsigned
long
listTypeLength
(
robj
*
subject
)
{
if
(
subject
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
return
ziplistLen
(
subject
->
ptr
);
}
else
if
(
subject
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
subject
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
return
listLength
((
list
*
)
subject
->
ptr
);
}
else
{
redisPanic
(
"Unknown list encoding"
);
...
...
@@ -5025,7 +5025,7 @@ static listTypeIterator *listTypeInitIterator(robj *subject, int index, unsigned
li
->
direction
=
direction
;
if
(
li
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
li
->
zi
=
ziplistIndex
(
subject
->
ptr
,
index
);
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
li
->
ln
=
listIndex
(
subject
->
ptr
,
index
);
}
else
{
redisPanic
(
"Unknown list encoding"
);
...
...
@@ -5055,7 +5055,7 @@ static int listTypeNext(listTypeIterator *li, listTypeEntry *entry) {
li
->
zi
=
ziplistPrev
(
li
->
subject
->
ptr
,
li
->
zi
);
return
1
;
}
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
entry
->
ln
=
li
->
ln
;
if
(
entry
->
ln
!=
NULL
)
{
if
(
li
->
direction
==
REDIS_TAIL
)
...
...
@@ -5086,7 +5086,7 @@ static robj *listTypeGet(listTypeEntry *entry) {
value
=
createStringObjectFromLongLong
(
vlong
);
}
}
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
redisAssert
(
entry
->
ln
!=
NULL
);
value
=
listNodeValue
(
entry
->
ln
);
incrRefCount
(
value
);
...
...
@@ -5114,7 +5114,7 @@ static void listTypeInsert(listTypeEntry *entry, robj *value, int where) {
subject
->
ptr
=
ziplistInsert
(
subject
->
ptr
,
entry
->
zi
,
value
->
ptr
,
sdslen
(
value
->
ptr
));
}
decrRefCount
(
value
);
}
else
if
(
entry
->
li
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
entry
->
li
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
if
(
where
==
REDIS_TAIL
)
{
listInsertNode
(
subject
->
ptr
,
entry
->
ln
,
value
,
AL_START_TAIL
);
}
else
{
...
...
@@ -5132,7 +5132,7 @@ static int listTypeEqual(listTypeEntry *entry, robj *o) {
if
(
li
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
redisAssert
(
o
->
encoding
==
REDIS_ENCODING_RAW
);
return
ziplistCompare
(
entry
->
zi
,
o
->
ptr
,
sdslen
(
o
->
ptr
));
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
return
equalStringObjects
(
o
,
listNodeValue
(
entry
->
ln
));
}
else
{
redisPanic
(
"Unknown list encoding"
);
...
...
@@ -5151,7 +5151,7 @@ static void listTypeDelete(listTypeEntry *entry) {
li
->
zi
=
p
;
else
li
->
zi
=
ziplistPrev
(
li
->
subject
->
ptr
,
p
);
}
else
if
(
entry
->
li
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
entry
->
li
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
listNode
*
next
;
if
(
li
->
direction
==
REDIS_TAIL
)
next
=
entry
->
ln
->
next
;
...
...
@@ -5169,7 +5169,7 @@ static void listTypeConvert(robj *subject, int enc) {
listTypeEntry
entry
;
redisAssert
(
subject
->
type
==
REDIS_LIST
);
if
(
enc
==
REDIS_ENCODING_LIST
)
{
if
(
enc
==
REDIS_ENCODING_
LINKED
LIST
)
{
list
*
l
=
listCreate
();
listSetFreeMethod
(
l
,
decrRefCount
);
...
...
@@ -5178,7 +5178,7 @@ static void listTypeConvert(robj *subject, int enc) {
while
(
listTypeNext
(
li
,
&
entry
))
listAddNodeTail
(
l
,
listTypeGet
(
&
entry
));
listTypeReleaseIterator
(
li
);
subject
->
encoding
=
REDIS_ENCODING_LIST
;
subject
->
encoding
=
REDIS_ENCODING_
LINKED
LIST
;
zfree
(
subject
->
ptr
);
subject
->
ptr
=
l
;
}
else
{
...
...
@@ -5254,7 +5254,7 @@ static void pushxGenericCommand(redisClient *c, robj *refval, robj *val, int whe
/* Check if the length exceeds the ziplist length threshold. */
if
(
subject
->
encoding
==
REDIS_ENCODING_ZIPLIST
&&
ziplistLen
(
subject
->
ptr
)
>
server
.
list_max_ziplist_entries
)
listTypeConvert
(
subject
,
REDIS_ENCODING_LIST
);
listTypeConvert
(
subject
,
REDIS_ENCODING_
LINKED
LIST
);
server
.
dirty
++
;
}
else
{
/* Notify client of a failed insert */
...
...
@@ -5316,7 +5316,7 @@ static void lindexCommand(redisClient *c) {
}
else
{
addReply
(
c
,
shared
.
nullbulk
);
}
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
listNode
*
ln
=
listIndex
(
o
->
ptr
,
index
);
if
(
ln
!=
NULL
)
{
value
=
listNodeValue
(
ln
);
...
...
@@ -5349,7 +5349,7 @@ static void lsetCommand(redisClient *c) {
addReply
(
c
,
shared
.
ok
);
server
.
dirty
++
;
}
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
listNode
*
ln
=
listIndex
(
o
->
ptr
,
index
);
if
(
ln
==
NULL
)
{
addReply
(
c
,
shared
.
outofrangeerr
);
...
...
@@ -5461,7 +5461,7 @@ static void ltrimCommand(redisClient *c) {
if
(
o
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
o
->
ptr
=
ziplistDeleteRange
(
o
->
ptr
,
0
,
ltrim
);
o
->
ptr
=
ziplistDeleteRange
(
o
->
ptr
,
-
rtrim
,
rtrim
);
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
list
=
o
->
ptr
;
for
(
j
=
0
;
j
<
ltrim
;
j
++
)
{
ln
=
listFirst
(
list
);
...
...
@@ -9151,7 +9151,7 @@ static int rewriteAppendOnlyFile(char *filename) {
}
p
=
ziplistNext
(
zl
,
p
);
}
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_LIST
)
{
}
else
if
(
o
->
encoding
==
REDIS_ENCODING_
LINKED
LIST
)
{
list
*
list
=
o
->
ptr
;
listNode
*
ln
;
listIter
li
;
...
...
tests/support/test.tcl
View file @
d52e5888
...
...
@@ -26,6 +26,8 @@ proc assert_error {pattern code} {
}
proc assert_encoding
{
enc key
}
{
# swapped out value doesn't have encoding, so swap in first
r debug swapin $key
assert_match
"* encoding:
$enc
*"
[
r debug object $key
]
}
...
...
tests/unit/type/list.tcl
View file @
d52e5888
...
...
@@ -33,7 +33,7 @@ start_server {
# first lpush then rpush
assert_equal 1
[
r lpush mylist1 $large_value
]
assert_encoding list mylist1
assert_encoding
linked
list mylist1
assert_equal 2
[
r rpush mylist1 b
]
assert_equal 3
[
r rpush mylist1 c
]
assert_equal 3
[
r llen mylist1
]
...
...
@@ -43,7 +43,7 @@ start_server {
# first rpush then lpush
assert_equal 1
[
r rpush mylist2 $large_value
]
assert_encoding list mylist2
assert_encoding
linked
list mylist2
assert_equal 2
[
r lpush mylist2 b
]
assert_equal 3
[
r lpush mylist2 c
]
assert_equal 3
[
r llen mylist2
]
...
...
@@ -70,12 +70,12 @@ start_server {
assert_encoding ziplist $key
}
proc create_list
{
key entries
}
{
proc create_
linked
list
{
key entries
}
{
r del $key
r rpush $key
"aaaaaaaaaaaaaaaaa"
foreach entry $entries
{
r rpush $key $entry
}
assert_equal
"aaaaaaaaaaaaaaaaa"
[
r lpop $key
]
assert_encoding list $key
assert_encoding
linked
list $key
}
test
{
LPUSHX, RPUSHX - generic
}
{
...
...
@@ -86,7 +86,7 @@ start_server {
assert_equal 0
[
r llen xlist
]
}
foreach type
{
ziplist list
}
{
foreach type
{
ziplist
linked
list
}
{
test
"LPUSHX, RPUSHX -
$type
"
{
create_$type xlist
{
b c
}
assert_equal 3
[
r rpushx xlist d
]
...
...
@@ -119,18 +119,18 @@ start_server {
# convert when a large value is pushed
create_ziplist xlist a
assert_equal 2
[
r rpushx xlist $large_value
]
assert_encoding list xlist
assert_encoding
linked
list xlist
create_ziplist xlist a
assert_equal 2
[
r lpushx xlist $large_value
]
assert_encoding list xlist
assert_encoding
linked
list xlist
# convert when the length threshold is exceeded
create_ziplist xlist
[
lrepeat 256 a
]
assert_equal 257
[
r rpushx xlist b
]
assert_encoding list xlist
assert_encoding
linked
list xlist
create_ziplist xlist
[
lrepeat 256 a
]
assert_equal 257
[
r lpushx xlist b
]
assert_encoding list xlist
assert_encoding
linked
list xlist
}
test
{
LINSERT convert from ziplist to list
}
{
...
...
@@ -139,18 +139,18 @@ start_server {
# convert when a large value is inserted
create_ziplist xlist a
assert_equal 2
[
r linsert xlist before a $large_value
]
assert_encoding list xlist
assert_encoding
linked
list xlist
create_ziplist xlist a
assert_equal 2
[
r linsert xlist after a $large_value
]
assert_encoding list xlist
assert_encoding
linked
list xlist
# convert when the length threshold is exceeded
create_ziplist xlist
[
lrepeat 256 a
]
assert_equal 257
[
r linsert xlist before a a
]
assert_encoding list xlist
assert_encoding
linked
list xlist
create_ziplist xlist
[
lrepeat 256 a
]
assert_equal 257
[
r linsert xlist after a a
]
assert_encoding list xlist
assert_encoding
linked
list xlist
# don't convert when the value could not be inserted
create_ziplist xlist
[
lrepeat 256 a
]
...
...
@@ -161,7 +161,7 @@ start_server {
assert_encoding ziplist xlist
}
foreach
{
type num
}
{
ziplist 250 list 500
}
{
foreach
{
type num
}
{
ziplist 250
linked
list 500
}
{
proc check_numbered_list_consistency
{
key
}
{
set len
[
r llen $key
]
for
{
set i 0
}
{
$i
< $len
}
{
incr i
}
{
...
...
@@ -227,7 +227,7 @@ start_server {
assert_error ERR*
{
r rpush mylist 0
}
}
foreach type
{
ziplist list
}
{
foreach type
{
ziplist
linked
list
}
{
test
"RPOPLPUSH base case -
$type
"
{
r del mylist1 mylist2
create_$type mylist1
{
a b c d
}
...
...
@@ -245,7 +245,7 @@ start_server {
assert_equal
{
c a b
}
[
r lrange mylist 0 -1
]
}
foreach othertype
{
ziplist list
}
{
foreach othertype
{
ziplist
linked
list
}
{
test
"RPOPLPUSH with
$type
source and existing target
$othertype
"
{
create_$type srclist
{
a b c d
}
create_$othertype dstlist
{
x
}
...
...
@@ -285,7 +285,7 @@ start_server {
assert_equal
{}
[
r rpoplpush srclist dstlist
]
}
{}
foreach type
{
ziplist list
}
{
foreach type
{
ziplist
linked
list
}
{
test
"Basic LPOP/RPOP -
$type
"
{
create_$type mylist
{
0 1 2
}
assert_equal 0
[
r lpop mylist
]
...
...
@@ -305,7 +305,7 @@ start_server {
assert_error ERR*kind*
{
r rpop notalist
}
}
foreach
{
type num
}
{
ziplist 250 list 500
}
{
foreach
{
type num
}
{
ziplist 250
linked
list 500
}
{
test
"Mass RPOP/LPOP -
$type
"
{
r del mylist
set sum1 0
...
...
@@ -323,7 +323,7 @@ start_server {
}
}
foreach type
{
ziplist list
}
{
foreach type
{
ziplist
linked
list
}
{
test
"LRANGE basics -
$type
"
{
create_$type mylist
{
0 1 2 3 4 5 6 7 8 9
}
assert_equal
{
1 2 3 4 5 6 7 8
}
[
r lrange mylist 1 -2
]
...
...
@@ -346,36 +346,65 @@ start_server {
assert_equal
{}
[
r lrange nosuchkey 0 1
]
}
foreach type
{
ziplist list
}
{
test
"LTRIM basics -
$type
"
{
create_$type mylist
"foo"
for
{
set i 0
}
{
$i
< 100
}
{
incr i
}
{
r lpush mylist $i
r ltrim mylist 0 4
}
foreach type
{
ziplist linkedlist
}
{
proc trim_list
{
type min max
}
{
r del mylist
create_$type mylist
{
1 2 3 4 5
}
r ltrim mylist $min $max
r lrange mylist 0 -1
}
{
99 98 97 96 95
}
test
"LTRIM stress testing -
$type
"
{
set mylist
{}
for
{
set i 0
}
{
$i
< 20
}
{
incr i
}
{
lappend mylist $i
}
}
for
{
set j 0
}
{
$j
< 100
}
{
incr j
}
{
create_$type mylist $mylist
test
"LTRIM basics -
$type
"
{
assert_equal
{
1
}
[
trim_list $type 0 0
]
assert_equal
{
1 2
}
[
trim_list $type 0 1
]
assert_equal
{
1 2 3
}
[
trim_list $type 0 2
]
assert_equal
{
2 3
}
[
trim_list $type 1 2
]
assert_equal
{
2 3 4 5
}
[
trim_list $type 1 -1
]
assert_equal
{
2 3 4
}
[
trim_list $type 1 -2
]
assert_equal
{
4 5
}
[
trim_list $type -2 -1
]
assert_equal
{
5
}
[
trim_list $type -1 -1
]
assert_equal
{
1 2 3 4 5
}
[
trim_list $type -5 -1
]
assert_equal
{
1 2 3 4 5
}
[
trim_list $type -10 10
]
assert_equal
{
1 2 3 4 5
}
[
trim_list $type 0 5
]
assert_equal
{
1 2 3 4 5
}
[
trim_list $type 0 10
]
}
# Trim at random
set a
[
randomInt 20
]
set b
[
randomInt 20
]
r ltrim mylist $a $b
assert_equal
[
lrange $mylist $a $b
]
[
r lrange mylist 0 -1
]
tags
{
"slow"
}
{
test
"LTRIM stress testing -
$type
"
{
set mylist
{}
set startlen 32
r del mylist
for
{
set i 0
}
{
$i
< $startlen
}
{
incr i
}
{
set str
[
randomInt 9223372036854775807
]
r rpush mylist $str
lappend mylist $str
}
# do a push/pop of a large value to convert to a real list
if
{
$type
eq
"list"
}
{
r rpush mylist
"aaaaaaaaaaaaaaaaa"
r rpop mylist
assert_encoding linkedlist mylist
}
for
{
set i 0
}
{
$i
< 10000
}
{
incr i
}
{
set min
[
expr
{
int
(
rand
()
*$startlen
)}]
set max
[
expr
{
$min
+int
(
rand
()
*$startlen
)}]
set mylist
[
lrange $mylist $min $max
]
r ltrim mylist $min $max
assert_equal $mylist
[
r lrange mylist 0 -1
]
for
{
set j
[
r llen mylist
]}
{
$j
< $startlen
}
{
incr j
}
{
set str
[
randomInt 9223372036854775807
]
r rpush mylist $str
lappend mylist $str
}
}
}
}
}
foreach type
{
ziplist list
}
{
foreach type
{
ziplist
linked
list
}
{
test
"LSET -
$type
"
{
create_$type mylist
{
99 98 97 96 95
}
r lset mylist 1 foo
...
...
@@ -397,7 +426,7 @@ start_server {
assert_error ERR*value*
{
r lset nolist 0 foo
}
}
foreach type
{
ziplist list
}
{
foreach type
{
ziplist
linked
list
}
{
test
"LREM remove all the occurrences -
$type
"
{
create_$type mylist
{
foo bar foobar foobared zap bar test foo
}
assert_equal 2
[
r lrem mylist 0 bar
]
...
...
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