关键词搜索

源码搜索 ×
×

漫话Redis源码之九

发布2021-11-21浏览621次

详情内容

在redis源码中,hash的思想无处不在,这不,又见到了:

  1. /* This is a helper function for the COPY command.
  2. * Duplicate a hash object, with the guarantee that the returned object
  3. * has the same encoding as the original one.
  4. *
  5. * The resulting object always has refcount set to 1 */
  6. robj *hashTypeDup(robj *o) {
  7. robj *hobj;
  8. hashTypeIterator *hi;
  9. serverAssert(o->type == OBJ_HASH);
  10. if(o->encoding == OBJ_ENCODING_ZIPLIST){
  11. unsigned char *zl = o->ptr;
  12. size_t sz = ziplistBlobLen(zl);
  13. unsigned char *new_zl = zmalloc(sz);
  14. memcpy(new_zl, zl, sz);
  15. hobj = createObject(OBJ_HASH, new_zl);
  16. hobj->encoding = OBJ_ENCODING_ZIPLIST;
  17. } else if(o->encoding == OBJ_ENCODING_HT){
  18. dict *d = dictCreate(&hashDictType, NULL);
  19. dictExpand(d, dictSize((const dict*)o->ptr));
  20. hi = hashTypeInitIterator(o);
  21. while (hashTypeNext(hi) != C_ERR) {
  22. sds field, value;
  23. sds newfield, newvalue;
  24. /* Extract a field-value pair from an original hash object.*/
  25. field = hashTypeCurrentFromHashTable(hi, OBJ_HASH_KEY);
  26. value = hashTypeCurrentFromHashTable(hi, OBJ_HASH_VALUE);
  27. newfield = sdsdup(field);
  28. newvalue = sdsdup(value);
  29. /* Add a field-value pair to a new hash object. */
  30. dictAdd(d,newfield,newvalue);
  31. }
  32. hashTypeReleaseIterator(hi);
  33. hobj = createObject(OBJ_HASH, d);
  34. hobj->encoding = OBJ_ENCODING_HT;
  35. } else {
  36. serverPanic("Unknown hash encoding");
  37. }
  38. return hobj;
  39. }
  40. /* callback for to check the ziplist doesn't have duplicate recoreds */
  41. static int _hashZiplistEntryValidation(unsigned char *p, void *userdata) {
  42. struct {
  43. long count;
  44. dict *fields;
  45. } *data = userdata;
  46. /* Odd records are field names, add to dict and check that's not a dup */
  47. if (((data->count) & 1) == 0) {
  48. unsigned char *str;
  49. unsigned int slen;
  50. long long vll;
  51. if (!ziplistGet(p, &str, &slen, &vll))
  52. return 0;
  53. sds field = str? sdsnewlen(str, slen): sdsfromlonglong(vll);;
  54. if (dictAdd(data->fields, field, NULL) != DICT_OK) {
  55. /* Duplicate, return an error */
  56. sdsfree(field);
  57. return 0;
  58. }
  59. }
  60. (data->count)++;
  61. return 1;
  62. }

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载