]> git.saurik.com Git - redis.git/commitdiff
Test that zipmap from RDB is correctly converted
authorPieter Noordhuis <pcnoordhuis@gmail.com>
Wed, 25 Jan 2012 21:26:25 +0000 (13:26 -0800)
committerPieter Noordhuis <pcnoordhuis@gmail.com>
Wed, 25 Jan 2012 21:28:11 +0000 (13:28 -0800)
src/rdb.c
tests/assets/hash-zipmap.rdb [new file with mode: 0644]
tests/integration/convert-zipmap-hash-on-load.tcl [new file with mode: 0644]

index c74ec41c53fcce04e2ceaa40b5423ae43964b6e0..15555fe48c7819d9bf770b4ad3f005eec4c8b4f2 100644 (file)
--- a/src/rdb.c
+++ b/src/rdb.c
@@ -915,12 +915,13 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
                 {
                     unsigned char *zl = ziplistNew();
                     unsigned char *zi = zipmapRewind(o->ptr);
+                    unsigned char *fstr, *vstr;
+                    unsigned int flen, vlen;
+                    unsigned int maxlen = 0;
 
-                    while (zi != NULL) {
-                        unsigned char *fstr, *vstr;
-                        unsigned int flen, vlen;
-
-                        zi = zipmapNext(zi, &fstr, &flen, &vstr, &vlen);
+                    while ((zi = zipmapNext(zi, &fstr, &flen, &vstr, &vlen)) != NULL) {
+                        if (flen > maxlen) maxlen = flen;
+                        if (vlen > maxlen) maxlen = vlen;
                         zl = ziplistPush(zl, fstr, flen, ZIPLIST_TAIL);
                         zl = ziplistPush(zl, vstr, vlen, ZIPLIST_TAIL);
                     }
@@ -930,8 +931,11 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
                     o->type = REDIS_HASH;
                     o->encoding = REDIS_ENCODING_ZIPLIST;
 
-                    if (hashTypeLength(o) > server.hash_max_ziplist_entries)
+                    if (hashTypeLength(o) > server.hash_max_ziplist_entries ||
+                        maxlen > server.hash_max_ziplist_value)
+                    {
                         hashTypeConvert(o, REDIS_ENCODING_HT);
+                    }
                 }
                 break;
             case REDIS_RDB_TYPE_LIST_ZIPLIST:
diff --git a/tests/assets/hash-zipmap.rdb b/tests/assets/hash-zipmap.rdb
new file mode 100644 (file)
index 0000000..27a42ed
Binary files /dev/null and b/tests/assets/hash-zipmap.rdb differ
diff --git a/tests/integration/convert-zipmap-hash-on-load.tcl b/tests/integration/convert-zipmap-hash-on-load.tcl
new file mode 100644 (file)
index 0000000..75a65d3
--- /dev/null
@@ -0,0 +1,34 @@
+set server_path [tmpdir "server.convert-zipmap-hash-on-load"]
+
+# Copy RDB with zipmap encoded hash to server path
+exec cp tests/assets/hash-zipmap.rdb $server_path
+
+start_server [list overrides [list "dir" $server_path "dbfilename" "hash-zipmap.rdb"]] {
+  test "RDB load zipmap hash: converts to ziplist" {
+    r select 0
+
+    assert_match "*ziplist*" [r debug object hash]
+    assert_equal 2 [r hlen hash]
+    assert_match {v1 v2} [r hmget hash f1 f2]
+  }
+}
+
+start_server [list overrides [list "dir" $server_path "dbfilename" "hash-zipmap.rdb" "hash-max-ziplist-entries" 1]] {
+  test "RDB load zipmap hash: converts to hash table when hash-max-ziplist-entries is exceeded" {
+    r select 0
+
+    assert_match "*hashtable*" [r debug object hash]
+    assert_equal 2 [r hlen hash]
+    assert_match {v1 v2} [r hmget hash f1 f2]
+  }
+}
+
+start_server [list overrides [list "dir" $server_path "dbfilename" "hash-zipmap.rdb" "hash-max-ziplist-value" 1]] {
+  test "RDB load zipmap hash: converts to hash table when hash-max-ziplist-value is exceeded" {
+    r select 0
+
+    assert_match "*hashtable*" [r debug object hash]
+    assert_equal 2 [r hlen hash]
+    assert_match {v1 v2} [r hmget hash f1 f2]
+  }
+}