Permalink
Browse files

save zipmap encoded hashes as blobs. Work in progress.

  • Loading branch information...
1 parent 1c53928 commit 3dffb8e21ed9066caebb6a95d1ac0a58157887c7 @antirez committed Feb 28, 2011
Showing with 29 additions and 18 deletions.
  1. +18 −14 src/rdb.c
  2. +2 −0 src/redis.h
  3. +7 −3 src/zipmap.c
  4. +2 −1 src/zipmap.h
View
@@ -139,7 +139,7 @@ int rdbSaveLzfStringObject(FILE *fp, unsigned char *s, size_t len) {
}
/* Save a string objet as [len][data] on disk. If the object is a string
- * representation of an integer value we try to safe it in a special form */
+ * representation of an integer value we try to save it in a special form */
int rdbSaveRawString(FILE *fp, unsigned char *s, size_t len) {
int enclen;
int n, nwritten = 0;
@@ -385,20 +385,10 @@ int rdbSaveObject(FILE *fp, robj *o) {
} else if (o->type == REDIS_HASH) {
/* Save a hash value */
if (o->encoding == REDIS_ENCODING_ZIPMAP) {
- unsigned char *p = zipmapRewind(o->ptr);
- unsigned int count = zipmapLen(o->ptr);
- unsigned char *key, *val;
- unsigned int klen, vlen;
+ size_t l = zipmapBlobLen((unsigned char*)o->ptr);
- if ((n = rdbSaveLen(fp,count)) == -1) return -1;
+ if ((n = rdbSaveRawString(fp,o->ptr,l)) == -1) return -1;
nwritten += n;
-
- while((p = zipmapNext(p,&key,&klen,&val,&vlen)) != NULL) {
- if ((n = rdbSaveRawString(fp,key,klen)) == -1) return -1;
- nwritten += n;
- if ((n = rdbSaveRawString(fp,val,vlen)) == -1) return -1;
- nwritten += n;
- }
} else {
dictIterator *di = dictGetIterator(o->ptr);
dictEntry *de;
@@ -495,8 +485,12 @@ int rdbSave(char *filename) {
* handling if the value is swapped out. */
if (!server.vm_enabled || o->storage == REDIS_VM_MEMORY ||
o->storage == REDIS_VM_SWAPPING) {
+ int otype = o->type;
+
+ if (otype == REDIS_HASH && o->encoding == REDIS_ENCODING_ZIPMAP)
+ otype = REDIS_HASH_ZIPMAP;
/* Save type, key, value */
- if (rdbSaveType(fp,o->type) == -1) goto werr;
+ if (rdbSaveType(fp,otype) == -1) goto werr;
if (rdbSaveStringObject(fp,&key) == -1) goto werr;
if (rdbSaveObject(fp,o) == -1) goto werr;
} else {
@@ -890,6 +884,16 @@ robj *rdbLoadObject(int type, FILE *fp) {
dictAdd((dict*)o->ptr,key,val);
}
}
+ } else if (type == REDIS_HASH_ZIPMAP) {
+ robj *aux = rdbLoadStringObject(fp);
+
+ if (aux == NULL) return NULL;
+ o = createHashObject();
+ o->encoding = REDIS_ENCODING_ZIPMAP;
+ o->ptr = zmalloc(sdslen(aux->ptr));
+ memcpy(o->ptr,aux->ptr,sdslen(aux->ptr));
+ decrRefCount(aux);
+ /* FIXME: conver the object if needed */
} else {
redisPanic("Unknown object type");
}
View
@@ -70,6 +70,8 @@
#define REDIS_ZSET 3
#define REDIS_HASH 4
#define REDIS_VMPOINTER 8
+/* Object types only used for persistence in .rdb files */
+#define REDIS_HASH_ZIPMAP 9
/* Objects encoding. Some kind of objects like Strings and Hashes can be
* internally represented in multiple ways. The 'encoding' field of the object
View
@@ -80,6 +80,7 @@
#include <string.h>
#include <assert.h>
#include "zmalloc.h"
+#include "endian.h"
#define ZIPMAP_BIGLEN 254
#define ZIPMAP_END 255
@@ -108,6 +109,7 @@ static unsigned int zipmapDecodeLength(unsigned char *p) {
if (len < ZIPMAP_BIGLEN) return len;
memcpy(&len,p+1,sizeof(unsigned int));
+ memrev32ifbe(&len);
return len;
}
@@ -123,6 +125,7 @@ static unsigned int zipmapEncodeLength(unsigned char *p, unsigned int len) {
} else {
p[0] = ZIPMAP_BIGLEN;
memcpy(p+1,&len,sizeof(len));
+ memrev32ifbe(p+1);
return 1+sizeof(len);
}
}
@@ -360,15 +363,16 @@ unsigned int zipmapLen(unsigned char *zm) {
return len;
}
-/* Return zipmap size in bytes. */
-size_t zipmapSize(unsigned char *zm) {
+/* Return the raw size in bytes of a zipmap, so that we can serialize
+ * the zipmap on disk (or everywhere is needed) just writing the returned
+ * amount of bytes of the C array starting at the zipmap pointer. */
+size_t zipmapBlobLen(unsigned char *zm) {
unsigned int totlen;
zipmapLookupRaw(zm,NULL,0,&totlen);
return totlen;
}
#ifdef ZIPMAP_TEST_MAIN
-
void zipmapRepr(unsigned char *p) {
unsigned int l;
View
@@ -43,6 +43,7 @@ unsigned char *zipmapNext(unsigned char *zm, unsigned char **key, unsigned int *
int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char **value, unsigned int *vlen);
int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen);
unsigned int zipmapLen(unsigned char *zm);
-size_t zipmapSize(unsigned char *zm);
+size_t zipmapBlobLen(unsigned char *zm);
+void zipmapRepr(unsigned char *p);
#endif

0 comments on commit 3dffb8e

Please sign in to comment.