关键词搜索

源码搜索 ×
×

漫话Redis源码之十一

发布2021-11-28浏览558次

详情内容

仔细看了一下,这里的hashTypeSet函数的实现挺巧妙,该函数被频繁调用多次,挺重要:

  1. #define HASH_SET_TAKE_FIELD (1<<0)
  2. #define HASH_SET_TAKE_VALUE (1<<1)
  3. #define HASH_SET_COPY 0
  4. int hashTypeSet(robj *o, sds field, sds value, int flags) {
  5. int update = 0;
  6. if (o->encoding == OBJ_ENCODING_ZIPLIST) {
  7. unsigned char *zl, *fptr, *vptr;
  8. zl = o->ptr;
  9. fptr = ziplistIndex(zl, ZIPLIST_HEAD);
  10. if (fptr != NULL) {
  11. fptr = ziplistFind(zl, fptr, (unsigned char*)field, sdslen(field), 1);
  12. if (fptr != NULL) {
  13. /* Grab pointer to the value (fptr points to the field) */
  14. vptr = ziplistNext(zl, fptr);
  15. serverAssert(vptr != NULL);
  16. update = 1;
  17. /* Replace value */
  18. zl = ziplistReplace(zl, vptr, (unsigned char*)value,
  19. sdslen(value));
  20. }
  21. }
  22. if (!update) {
  23. /* Push new field/value pair onto the tail of the ziplist */
  24. zl = ziplistPush(zl, (unsigned char*)field, sdslen(field),
  25. ZIPLIST_TAIL);
  26. zl = ziplistPush(zl, (unsigned char*)value, sdslen(value),
  27. ZIPLIST_TAIL);
  28. }
  29. o->ptr = zl;
  30. /* Check if the ziplist needs to be converted to a hash table */
  31. if (hashTypeLength(o) > server.hash_max_ziplist_entries)
  32. hashTypeConvert(o, OBJ_ENCODING_HT);
  33. } else if (o->encoding == OBJ_ENCODING_HT) {
  34. dictEntry *de = dictFind(o->ptr,field);
  35. if (de) {
  36. sdsfree(dictGetVal(de));
  37. if (flags & HASH_SET_TAKE_VALUE) {
  38. dictGetVal(de) = value;
  39. value = NULL;
  40. } else {
  41. dictGetVal(de) = sdsdup(value);
  42. }
  43. update = 1;
  44. } else {
  45. sds f,v;
  46. if (flags & HASH_SET_TAKE_FIELD) {
  47. f = field;
  48. field = NULL;
  49. } else {
  50. f = sdsdup(field);
  51. }
  52. if (flags & HASH_SET_TAKE_VALUE) {
  53. v = value;
  54. value = NULL;
  55. } else {
  56. v = sdsdup(value);
  57. }
  58. dictAdd(o->ptr,f,v);
  59. }
  60. } else {
  61. serverPanic("Unknown hash encoding");
  62. }
  63. /* Free SDS strings we did not referenced elsewhere if the flags
  64. * want this function to be responsible. */
  65. if (flags & HASH_SET_TAKE_FIELD && field) sdsfree(field);
  66. if (flags & HASH_SET_TAKE_VALUE && value) sdsfree(value);
  67. return update;
  68. }
  69. /* Delete an element from a hash.
  70. * Return 1 on deleted and 0 on not found. */
  71. int hashTypeDelete(robj *o, sds field) {
  72. int deleted = 0;
  73. if (o->encoding == OBJ_ENCODING_ZIPLIST) {
  74. unsigned char *zl, *fptr;
  75. zl = o->ptr;
  76. fptr = ziplistIndex(zl, ZIPLIST_HEAD);
  77. if (fptr != NULL) {
  78. fptr = ziplistFind(zl, fptr, (unsigned char*)field, sdslen(field), 1);
  79. if (fptr != NULL) {
  80. zl = ziplistDelete(zl,&fptr); /* Delete the key. */
  81. zl = ziplistDelete(zl,&fptr); /* Delete the value. */
  82. o->ptr = zl;
  83. deleted = 1;
  84. }
  85. }
  86. } else if (o->encoding == OBJ_ENCODING_HT) {
  87. if (dictDelete((dict*)o->ptr, field) == C_OK) {
  88. deleted = 1;
  89. /* Always check if the dictionary needs a resize after a delete. */
  90. if (htNeedsResize(o->ptr)) dictResize(o->ptr);
  91. }
  92. } else {
  93. serverPanic("Unknown hash encoding");
  94. }
  95. return deleted;
  96. }

相关技术文章

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

提示信息

×

选择支付方式

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