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
Hide 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