This is a helper function for the COPY command. * Duplicate a hash object, with the guarantee that the returned object * has the same encoding as the original one. * * The resulting object always has refcount set to 1 */
| 513 | * |
| 514 | * The resulting object always has refcount set to 1 */ |
| 515 | robj *hashTypeDup(robj *o) { |
| 516 | robj *hobj; |
| 517 | hashTypeIterator *hi; |
| 518 | |
| 519 | serverAssert(o->type == OBJ_HASH); |
| 520 | |
| 521 | if(o->encoding == OBJ_ENCODING_ZIPLIST){ |
| 522 | unsigned char *zl = (unsigned char*)ptrFromObj(o); |
| 523 | size_t sz = ziplistBlobLen(zl); |
| 524 | unsigned char *new_zl = (unsigned char*)zmalloc(sz); |
| 525 | memcpy(new_zl, zl, sz); |
| 526 | hobj = createObject(OBJ_HASH, new_zl); |
| 527 | hobj->encoding = OBJ_ENCODING_ZIPLIST; |
| 528 | } else if(o->encoding == OBJ_ENCODING_HT){ |
| 529 | dict *d = dictCreate(&hashDictType, NULL); |
| 530 | dictExpand(d, dictSize((const dict*)ptrFromObj(o))); |
| 531 | |
| 532 | hi = hashTypeInitIterator(o); |
| 533 | while (hashTypeNext(hi) != C_ERR) { |
| 534 | sds field, value; |
| 535 | sds newfield, newvalue; |
| 536 | /* Extract a field-value pair from an original hash object.*/ |
| 537 | field = hashTypeCurrentFromHashTable(hi, OBJ_HASH_KEY); |
| 538 | value = hashTypeCurrentFromHashTable(hi, OBJ_HASH_VALUE); |
| 539 | newfield = sdsdup(field); |
| 540 | newvalue = sdsdup(value); |
| 541 | |
| 542 | /* Add a field-value pair to a new hash object. */ |
| 543 | dictAdd(d,newfield,newvalue); |
| 544 | } |
| 545 | hashTypeReleaseIterator(hi); |
| 546 | |
| 547 | hobj = createObject(OBJ_HASH, d); |
| 548 | hobj->encoding = OBJ_ENCODING_HT; |
| 549 | } else { |
| 550 | serverPanic("Unknown hash encoding"); |
| 551 | } |
| 552 | return hobj; |
| 553 | } |
| 554 | |
| 555 | struct hash_ziplist_data { |
| 556 | long count; |
no test coverage detected