]> git.saurik.com Git - redis.git/commitdiff
zipmap to hash conversion in HSET
authorantirez <antirez@gmail.com>
Mon, 15 Mar 2010 17:28:12 +0000 (18:28 +0100)
committerantirez <antirez@gmail.com>
Mon, 15 Mar 2010 17:28:12 +0000 (18:28 +0100)
Changelog
redis.c

index 8f1870ce998ce9fb54f971e0d5eb94f39a1aa01e..3154cf53a79a36dfa28971290646ef5ecac3afb2 100644 (file)
--- 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 0cc71c68b97c151e778dddff8a4e80f1f70c8ece..b45b86184a51b46afed6a4b19d6803ceff7359c7 100644 (file)
--- 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 {