From: antirez Date: Mon, 15 Mar 2010 17:28:12 +0000 (+0100) Subject: zipmap to hash conversion in HSET X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/bae2c7ec6b2a65218b6c5b3d6f434325ef58edc6 zipmap to hash conversion in HSET --- diff --git a/Changelog b/Changelog index 8f1870ce..3154cf53 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,8 @@ +2010-03-14 max zipmap entries and max zipmap value parameters added into INFO output +2010-03-14 HDEL and some improvement in DEBUG OBJECT command +2010-03-14 Append only file support for hashes +2010-03-13 utility to check rdb files for unprocessable opcodes +2010-03-12 A minor fix and a few debug messages removed 2010-03-12 Applied the replication bug patch provided by Jeremy Zawodny, removing temp file collision after the slave got the dump.rdb file in the SYNC stage 2010-03-11 Fix for HGET against non Hash type, debug messages used to understand a bit better a corrupted rdb file 2010-03-09 fix: use zmalloc instead of malloc diff --git a/redis.c b/redis.c index 0cc71c68..b45b8618 100644 --- a/redis.c +++ b/redis.c @@ -5932,6 +5932,20 @@ static void hsetCommand(redisClient *c) { return; } } + /* We want to convert the zipmap into an hash table right now if the + * entry to be added is too big. Note that we check if the object + * is integer encoded before to try fetching the length in the test below. + * This is because integers are small, but currently stringObjectLen() + * performs a slow conversion: not worth it. */ + if (o->encoding == REDIS_ENCODING_ZIPMAP && + ((c->argv[2]->encoding == REDIS_ENCODING_RAW && + sdslen(c->argv[2]->ptr) > server.hash_max_zipmap_value) || + (c->argv[3]->encoding == REDIS_ENCODING_RAW && + sdslen(c->argv[3]->ptr) > server.hash_max_zipmap_value))) + { + convertToRealHash(o); + } + if (o->encoding == REDIS_ENCODING_ZIPMAP) { unsigned char *zm = o->ptr; robj *valobj = getDecodedObject(c->argv[3]); @@ -5940,7 +5954,16 @@ static void hsetCommand(redisClient *c) { valobj->ptr,sdslen(valobj->ptr),&update); decrRefCount(valobj); o->ptr = zm; + + /* And here there is the second check for hash conversion... + * we want to do it only if the operation was not just an update as + * zipmapLen() is O(N). */ + if (!update && zipmapLen(zm) > server.hash_max_zipmap_entries) + convertToRealHash(o); } else { + tryObjectEncoding(c->argv[2]); + /* note that c->argv[3] is already encoded, as the latest arg + * of a bulk command is always integer encoded if possible. */ if (dictAdd(o->ptr,c->argv[2],c->argv[3]) == DICT_OK) { incrRefCount(c->argv[2]); } else {