diff --git a/redis.c b/redis.c index f451f916..b63121a0 100644 --- a/redis.c +++ b/redis.c @@ -2933,7 +2933,7 @@ static int rdbSaveLen(FILE *fp, uint32_t len) { /* String objects in the form "2391" "-100" without any space and with a * range of values that can fit in an 8, 16 or 32 bit signed value can be * encoded as integers to save space */ -static int rdbTryIntegerEncoding(sds s, unsigned char *enc) { +static int rdbTryIntegerEncoding(char *s, size_t len, unsigned char *enc) { long long value; char *endptr, buf[32]; @@ -2944,7 +2944,7 @@ static int rdbTryIntegerEncoding(sds s, unsigned char *enc) { /* If the number converted back into a string is not identical * then it's not possible to encode the string as integer */ - if (strlen(buf) != sdslen(s) || memcmp(buf,s,sdslen(s))) return 0; + if (strlen(buf) != len || memcmp(buf,s,len)) return 0; /* Finally check if it fits in our ranges */ if (value >= -(1<<7) && value <= (1<<7)-1) { @@ -2968,16 +2968,16 @@ static int rdbTryIntegerEncoding(sds s, unsigned char *enc) { } } -static int rdbSaveLzfStringObject(FILE *fp, robj *obj) { - unsigned int comprlen, outlen; +static int rdbSaveLzfStringObject(FILE *fp, unsigned char *s, size_t len) { + size_t comprlen, outlen; unsigned char byte; void *out; /* We require at least four bytes compression for this to be worth it */ - outlen = sdslen(obj->ptr)-4; - if (outlen <= 0) return 0; + if (len <= 4) return 0; + outlen = len-4; if ((out = zmalloc(outlen+1)) == NULL) return 0; - comprlen = lzf_compress(obj->ptr, sdslen(obj->ptr), out, outlen); + comprlen = lzf_compress(s, len, out, outlen); if (comprlen == 0) { zfree(out); return 0; @@ -2986,7 +2986,7 @@ static int rdbSaveLzfStringObject(FILE *fp, robj *obj) { byte = (REDIS_RDB_ENCVAL<<6)|REDIS_RDB_ENC_LZF; if (fwrite(&byte,1,1,fp) == 0) goto writeerr; if (rdbSaveLen(fp,comprlen) == -1) goto writeerr; - if (rdbSaveLen(fp,sdslen(obj->ptr)) == -1) goto writeerr; + if (rdbSaveLen(fp,len) == -1) goto writeerr; if (fwrite(out,comprlen,1,fp) == 0) goto writeerr; zfree(out); return comprlen; @@ -2998,16 +2998,13 @@ writeerr: /* 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 */ -static int rdbSaveStringObjectRaw(FILE *fp, robj *obj) { - size_t len; +static int rdbSaveRawString(FILE *fp, unsigned char *s, size_t len) { int enclen; - len = sdslen(obj->ptr); - /* Try integer encoding */ if (len <= 11) { unsigned char buf[5]; - if ((enclen = rdbTryIntegerEncoding(obj->ptr,buf)) > 0) { + if ((enclen = rdbTryIntegerEncoding((char*)s,len,buf)) > 0) { if (fwrite(buf,enclen,1,fp) == 0) return -1; return 0; } @@ -3018,7 +3015,7 @@ static int rdbSaveStringObjectRaw(FILE *fp, robj *obj) { if (server.rdbcompression && len > 20) { int retval; - retval = rdbSaveLzfStringObject(fp,obj); + retval = rdbSaveLzfStringObject(fp,s,len); if (retval == -1) return -1; if (retval > 0) return 0; /* retval == 0 means data can't be compressed, save the old way */ @@ -3026,7 +3023,7 @@ static int rdbSaveStringObjectRaw(FILE *fp, robj *obj) { /* Store verbatim */ if (rdbSaveLen(fp,len) == -1) return -1; - if (len && fwrite(obj->ptr,len,1,fp) == 0) return -1; + if (len && fwrite(s,len,1,fp) == 0) return -1; return 0; } @@ -3041,10 +3038,10 @@ static int rdbSaveStringObject(FILE *fp, robj *obj) { * this in order to avoid bugs) */ if (obj->encoding != REDIS_ENCODING_RAW) { obj = getDecodedObject(obj); - retval = rdbSaveStringObjectRaw(fp,obj); + retval = rdbSaveRawString(fp,obj->ptr,sdslen(obj->ptr)); decrRefCount(obj); } else { - retval = rdbSaveStringObjectRaw(fp,obj); + retval = rdbSaveRawString(fp,obj->ptr,sdslen(obj->ptr)); } return retval; } @@ -3122,6 +3119,33 @@ static int rdbSaveObject(FILE *fp, robj *o) { if (rdbSaveDoubleValue(fp,*score) == -1) return -1; } dictReleaseIterator(di); + } 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; + + if (rdbSaveLen(fp,count) == -1) return -1; + while((p = zipmapNext(p,&key,&klen,&val,&vlen)) != NULL) { + if (rdbSaveRawString(fp,key,klen) == -1) return -1; + if (rdbSaveRawString(fp,val,vlen) == -1) return -1; + } + } else { + dictIterator *di = dictGetIterator(o->ptr); + dictEntry *de; + + if (rdbSaveLen(fp,dictSize((dict*)o->ptr)) == -1) return -1; + while((de = dictNext(di)) != NULL) { + robj *key = dictGetEntryKey(de); + robj *val = dictGetEntryVal(de); + + if (rdbSaveStringObject(fp,key) == -1) return -1; + if (rdbSaveStringObject(fp,val) == -1) return -1; + } + dictReleaseIterator(di); + } } else { redisAssert(0 != 0); } @@ -5619,9 +5643,11 @@ static void hsetCommand(redisClient *c) { } if (o->encoding == REDIS_ENCODING_ZIPMAP) { unsigned char *zm = o->ptr; + robj *valobj = getDecodedObject(c->argv[3]); zm = zipmapSet(zm,c->argv[2]->ptr,sdslen(c->argv[2]->ptr), - c->argv[3]->ptr,sdslen(c->argv[3]->ptr),&update); + valobj->ptr,sdslen(valobj->ptr),&update); + decrRefCount(valobj); o->ptr = zm; } else { if (dictAdd(o->ptr,c->argv[2],c->argv[3]) == DICT_OK) { diff --git a/staticsymbols.h b/staticsymbols.h index 446a5dc4..85f07d32 100644 --- a/staticsymbols.h +++ b/staticsymbols.h @@ -5,8 +5,10 @@ static struct redisFunctionSym symsTable[] = { {"addReply",(unsigned long)addReply}, {"addReplyBulkLen",(unsigned long)addReplyBulkLen}, {"addReplyDouble",(unsigned long)addReplyDouble}, +{"addReplyLong",(unsigned long)addReplyLong}, {"addReplySds",(unsigned long)addReplySds}, {"aofRemoveTempFile",(unsigned long)aofRemoveTempFile}, +{"appendCommand",(unsigned long)appendCommand}, {"appendServerSaveParams",(unsigned long)appendServerSaveParams}, {"authCommand",(unsigned long)authCommand}, {"beforeSleep",(unsigned long)beforeSleep}, @@ -23,6 +25,7 @@ static struct redisFunctionSym symsTable[] = { {"compareStringObjects",(unsigned long)compareStringObjects}, {"computeObjectSwappability",(unsigned long)computeObjectSwappability}, {"createClient",(unsigned long)createClient}, +{"createHashObject",(unsigned long)createHashObject}, {"createListObject",(unsigned long)createListObject}, {"createObject",(unsigned long)createObject}, {"createSetObject",(unsigned long)createSetObject}, @@ -45,6 +48,7 @@ static struct redisFunctionSym symsTable[] = { {"dictObjKeyCompare",(unsigned long)dictObjKeyCompare}, {"dictRedisObjectDestructor",(unsigned long)dictRedisObjectDestructor}, {"dictVanillaFree",(unsigned long)dictVanillaFree}, +{"discardCommand",(unsigned long)discardCommand}, {"dontWaitForSwappedKey",(unsigned long)dontWaitForSwappedKey}, {"dupClientReplyValue",(unsigned long)dupClientReplyValue}, {"dupStringObject",(unsigned long)dupStringObject}, @@ -75,6 +79,7 @@ static struct redisFunctionSym symsTable[] = { {"fwriteBulkDouble",(unsigned long)fwriteBulkDouble}, {"fwriteBulkLong",(unsigned long)fwriteBulkLong}, {"genRedisInfoString",(unsigned long)genRedisInfoString}, +{"genericZrangebyscoreCommand",(unsigned long)genericZrangebyscoreCommand}, {"getCommand",(unsigned long)getCommand}, {"getDecodedObject",(unsigned long)getDecodedObject}, {"getExpire",(unsigned long)getExpire}, @@ -84,6 +89,8 @@ static struct redisFunctionSym symsTable[] = { {"glueReplyBuffersIfNeeded",(unsigned long)glueReplyBuffersIfNeeded}, {"handleClientsBlockedOnSwappedKey",(unsigned long)handleClientsBlockedOnSwappedKey}, {"handleClientsWaitingListPush",(unsigned long)handleClientsWaitingListPush}, +{"hgetCommand",(unsigned long)hgetCommand}, +{"hsetCommand",(unsigned long)hsetCommand}, {"htNeedsResize",(unsigned long)htNeedsResize}, {"incrCommand",(unsigned long)incrCommand}, {"incrDecrCommand",(unsigned long)incrDecrCommand}, @@ -143,8 +150,8 @@ static struct redisFunctionSym symsTable[] = { {"rdbSaveLen",(unsigned long)rdbSaveLen}, {"rdbSaveLzfStringObject",(unsigned long)rdbSaveLzfStringObject}, {"rdbSaveObject",(unsigned long)rdbSaveObject}, +{"rdbSaveRawString",(unsigned long)rdbSaveRawString}, {"rdbSaveStringObject",(unsigned long)rdbSaveStringObject}, -{"rdbSaveStringObjectRaw",(unsigned long)rdbSaveStringObjectRaw}, {"rdbSaveTime",(unsigned long)rdbSaveTime}, {"rdbSaveType",(unsigned long)rdbSaveType}, {"rdbSavedObjectLen",(unsigned long)rdbSavedObjectLen}, @@ -196,6 +203,7 @@ static struct redisFunctionSym symsTable[] = { {"srandmemberCommand",(unsigned long)srandmemberCommand}, {"sremCommand",(unsigned long)sremCommand}, {"stringObjectLen",(unsigned long)stringObjectLen}, +{"substrCommand",(unsigned long)substrCommand}, {"sunionCommand",(unsigned long)sunionCommand}, {"sunionDiffGenericCommand",(unsigned long)sunionDiffGenericCommand}, {"sunionstoreCommand",(unsigned long)sunionstoreCommand}, @@ -240,10 +248,12 @@ static struct redisFunctionSym symsTable[] = { {"zaddCommand",(unsigned long)zaddCommand}, {"zaddGenericCommand",(unsigned long)zaddGenericCommand}, {"zcardCommand",(unsigned long)zcardCommand}, +{"zcountCommand",(unsigned long)zcountCommand}, {"zincrbyCommand",(unsigned long)zincrbyCommand}, {"zrangeCommand",(unsigned long)zrangeCommand}, {"zrangeGenericCommand",(unsigned long)zrangeGenericCommand}, {"zrangebyscoreCommand",(unsigned long)zrangebyscoreCommand}, +{"zrankCommand",(unsigned long)zrankCommand}, {"zremCommand",(unsigned long)zremCommand}, {"zremrangebyscoreCommand",(unsigned long)zremrangebyscoreCommand}, {"zrevrangeCommand",(unsigned long)zrevrangeCommand}, diff --git a/zipmap.c b/zipmap.c index 5729c18f..5f024dfa 100644 --- a/zipmap.c +++ b/zipmap.c @@ -363,6 +363,15 @@ int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen) { return zipmapLookupRaw(zm,key,klen,NULL,NULL,NULL) != NULL; } +/* Return the number of entries inside a zipmap */ +unsigned int zipmapLen(unsigned char *zm) { + unsigned char *p = zipmapRewind(zm); + unsigned int len = 0; + + while((p = zipmapNext(p,NULL,NULL,NULL,NULL)) != NULL) len++; + return len; +} + void zipmapRepr(unsigned char *p) { unsigned int l; diff --git a/zipmap.h b/zipmap.h index bf65740c..089472ed 100644 --- a/zipmap.h +++ b/zipmap.h @@ -42,5 +42,6 @@ unsigned char *zipmapRewind(unsigned char *zm); unsigned char *zipmapNext(unsigned char *zm, unsigned char **key, unsigned int *klen, unsigned char **value, unsigned int *vlen); 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); #endif