+/* Emit the commands needed to rebuild a hash object.
+ * The function returns 0 on error, 1 on success. */
+int rewriteHashObject(rio *r, robj *key, robj *o) {
+ long long count = 0, items = hashTypeLength(o);
+
+ if (o->encoding == REDIS_ENCODING_ZIPMAP) {
+ unsigned char *p = zipmapRewind(o->ptr);
+ unsigned char *field, *val;
+ unsigned int flen, vlen;
+
+ while((p = zipmapNext(p,&field,&flen,&val,&vlen)) != NULL) {
+ if (count == 0) {
+ int cmd_items = (items > REDIS_AOFREWRITE_ITEMS_PER_CMD) ?
+ REDIS_AOFREWRITE_ITEMS_PER_CMD : items;
+
+ if (rioWriteBulkCount(r,'*',2+cmd_items*2) == 0) return 0;
+ if (rioWriteBulkString(r,"HMSET",5) == 0) return 0;
+ if (rioWriteBulkObject(r,key) == 0) return 0;
+ }
+ if (rioWriteBulkString(r,(char*)field,flen) == 0) return 0;
+ if (rioWriteBulkString(r,(char*)val,vlen) == 0) return 0;
+ if (++count == REDIS_AOFREWRITE_ITEMS_PER_CMD) count = 0;
+ items--;
+ }
+ } else {
+ dictIterator *di = dictGetIterator(o->ptr);
+ dictEntry *de;
+
+ while((de = dictNext(di)) != NULL) {
+ robj *field = dictGetKey(de);
+ robj *val = dictGetVal(de);
+
+ if (count == 0) {
+ int cmd_items = (items > REDIS_AOFREWRITE_ITEMS_PER_CMD) ?
+ REDIS_AOFREWRITE_ITEMS_PER_CMD : items;
+
+ if (rioWriteBulkCount(r,'*',2+cmd_items*2) == 0) return 0;
+ if (rioWriteBulkString(r,"HMSET",5) == 0) return 0;
+ if (rioWriteBulkObject(r,key) == 0) return 0;
+ }
+ if (rioWriteBulkObject(r,field) == 0) return 0;
+ if (rioWriteBulkObject(r,val) == 0) return 0;
+ if (++count == REDIS_AOFREWRITE_ITEMS_PER_CMD) count = 0;
+ items--;
+ }
+ dictReleaseIterator(di);
+ }
+ return 1;
+}
+