]> git.saurik.com Git - redis.git/commitdiff
test for intset integer encodability test and some small refactoring
authorantirez <antirez@gmail.com>
Thu, 26 Aug 2010 16:47:03 +0000 (18:47 +0200)
committerantirez <antirez@gmail.com>
Thu, 26 Aug 2010 16:47:03 +0000 (18:47 +0200)
src/redis.h
src/t_set.c
src/util.c

index 6156a6ca74187dbb1ee9460f4cf941594e0c48f9..a4fdcb197de8ff786bedbec8b4530137503cf468 100644 (file)
@@ -769,6 +769,8 @@ int stringmatch(const char *pattern, const char *string, int nocase);
 long long memtoll(const char *p, int *err);
 int ll2string(char *s, size_t len, long long value);
 int isStringRepresentableAsLong(sds s, long *longval);
+int isStringRepresentableAsLongLong(sds s, long long *longval);
+int isObjectRepresentableAsLongLong(robj *o, long long *llongval);
 
 /* Configuration */
 void loadServerConfig(char *filename);
index 97fc5bf4534f9a5ade43ad6c33ad92a9c107ebb3..68e132278f96c938e605490e6ed55aff46177ef8 100644 (file)
@@ -8,7 +8,7 @@
  * an integer-encodable value, an intset will be returned. Otherwise a regular
  * hash table. */
 robj *setTypeCreate(robj *value) {
-    if (getLongLongFromObject(value,NULL) == REDIS_OK)
+    if (isObjectRepresentableAsLongLong(value,NULL) == REDIS_OK)
         return createIntsetObject();
     return createSetObject();
 }
@@ -21,7 +21,7 @@ int setTypeAdd(robj *subject, robj *value) {
             return 1;
         }
     } else if (subject->encoding == REDIS_ENCODING_INTSET) {
-        if (getLongLongFromObject(value,&llval) == REDIS_OK) {
+        if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {
             uint8_t success = 0;
             subject->ptr = intsetAdd(subject->ptr,llval,&success);
             if (success) {
@@ -55,7 +55,7 @@ int setTypeRemove(robj *subject, robj *value) {
             return 1;
         }
     } else if (subject->encoding == REDIS_ENCODING_INTSET) {
-        if (getLongLongFromObject(value,&llval) == REDIS_OK) {
+        if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {
             uint8_t success;
             subject->ptr = intsetRemove(subject->ptr,llval,&success);
             if (success) return 1;
@@ -71,7 +71,7 @@ int setTypeIsMember(robj *subject, robj *value) {
     if (subject->encoding == REDIS_ENCODING_HT) {
         return dictFind((dict*)subject->ptr,value) != NULL;
     } else if (subject->encoding == REDIS_ENCODING_INTSET) {
-        if (getLongLongFromObject(value,&llval) == REDIS_OK) {
+        if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {
             return intsetFind((intset*)subject->ptr,llval);
         }
     } else {
index cc2794f6ab675ae4b88c6f9ae1d2782e802dc603..e304ff839204a5a445542ba5f462db9186803404 100644 (file)
@@ -200,24 +200,44 @@ int ll2string(char *s, size_t len, long long value) {
     return l;
 }
 
-/* Check if the nul-terminated string 's' can be represented by a long
+/* Check if the sds string 's' can be represented by a long long
  * (that is, is a number that fits into long without any other space or
- * character before or after the digits).
+ * character before or after the digits, so that converting this number
+ * back to a string will result in the same bytes as the original string).
  *
- * If so, the function returns REDIS_OK and *longval is set to the value
+ * If so, the function returns REDIS_OK and *llongval is set to the value
  * of the number. Otherwise REDIS_ERR is returned */
-int isStringRepresentableAsLong(sds s, long *longval) {
+int isStringRepresentableAsLongLong(sds s, long long *llongval) {
     char buf[32], *endptr;
-    long value;
+    long long value;
     int slen;
 
-    value = strtol(s, &endptr, 10);
+    value = strtoll(s, &endptr, 10);
     if (endptr[0] != '\0') return REDIS_ERR;
     slen = ll2string(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 */
     if (sdslen(s) != (unsigned)slen || memcmp(buf,s,slen)) return REDIS_ERR;
-    if (longval) *longval = value;
+    if (llongval) *llongval = value;
+    return REDIS_OK;
+}
+
+int isStringRepresentableAsLong(sds s, long *longval) {
+    long long ll;
+
+    if (isStringRepresentableAsLongLong(s,&ll) == REDIS_ERR) return REDIS_ERR;
+    if (ll < LONG_MIN || ll > LONG_MAX) return REDIS_ERR;
+    *longval = (long)ll;
     return REDIS_OK;
 }
+
+int isObjectRepresentableAsLongLong(robj *o, long long *llongval) {
+    redisAssert(o->type == REDIS_STRING);
+    if (o->encoding == REDIS_ENCODING_INT) {
+        if (llongval) *llongval = (long) o->ptr;
+        return REDIS_OK;
+    } else {
+        return isStringRepresentableAsLongLong(o->ptr,llongval);
+    }
+}