Skip to content

Instantly share code, notes, and snippets.

@pietern
Created June 11, 2010 18:33
Show Gist options
  • Save pietern/434862 to your computer and use it in GitHub Desktop.
Save pietern/434862 to your computer and use it in GitHub Desktop.
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