Created
June 11, 2010 18:33
-
-
Save pietern/434862 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/redis.c b/redis.c | |
index 3e7a17d..a2811e8 100644 | |
--- a/redis.c | |
+++ b/redis.c | |
@@ -35,6 +35,7 @@ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
+#include <stdint.h> | |
#include <time.h> | |
#include <unistd.h> | |
#include <signal.h> | |
@@ -252,6 +253,7 @@ static void _redisPanic(char *msg, char *file, int line); | |
/*================================= Data types ============================== */ | |
/* A redis object, that is a type able to hold a string / list / set */ | |
+#define REDIS_OBJECT_INT64(_o) (*(int64_t*)(&(_o)->ptr)) | |
/* The actual Redis Object */ | |
typedef struct redisObject { | |
@@ -260,6 +262,10 @@ typedef struct redisObject { | |
unsigned encoding:4; | |
unsigned lru:22; /* lru time (relative to server.lruclock) */ | |
int refcount; | |
+ /* To be able to store a 64-bit integer on the place of this pointer, | |
+ * we check in createObject if sizeof(void*) == sizeof(int64_t). | |
+ * When this is not the case (on 32-bit systems), extra bytes are | |
+ * allocated to be able to store a 64-bit integer anyway. */ | |
void *ptr; | |
/* VM fields, this are only allocated if VM is active, otherwise the | |
* object allocation function will just allocate | |
@@ -3004,7 +3010,11 @@ static robj *createObject(int type, void *ptr) { | |
} else { | |
if (server.vm_enabled) | |
pthread_mutex_unlock(&server.obj_freelist_mutex); | |
- o = zmalloc(sizeof(*o)); | |
+ if (sizeof(int64_t) > sizeof(void*)) { | |
+ o = zmalloc(sizeof(*o)+sizeof(int64_t)-sizeof(void*)); | |
+ } else { | |
+ o = zmalloc(sizeof(*o)); | |
+ } | |
} | |
o->type = type; | |
o->encoding = REDIS_ENCODING_RAW; | |
@@ -3031,13 +3041,9 @@ static robj *createStringObjectFromLongLong(long long value) { | |
incrRefCount(shared.integers[value]); | |
o = shared.integers[value]; | |
} else { | |
- if (value >= LONG_MIN && value <= LONG_MAX) { | |
- o = createObject(REDIS_STRING, NULL); | |
- o->encoding = REDIS_ENCODING_INT; | |
- o->ptr = (void*)((long)value); | |
- } else { | |
- o = createObject(REDIS_STRING,sdsfromlonglong(value)); | |
- } | |
+ o = createObject(REDIS_STRING, NULL); | |
+ o->encoding = REDIS_ENCODING_INT; | |
+ REDIS_OBJECT_INT64(o) = value; | |
} | |
return o; | |
} | |
@@ -3252,7 +3258,7 @@ static robj *getDecodedObject(robj *o) { | |
if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_INT) { | |
char buf[32]; | |
- ll2string(buf,32,(long)o->ptr); | |
+ ll2string(buf,32,REDIS_OBJECT_INT64(o)); | |
dec = createStringObject(buf,strlen(buf)); | |
return dec; | |
} else { | |
@@ -3363,7 +3369,7 @@ static int getLongLongFromObject(robj *o, long long *target) { | |
value = strtoll(o->ptr, &eptr, 10); | |
if (eptr[0] != '\0') return REDIS_ERR; | |
} else if (o->encoding == REDIS_ENCODING_INT) { | |
- value = (long)o->ptr; | |
+ value = REDIS_OBJECT_INT64(o); | |
} else { | |
redisPanic("Unknown string encoding"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment