{
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);
}
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:
--- /dev/null
+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]
+ }
+}