Commit ee14da56 authored by antirez's avatar antirez
Browse files

long long to string conversion speedup applied in other places as well. Still...

long long to string conversion speedup applied in other places as well. Still the code has bugs, fixing right now...
parent e5b7a215
...@@ -1023,6 +1023,30 @@ static long long memtoll(const char *p, int *err) { ...@@ -1023,6 +1023,30 @@ static long long memtoll(const char *p, int *err) {
return val*mul; 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, ...) { static void redisLog(int level, const char *fmt, ...) {
va_list ap; va_list ap;
FILE *fp; FILE *fp;
...@@ -1126,7 +1150,7 @@ static unsigned int dictEncObjHash(const void *key) { ...@@ -1126,7 +1150,7 @@ static unsigned int dictEncObjHash(const void *key) {
char buf[32]; char buf[32];
int len; int len;
len = snprintf(buf,32,"%ld",(long)o->ptr); len = ll2string(buf,32,(long)o->ptr);
return dictGenHashFunction((unsigned char*)buf, len); return dictGenHashFunction((unsigned char*)buf, len);
} else { } else {
unsigned int hash; unsigned int hash;
...@@ -2897,19 +2921,7 @@ static robj *createStringObjectFromLongLong(long long value) { ...@@ -2897,19 +2921,7 @@ static robj *createStringObjectFromLongLong(long long value) {
o->encoding = REDIS_ENCODING_INT; o->encoding = REDIS_ENCODING_INT;
o->ptr = (void*)((long)value); o->ptr = (void*)((long)value);
} else { } else {
char buf[32], *p; o = createObject(REDIS_STRING,sdsfromlonglong(value));
char *c = "0123456789";
unsigned long v;
v = (value < 0) ? -value : value;
p = buf+31; /* point to the last character */
while(v) {
*p-- = c[v%10];
v /= 10;
}
if (value < 0) *p-- = '-';
p++;
o = createObject(REDIS_STRING,sdsnewlen(p,32-(p-buf+1)));
} }
} }
return o; return o;
...@@ -3124,7 +3136,7 @@ static int isStringRepresentableAsLong(sds s, long *longval) { ...@@ -3124,7 +3136,7 @@ static int isStringRepresentableAsLong(sds s, long *longval) {
value = strtol(s, &endptr, 10); value = strtol(s, &endptr, 10);
if (endptr[0] != '\0') return REDIS_ERR; if (endptr[0] != '\0') return REDIS_ERR;
slen = snprintf(buf,32,"%ld",value); slen = ll2string(buf,32,value);
/* If the number converted back into a string is not identical /* If the number converted back into a string is not identical
* then it's not possible to encode the string as integer */ * then it's not possible to encode the string as integer */
...@@ -3177,7 +3189,7 @@ static robj *getDecodedObject(robj *o) { ...@@ -3177,7 +3189,7 @@ static robj *getDecodedObject(robj *o) {
if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_INT) { if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_INT) {
char buf[32]; char buf[32];
snprintf(buf,32,"%ld",(long)o->ptr); ll2string(buf,32,(long)o->ptr);
dec = createStringObject(buf,strlen(buf)); dec = createStringObject(buf,strlen(buf));
return dec; return dec;
} else { } else {
...@@ -3187,7 +3199,7 @@ static robj *getDecodedObject(robj *o) { ...@@ -3187,7 +3199,7 @@ static robj *getDecodedObject(robj *o) {
/* Compare two string objects via strcmp() or alike. /* Compare two string objects via strcmp() or alike.
* Note that the objects may be integer-encoded. In such a case we * Note that the objects may be integer-encoded. In such a case we
* use snprintf() to get a string representation of the numbers on the stack * use ll2string() to get a string representation of the numbers on the stack
* and compare the strings, it's much faster than calling getDecodedObject(). * and compare the strings, it's much faster than calling getDecodedObject().
* *
* Important note: if objects are not integer encoded, but binary-safe strings, * Important note: if objects are not integer encoded, but binary-safe strings,
...@@ -3200,14 +3212,14 @@ static int compareStringObjects(robj *a, robj *b) { ...@@ -3200,14 +3212,14 @@ static int compareStringObjects(robj *a, robj *b) {
if (a == b) return 0; if (a == b) return 0;
if (a->encoding != REDIS_ENCODING_RAW) { if (a->encoding != REDIS_ENCODING_RAW) {
snprintf(bufa,sizeof(bufa),"%ld",(long) a->ptr); ll2string(bufa,sizeof(bufa),(long) a->ptr);
astr = bufa; astr = bufa;
bothsds = 0; bothsds = 0;
} else { } else {
astr = a->ptr; astr = a->ptr;
} }
if (b->encoding != REDIS_ENCODING_RAW) { if (b->encoding != REDIS_ENCODING_RAW) {
snprintf(bufb,sizeof(bufb),"%ld",(long) b->ptr); ll2string(bufb,sizeof(bufb),(long) b->ptr);
bstr = bufb; bstr = bufb;
bothsds = 0; bothsds = 0;
} else { } else {
...@@ -3235,7 +3247,7 @@ static size_t stringObjectLen(robj *o) { ...@@ -3235,7 +3247,7 @@ static size_t stringObjectLen(robj *o) {
} else { } else {
char buf[32]; char buf[32];
return snprintf(buf,32,"%ld",(long)o->ptr); return ll2string(buf,32,(long)o->ptr);
} }
} }
...@@ -3376,7 +3388,7 @@ static int rdbTryIntegerEncoding(char *s, size_t len, unsigned char *enc) { ...@@ -3376,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 */ /* Check if it's possible to encode this value as a number */
value = strtoll(s, &endptr, 10); value = strtoll(s, &endptr, 10);
if (endptr[0] != '\0') return 0; if (endptr[0] != '\0') return 0;
snprintf(buf,32,"%lld",value); ll2string(buf,32,value);
/* If the number converted back into a string is not identical /* If the number converted back into a string is not identical
* then it's not possible to encode the string as integer */ * then it's not possible to encode the string as integer */
......
...@@ -342,3 +342,18 @@ void sdsfreesplitres(sds *tokens, int count) { ...@@ -342,3 +342,18 @@ void sdsfreesplitres(sds *tokens, int count) {
sdsfree(tokens[count]); sdsfree(tokens[count]);
zfree(tokens); 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));
}
...@@ -68,5 +68,6 @@ sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count); ...@@ -68,5 +68,6 @@ sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count);
void sdsfreesplitres(sds *tokens, int count); void sdsfreesplitres(sds *tokens, int count);
void sdstolower(sds s); void sdstolower(sds s);
void sdstoupper(sds s); void sdstoupper(sds s);
sds sdsfromlonglong(long long value);
#endif #endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment