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
724a51b1
Commit
724a51b1
authored
Sep 18, 2009
by
antirez
Browse files
LREM fixed, used to crash since the new object integer encoding is on the stage
parent
d4465900
Changes
2
Show whitespace changes
Inline
Side-by-side
redis.c
View file @
724a51b1
...
...
@@ -1836,10 +1836,31 @@ static robj *tryObjectSharing(robj *o) {
}
}
/* Check if the nul-terminated string 's' can be represented by a long
* (that is, is a number that fits into long without any other space or
* character before or after the digits).
*
* If so, the function returns REDIS_OK and *longval is set to the value
* of the number. Otherwise REDIS_ERR is returned */
static
int
isStringRepresentableAsLong
(
char
*
s
,
long
*
longval
)
{
char
buf
[
32
],
*
endptr
;
long
value
;
int
slen
;
value
=
strtol
(
s
,
&
endptr
,
10
);
if
(
endptr
[
0
]
!=
'\0'
)
return
REDIS_ERR
;
slen
=
snprintf
(
buf
,
32
,
"%ld"
,
value
);
/* If the number converted back into a string is not identical
* then it's not possible to encode the string as integer */
if
(
strlen
(
buf
)
!=
(
unsigned
)
slen
||
memcmp
(
buf
,
s
,
slen
))
return
REDIS_ERR
;
if
(
longval
)
*
longval
=
value
;
return
REDIS_OK
;
}
/* Try to encode a string object in order to save space */
static
int
tryObjectEncoding
(
robj
*
o
)
{
long
value
;
char
*
endptr
,
buf
[
32
];
sds
s
=
o
->
ptr
;
if
(
o
->
encoding
!=
REDIS_ENCODING_RAW
)
...
...
@@ -1853,15 +1874,8 @@ static int tryObjectEncoding(robj *o) {
/* Currently we try to encode only strings */
assert
(
o
->
type
==
REDIS_STRING
);
/* Check if it's possible to encode this value as a long. We are assuming
* that sizeof(long) = sizeof(void) in all the supported archs. */
value
=
strtol
(
s
,
&
endptr
,
10
);
if
(
endptr
[
0
]
!=
'\0'
)
return
REDIS_ERR
;
snprintf
(
buf
,
32
,
"%ld"
,
value
);
/* If the number converted back into a string is not identical
* then it's not possible to encode the string as integer */
if
(
strlen
(
buf
)
!=
sdslen
(
s
)
||
memcmp
(
buf
,
s
,
sdslen
(
s
)))
return
REDIS_ERR
;
/* Check if we can represent this string as a long integer */
if
(
isStringRepresentableAsLong
(
s
,
&
value
)
==
REDIS_ERR
)
return
REDIS_ERR
;
/* Ok, this object can be encoded */
o
->
encoding
=
REDIS_ENCODING_INT
;
...
...
@@ -1886,6 +1900,25 @@ static robj *getDecodedObject(const robj *o) {
}
}
static
int
compareStringObjects
(
robj
*
a
,
robj
*
b
)
{
assert
(
a
->
type
==
REDIS_STRING
&&
b
->
type
==
REDIS_STRING
);
if
(
a
->
encoding
==
REDIS_ENCODING_INT
&&
b
->
encoding
==
REDIS_ENCODING_INT
){
return
(
long
)
a
->
ptr
-
(
long
)
b
->
ptr
;
}
else
{
int
retval
;
incrRefCount
(
a
);
incrRefCount
(
b
);
if
(
a
->
encoding
!=
REDIS_ENCODING_RAW
)
a
=
getDecodedObject
(
a
);
if
(
b
->
encoding
!=
REDIS_ENCODING_RAW
)
b
=
getDecodedObject
(
a
);
retval
=
sdscmp
(
a
->
ptr
,
b
->
ptr
);
decrRefCount
(
a
);
decrRefCount
(
b
);
return
retval
;
}
}
/*============================ DB saving/loading ============================ */
static
int
rdbSaveType
(
FILE
*
fp
,
unsigned
char
type
)
{
...
...
@@ -3090,7 +3123,7 @@ static void lremCommand(redisClient *c) {
robj
*
ele
=
listNodeValue
(
ln
);
next
=
fromtail
?
ln
->
prev
:
ln
->
next
;
if
(
sdscmp
(
ele
->
ptr
,
c
->
argv
[
3
]
->
ptr
)
==
0
)
{
if
(
compareStringObjects
(
ele
,
c
->
argv
[
3
])
==
0
)
{
listDelNode
(
list
,
ln
);
server
.
dirty
++
;
removed
++
;
...
...
@@ -4375,6 +4408,8 @@ static void debugCommand(redisClient *c) {
#ifdef HAVE_BACKTRACE
static
struct
redisFunctionSym
symsTable
[]
=
{
{
"compareStringObjects"
,
(
unsigned
long
)
compareStringObjects
},
{
"isStringRepresentableAsLong"
,
(
unsigned
long
)
isStringRepresentableAsLong
},
{
"dictEncObjKeyCompare"
,
(
unsigned
long
)
dictEncObjKeyCompare
},
{
"dictEncObjHash"
,
(
unsigned
long
)
dictEncObjHash
},
{
"incrDecrCommand"
,
(
unsigned
long
)
incrDecrCommand
},
...
...
test-redis.tcl
View file @
724a51b1
...
...
@@ -651,6 +651,14 @@ proc main {server port} {
list
[
$r
lrange mylist 0 -1
]
$res
}
{{
foo bar foobar foobared zap test
}
2
}
test
{
LREM, deleting objects that may be encoded as integers
}
{
$r lpush myotherlist 1
$r lpush myotherlist 2
$r lpush myotherlist 3
$r lrem myotherlist 1 2
$r llen myotherlist
}
{
2
}
test
{
MGET
}
{
$r flushall
$r set foo 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