diff options
| author | Matt Stancliff <matt@genges.com> | 2015-01-20 10:58:35 -0500 | 
|---|---|---|
| committer | Matt Stancliff <matt@genges.com> | 2015-01-22 16:00:38 -0500 | 
| commit | 195aca34274bd633f6ecfca2e9a4e76ae669ae0e (patch) | |
| tree | 70b3a98c84f26fa8d89b61b8b629327004411bbb | |
| parent | 802456def1949cc1b1eef21cd5c8290161c4f434 (diff) | |
| download | hiredict-195aca34274bd633f6ecfca2e9a4e76ae669ae0e.tar.xz | |
Improve digit counting for multibulk creation
This replaces the old intlen() implementation with a slightly
faster way of counting digits.
Implementation taken from the same place where digits10() in
redis/src/util.c came from.
The old 'intlen' allowed negative inputs, but no usage in hiredis
was passing negative numbers, so that ability is removed.  Also,
the new implementation can count higher (uint64_t) instead of
limited to just int as before.
Fixes #295 by replacing implementation
| -rw-r--r-- | hiredis.c | 32 | ||||
| -rw-r--r-- | hiredis.h | 1 | 
2 files changed, 17 insertions, 16 deletions
| @@ -186,23 +186,23 @@ static void *createNilObject(const redisReadTask *task) {      return r;  } -/* Calculate the number of bytes needed to represent an integer as string. */ -static int intlen(int i) { -    int len = 0; -    if (i < 0) { -        len++; -        i = -i; -    } -    do { -        len++; -        i /= 10; -    } while(i); -    return len; +/* Return the number of digits of 'v' when converted to string in radix 10. + * Implementation borrowed from link in redis/src/util.c:string2ll(). */ +static uint32_t countDigits(uint64_t v) { +  uint32_t result = 1; +  for (;;) { +    if (v < 10) return result; +    if (v < 100) return result + 1; +    if (v < 1000) return result + 2; +    if (v < 10000) return result + 3; +    v /= 10000U; +    result += 4; +  }  }  /* Helper that calculates the bulk length given a certain string length. */  static size_t bulklen(size_t len) { -    return 1+intlen(len)+2+len+2; +    return 1+countDigits(len)+2+len+2;  }  int redisvFormatCommand(char **target, const char *format, va_list ap) { @@ -392,7 +392,7 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {      curarg = NULL;      /* Add bytes needed to hold multi bulk count */ -    totlen += 1+intlen(argc)+2; +    totlen += 1+countDigits(argc)+2;      /* Build the command at protocol level */      cmd = malloc(totlen+1); @@ -485,7 +485,7 @@ int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv,          return -1;      /* Calculate our total size */ -    totlen = 1+intlen(argc)+2; +    totlen = 1+countDigits(argc)+2;      for (j = 0; j < argc; j++) {          len = argvlen ? argvlen[j] : strlen(argv[j]);          totlen += bulklen(len); @@ -536,7 +536,7 @@ int redisFormatCommandArgv(char **target, int argc, const char **argv, const siz          return -1;      /* Calculate number of bytes needed for the command */ -    totlen = 1+intlen(argc)+2; +    totlen = 1+countDigits(argc)+2;      for (j = 0; j < argc; j++) {          len = argvlen ? argvlen[j] : strlen(argv[j]);          totlen += bulklen(len); @@ -34,6 +34,7 @@  #include "read.h"  #include <stdarg.h> /* for va_list */  #include <sys/time.h> /* for struct timeval */ +#include <stdint.h> /* uintXX_t, etc */  #include "sds.h" /* for sds */  #define HIREDIS_MAJOR 0 | 
