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
abce5627
Commit
abce5627
authored
May 12, 2010
by
antirez
Browse files
Merge branch 'vm-speedup'
parents
6485f293
ad30aa60
Changes
3
Hide whitespace changes
Inline
Side-by-side
redis.c
View file @
abce5627
...
...
@@ -622,6 +622,7 @@ static int pubsubUnsubscribeAllPatterns(redisClient *c, int notify);
static void freePubsubPattern(void *p);
static int listMatchPubsubPattern(void *a, void *b);
static int compareStringObjects(robj *a, robj *b);
static int equalStringObjects(robj *a, robj *b);
static void usage();
static int rewriteAppendOnlyFileBackground(void);
static int vmSwapObjectBlocking(robj *key, robj *val);
...
...
@@ -1022,6 +1023,30 @@ static long long memtoll(const char *p, int *err) {
return val*mul;
}
/* Convert a long long into a string. Returns the number of
* characters needed to represent the number, that can be shorter if passed
* buffer length is not enough to store the whole number. */
static int ll2string(char *s, size_t len, long long value) {
char buf[32], *p;
unsigned long long v;
size_t l;
if (len == 0) return 0;
v = (value < 0) ? -value : value;
p = buf+31; /* point to the last character */
do {
*p-- = '0'+(v%10);
v /= 10;
} while(v);
if (value < 0) *p-- = '-';
p++;
l = 32-(p-buf);
if (l+1 > len) l = len-1; /* Make sure it fits, including the nul term */
memcpy(s,p,l);
s[l] = '\0';
return l;
}
static void redisLog(int level, const char *fmt, ...) {
va_list ap;
FILE *fp;
...
...
@@ -1104,8 +1129,8 @@ static int dictEncObjKeyCompare(void *privdata, const void *key1,
int cmp;
if (o1->encoding == REDIS_ENCODING_INT &&
o2->encoding == REDIS_ENCODING_INT
&&
o1->ptr == o2->ptr
) return 1
;
o2->encoding == REDIS_ENCODING_INT
)
return
o1->ptr == o2->ptr;
o1 = getDecodedObject(o1);
o2 = getDecodedObject(o2);
...
...
@@ -1125,7 +1150,7 @@ static unsigned int dictEncObjHash(const void *key) {
char buf[32];
int len;
len =
snp
rin
tf
(buf,32,
"%ld",
(long)o->ptr);
len =
ll2st
rin
g
(buf,32,(long)o->ptr);
return dictGenHashFunction((unsigned char*)buf, len);
} else {
unsigned int hash;
...
...
@@ -2656,7 +2681,7 @@ static void *dupClientReplyValue(void *o) {
}
static int listMatchObjects(void *a, void *b) {
return
compare
StringObjects(a,b)
== 0
;
return
equal
StringObjects(a,b);
}
static redisClient *createClient(int fd) {
...
...
@@ -2896,7 +2921,7 @@ static robj *createStringObjectFromLongLong(long long value) {
o->encoding = REDIS_ENCODING_INT;
o->ptr = (void*)((long)value);
} else {
o
->ptr = sdscatprintf(sdsempty(),"%lld",
value);
o
= createObject(REDIS_STRING,sdsfromlonglong(
value)
)
;
}
}
return o;
...
...
@@ -3111,7 +3136,7 @@ static int isStringRepresentableAsLong(sds s, long *longval) {
value = strtol(s, &endptr, 10);
if (endptr[0] != '\0') return REDIS_ERR;
slen =
snp
rin
tf
(buf,32,
"%ld",
value);
slen =
ll2st
rin
g
(buf,32,value);
/* If the number converted back into a string is not identical
* then it's not possible to encode the string as integer */
...
...
@@ -3164,7 +3189,7 @@ static robj *getDecodedObject(robj *o) {
if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_INT) {
char buf[32];
snp
rin
tf
(buf,32,
"%ld",
(long)o->ptr);
ll2st
rin
g
(buf,32,(long)o->ptr);
dec = createStringObject(buf,strlen(buf));
return dec;
} else {
...
...
@@ -3174,7 +3199,7 @@ static robj *getDecodedObject(robj *o) {
/* Compare two string objects via strcmp() or alike.
* Note that the objects may be integer-encoded. In such a case we
* use
snp
rin
tf
() to get a string representation of the numbers on the stack
* use
ll2st
rin
g
() to get a string representation of the numbers on the stack
* and compare the strings, it's much faster than calling getDecodedObject().
*
* Important note: if objects are not integer encoded, but binary-safe strings,
...
...
@@ -3187,14 +3212,14 @@ static int compareStringObjects(robj *a, robj *b) {
if (a == b) return 0;
if (a->encoding != REDIS_ENCODING_RAW) {
snp
rin
tf
(bufa,sizeof(bufa),
"%ld",
(long) a->ptr);
ll2st
rin
g
(bufa,sizeof(bufa),(long) a->ptr);
astr = bufa;
bothsds = 0;
} else {
astr = a->ptr;
}
if (b->encoding != REDIS_ENCODING_RAW) {
snp
rin
tf
(bufb,sizeof(bufb),
"%ld",
(long) b->ptr);
ll2st
rin
g
(bufb,sizeof(bufb),(long) b->ptr);
bstr = bufb;
bothsds = 0;
} else {
...
...
@@ -3203,6 +3228,18 @@ static int compareStringObjects(robj *a, robj *b) {
return bothsds ? sdscmp(astr,bstr) : strcmp(astr,bstr);
}
/* Equal string objects return 1 if the two objects are the same from the
* point of view of a string comparison, otherwise 0 is returned. Note that
* this function is faster then checking for (compareStringObject(a,b) == 0)
* because it can perform some more optimization. */
static int equalStringObjects(robj *a, robj *b) {
if (a->encoding != REDIS_ENCODING_RAW && b->encoding != REDIS_ENCODING_RAW){
return a->ptr == b->ptr;
} else {
return compareStringObjects(a,b) == 0;
}
}
static size_t stringObjectLen(robj *o) {
redisAssert(o->type == REDIS_STRING);
if (o->encoding == REDIS_ENCODING_RAW) {
...
...
@@ -3210,7 +3247,7 @@ static size_t stringObjectLen(robj *o) {
} else {
char buf[32];
return
snp
rin
tf
(buf,32,
"%ld",
(long)o->ptr);
return
ll2st
rin
g
(buf,32,(long)o->ptr);
}
}
...
...
@@ -3351,7 +3388,7 @@ static int rdbTryIntegerEncoding(char *s, size_t len, unsigned char *enc) {
/* Check if it's possible to encode this value as a number */
value = strtoll(s, &endptr, 10);
if (endptr[0] != '\0') return 0;
snp
rin
tf
(buf,32,
"%lld",
value);
ll2st
rin
g
(buf,32,value);
/* If the number converted back into a string is not identical
* then it's not possible to encode the string as integer */
...
...
@@ -3760,7 +3797,11 @@ static uint32_t rdbLoadLen(FILE *fp, int *isencoded) {
}
}
static robj *rdbLoadIntegerObject(FILE *fp, int enctype) {
/* Load an integer-encoded object from file 'fp', with the specified
* encoding type 'enctype'. If encode is true the function may return
* an integer-encoded object as reply, otherwise the returned object
* will always be encoded as a raw string. */
static robj *rdbLoadIntegerObject(FILE *fp, int enctype, int encode) {
unsigned char enc[4];
long long val;
...
...
@@ -3781,7 +3822,10 @@ static robj *rdbLoadIntegerObject(FILE *fp, int enctype) {
val = 0; /* anti-warning */
redisPanic("Unknown RDB integer encoding type");
}
return createObject(REDIS_STRING,sdscatprintf(sdsempty(),"%lld",val));
if (encode)
return createStringObjectFromLongLong(val);
else
return createObject(REDIS_STRING,sdsfromlonglong(val));
}
static robj *rdbLoadLzfStringObject(FILE*fp) {
...
...
@@ -3803,7 +3847,7 @@ err:
return NULL;
}
static robj *rdbLoadStringObject(FILE*fp) {
static robj *rdb
Generic
LoadStringObject(FILE*fp
, int encode
) {
int isencoded;
uint32_t len;
sds val;
...
...
@@ -3814,7 +3858,7 @@ static robj *rdbLoadStringObject(FILE*fp) {
case REDIS_RDB_ENC_INT8:
case REDIS_RDB_ENC_INT16:
case REDIS_RDB_ENC_INT32:
return rdbLoadIntegerObject(fp,len);
return rdbLoadIntegerObject(fp,len
,encode
);
case REDIS_RDB_ENC_LZF:
return rdbLoadLzfStringObject(fp);
default:
...
...
@@ -3831,6 +3875,14 @@ static robj *rdbLoadStringObject(FILE*fp) {
return createObject(REDIS_STRING,val);
}
static robj *rdbLoadStringObject(FILE *fp) {
return rdbGenericLoadStringObject(fp,0);
}
static robj *rdbLoadEncodedStringObject(FILE *fp) {
return rdbGenericLoadStringObject(fp,1);
}
/* For information about double serialization check rdbSaveDoubleValue() */
static int rdbLoadDoubleValue(FILE *fp, double *val) {
char buf[128];
...
...
@@ -3857,7 +3909,7 @@ static robj *rdbLoadObject(int type, FILE *fp) {
redisLog(REDIS_DEBUG,"LOADING OBJECT %d (at %d)\n",type,ftell(fp));
if (type == REDIS_STRING) {
/* Read string value */
if ((o = rdbLoadStringObject(fp)) == NULL) return NULL;
if ((o = rdbLoad
Encoded
StringObject(fp)) == NULL) return NULL;
o = tryObjectEncoding(o);
} else if (type == REDIS_LIST || type == REDIS_SET) {
/* Read list/set value */
...
...
@@ -3873,7 +3925,7 @@ static robj *rdbLoadObject(int type, FILE *fp) {
while(listlen--) {
robj *ele;
if ((ele = rdbLoadStringObject(fp)) == NULL) return NULL;
if ((ele = rdbLoad
Encoded
StringObject(fp)) == NULL) return NULL;
ele = tryObjectEncoding(ele);
if (type == REDIS_LIST) {
listAddNodeTail((list*)o->ptr,ele);
...
...
@@ -3894,7 +3946,7 @@ static robj *rdbLoadObject(int type, FILE *fp) {
robj *ele;
double *score = zmalloc(sizeof(double));
if ((ele = rdbLoadStringObject(fp)) == NULL) return NULL;
if ((ele = rdbLoad
Encoded
StringObject(fp)) == NULL) return NULL;
ele = tryObjectEncoding(ele);
if (rdbLoadDoubleValue(fp,score) == -1) return NULL;
dictAdd(zs->dict,ele,score);
...
...
@@ -4850,7 +4902,7 @@ static void lremCommand(redisClient *c) {
robj *ele = listNodeValue(ln);
next = fromtail ? ln->prev : ln->next;
if (
compare
StringObjects(ele,c->argv[3])
== 0
) {
if (
equal
StringObjects(ele,c->argv[3])) {
listDelNode(list,ln);
server.dirty++;
removed++;
...
...
@@ -5454,7 +5506,7 @@ static int zslDelete(zskiplist *zsl, double score, robj *obj) {
/* We may have multiple elements with the same score, what we need
* is to find the element with both the right score and object. */
x = x->forward[0];
if (x && score == x->score &&
compare
StringObjects(x->obj,obj)
== 0
) {
if (x && score == x->score &&
equal
StringObjects(x->obj,obj)) {
zslDeleteNode(zsl, x, update);
zslFreeNode(x);
return 1;
...
...
@@ -5559,7 +5611,7 @@ static unsigned long zslGetRank(zskiplist *zsl, double score, robj *o) {
}
/* x might be equal to zsl->header, so test if obj is non-NULL */
if (x->obj &&
compare
StringObjects(x->obj,o)
== 0
) {
if (x->obj &&
equal
StringObjects(x->obj,o)) {
return rank;
}
}
...
...
@@ -9623,7 +9675,7 @@ static int dontWaitForSwappedKey(redisClient *c, robj *key) {
/* Remove the key from the list of keys this client is waiting for. */
listRewind(c->io_keys,&li);
while ((ln = listNext(&li)) != NULL) {
if (
compare
StringObjects(ln->value,key)
== 0
) {
if (
equal
StringObjects(ln->value,key)) {
listDelNode(c->io_keys,ln);
break;
}
...
...
@@ -9850,7 +9902,7 @@ static int listMatchPubsubPattern(void *a, void *b) {
pubsubPattern *pa = a, *pb = b;
return (pa->client == pb->client) &&
(
compare
StringObjects(pa->pattern,pb->pattern)
== 0
);
(
equal
StringObjects(pa->pattern,pb->pattern));
}
/* Subscribe a client to a channel. Returns 1 if the operation succeeded, or
...
...
sds.c
View file @
abce5627
...
...
@@ -342,3 +342,18 @@ void sdsfreesplitres(sds *tokens, int count) {
sdsfree
(
tokens
[
count
]);
zfree
(
tokens
);
}
sds
sdsfromlonglong
(
long
long
value
)
{
char
buf
[
32
],
*
p
;
unsigned
long
long
v
;
v
=
(
value
<
0
)
?
-
value
:
value
;
p
=
buf
+
31
;
/* point to the last character */
do
{
*
p
--
=
'0'
+
(
v
%
10
);
v
/=
10
;
}
while
(
v
);
if
(
value
<
0
)
*
p
--
=
'-'
;
p
++
;
return
sdsnewlen
(
p
,
32
-
(
p
-
buf
));
}
sds.h
View file @
abce5627
...
...
@@ -68,5 +68,6 @@ sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count);
void
sdsfreesplitres
(
sds
*
tokens
,
int
count
);
void
sdstolower
(
sds
s
);
void
sdstoupper
(
sds
s
);
sds
sdsfromlonglong
(
long
long
value
);
#endif
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