Chinaunix首页 | 论坛 | 博客
  • 博客访问: 260267
  • 博文数量: 84
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 927
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-06 23:00
个人简介

growing

文章分类

全部博文(84)

文章存档

2017年(6)

2016年(61)

2015年(17)

我的朋友

分类: 数据库开发技术

2016-06-05 11:53:33

源码地址:
本文对链接中源码进行剖析。

先来看看对元素的定义:
  1. struct node_s/* 定义实体结点*/
  2. {
  3.     char iden[64]; /* 每个缓存结点的名字或者信息 */
  4.     u_int replicas; /*实体结点的虚拟结点数量*/
  5.     u_int flag;/* 结点标识*/
  6. };
  1. /* 定义虚拟结点 */
  2. struct virtual_node_s
  3. {
  4.     long hash;/* 哈希值 */
  5.     struct node_s *node; /* 指向实体结点的指针 */
  6. };

  7. /* 一致性哈西 */
  8. struct conhash_s
  9. {
  10.     util_rbtree_t vnode_tree; /* 这里是利用红黑树来存储数据的 */
  11.     u_int ivnodes; /* 虚拟结点的数量 */
  12.     long (*cb_hashfunc)(const char *);
  13. };
函数的声明:
  1. /* initialize conhash library
  2.      * @pfhash : hash function, NULL to use default MD5 method
  3.      * return a conhash_s instance
  4.      */
  5.     CONHASH_API struct conhash_s* conhash_init(conhash_cb_hashfunc pfhash);//初始化每个缓存节点

  6.     /* finalize lib */
  7.     CONHASH_API void conhash_fini(struct conhash_s *conhash);//释放最后的缓存结点

  8.     /* set node */
  9.     CONHASH_API void conhash_set_node(struct node_s *node, const char *iden, u_int replica);//设置虚拟结点所指向的实体结点
  10.     /*
  11.      * add a new node
  12.      * @node: the node to add
  13.      */
  14.     CONHASH_API int conhash_add_node(struct conhash_s *conhash, struct node_s *node);//增加实体节点

  15.     /* remove a node */
  16.     CONHASH_API int conhash_del_node(struct conhash_s *conhash, struct node_s *node);//删除实体结点

  17.     /*
  18.      * update a node's virtual nodes
  19.      * @replica: new replica of server
  20.      * return 0 success, -1 failed
  21.      */
  22.     CONHASH_API int conhash_update_node(struct conhash_s *conhash, struct node_s *node, u_int replica);//更新缓存结点

  23.     /*
  24.      * lookup a server which object belongs to
  25.      * @object: the input string which indicates an object
  26.      * return the server_s structure, do not modify the value, or it will cause a disaster
  27.      */
  28.     CONHASH_API const struct node_s* conhash_lookup(const struct conhash_s *conhash, const char *object);//寻找目标对应的实体结点

  29.     /* some utility functions export*/
  30.     CONHASH_API void conhash_md5_digest(const u_char *instr, u_char digest[16]);//一些使用功能的接口
  31.     /* get virtual node number in the hash */
  32.     CONHASH_API u_int conhash_get_vnodes_num(const struct conhash_s *conhash);//计算每个缓存结点的哈希值
  33.     /*
  34.     * get virtual nodes in ascending oder
  35.     * @values, pointer to an array, stores all the nodes's hash value
  36.     * @size, how many nodes to get, can't be less than the array size
  37.     */
  38.     CONHASH_API void conhash_get_vnodes(const struct conhash_s *conhash, long *values, int size);//获得缓存结点的上升值
下面来看看函数的实现:

  1. struct conhash_s* conhash_init(conhash_cb_hashfunc pfhash)
  2. {
  3.     /* 定义一个缓存机器并初始化为0 */
  4.     struct conhash_s *conhash = (struct conhash_s*)calloc(1, sizeof(struct conhash_s));
  5.     if(conhash == NULL)//没calloc出来直接返回
  6.     {
  7.         return NULL;
  8.     }
  9.     do
  10.     {
  11.         /* 设置回调函数 */
  12.         if(pfhash != NULL)
  13.         {
  14.             conhash->cb_hashfunc = pfhash;//传入的数据保存下来
  15.         }
  16.         else
  17.         {
  18.             conhash->cb_hashfunc = __conhash_hash_def;
  19.         }
  20.         util_rbtree_init(&conhash->vnode_tree);//初始化用来存储数据的红黑树
  21.         return conhash;

  22.     }while(0);

  23.     free(conhash);
  24.     return NULL;
  25. }

  26. void conhash_fini(struct conhash_s *conhash)
  27. {
  28.     if(conhash != NULL)
  29.     {
  30.         /* 释放红黑树 */
  31.         while(!util_rbtree_isempty(&(conhash->vnode_tree)))
  32.         {
  33.             util_rbtree_node_t *rbnode = conhash->vnode_tree.root;
  34.             util_rbtree_delete(&(conhash->vnode_tree), rbnode);
  35.             __conhash_del_rbnode(rbnode);
  36.         }
  37.         free(conhash);
  38.     }
  39. }

  40. void conhash_set_node(struct node_s *node, const char *iden, u_int replica)
  41. {
  42.     strncpy(node->iden, iden, sizeof(node->iden)-1);
  43.     node->replicas = replica;
  44.     node->flag = NODE_FLAG_INIT;//把标注转换成已被初始化
  45. }

  46. int conhash_add_node(struct conhash_s *conhash, struct node_s *node)
  47. {
  48.     if((conhash==NULL) || (node==NULL))
  49.     {
  50.         return -1;
  51.     }
  52.     /* 首先检查结点 */
  53.     if(!(node->flag&NODE_FLAG_INIT) || (node->flag&NODE_FLAG_IN))
  54.     {
  55.         return -1;
  56.     }
  57.     node->flag |= NODE_FLAG_IN;
  58.     /* 再做添加的后续工作 */
  59.     __conhash_add_replicas(conhash, node);
  60.  
  61.     return 0;
  62. }

  63. int conhash_del_node(struct conhash_s *conhash, struct node_s *node)
  64. {
  65.    if((conhash==NULL) || (node==NULL))
  66.     {
  67.         return -1;
  68.     }
  69.     /* 先检查一下node是否存在 */
  70.     if(!(node->flag&NODE_FLAG_INIT) || !(node->flag&NODE_FLAG_IN))
  71.     {
  72.         return -1;
  73.     }
  74.     node->flag &= (~NODE_FLAG_IN);
  75.     /* 调整至删除后对应的状态 */
  76.     __conhash_del_replicas(conhash, node);

  77.     return 0;
  78. }

  79. const struct node_s* conhash_lookup(const struct conhash_s *conhash, const char *object)
  80. {
  81.     long hash;
  82.     const util_rbtree_node_t *rbnode;
  83.     if((conhash==NULL) || (conhash->ivnodes==0) || (object==NULL))
  84.     {
  85.         return NULL;
  86.     }
  87.     /* 计算哈希值 */
  88.     hash = conhash->cb_hashfunc(object);
  89.     
  90.     rbnode = util_rbtree_lookup(&(conhash->vnode_tree), hash)
  91.      /* 找到了就返回值,找不到就返回NULL */
  92.     if(rbnode != NULL)
  93.     {
  94.         struct virtual_node_s *vnode = rbnode->data;
  95.         return vnode->node;
  96.     }
  97.     return NULL;
  98. }
最后来看上面接口中的小功能实现:

  1. /*
  2.  * 利用MD5作为默认的哈希==加密
  3.  * instr即为input string
  4.  */
  5. long __conhash_hash_def(const char *instr)
  6. {
  7.     int i;
  8.     long hash = 0;
  9.     unsigned char digest[16];
  10.     conhash_md5_digest((const u_char*)instr, digest);

  11.     /*利用连续的4个比特位来计算哈希*/
  12.     for(i = 0; i < 4; i++)
  13.     {
  14.         hash += ((long)(digest[i*4 + 3]&0xFF) << 24)
  15.             | ((long)(digest[i*4 + 2]&0xFF) << 16)
  16.             | ((long)(digest[i*4 + 1]&0xFF) << 8)
  17.             | ((long)(digest[i*4 + 0]&0xFF));
  18.     }
  19.     return hash;
  20. }
  21. void __conhash_add_replicas(struct conhash_s *conhash, struct node_s *node)//加入一个设备需要的代价
  22. {
  23.     u_int i, len;
  24.     long hash;
  25.     char buff[128];
  26.     util_rbtree_node_t *rbnode;
  27.     for(i = 0; i < node->replicas; i++)
  28.     {
  29.         /* 计算每个虚拟结点的哈希值 */
  30.         __conhash_node2string(node, i, buff, &len);
  31.         hash = conhash->cb_hashfunc(buff);
  32.         /* 加入一个虚拟结点,并且检查需要复制的数据 */
  33.         if(util_rbtree_search(&(conhash->vnode_tree), hash) == NULL)
  34.         {
  35.             rbnode = __conhash_get_rbnode(node, hash);
  36.             if(rbnode != NULL)
  37.             {
  38.                 util_rbtree_insert(&(conhash->vnode_tree), rbnode);
  39.                 conhash->ivnodes++;
  40.             }
  41.         }
  42.     }
  43. }

  44. void __conhash_del_replicas(struct conhash_s *conhash, struct node_s *node)//删除一个设备需要做的工作
  45. {
  46.     u_int i, len;
  47.     long hash;
  48.     char buff[128];
  49.     struct virtual_node_s *vnode;
  50.     util_rbtree_node_t *rbnode;
  51.     for(i = 0; i < node->replicas; i++)
  52.     {
  53.         /* 计算每个虚拟结点的哈希值*/
  54.         __conhash_node2string(node, i, buff, &len);
  55.         hash = conhash->cb_hashfunc(buff);
  56.         rbnode = util_rbtree_search(&(conhash->vnode_tree), hash);
  57.         if(rbnode != NULL)//删掉数据
  58.         {
  59.             vnode = rbnode->data;
  60.             if((vnode->hash == hash) && (vnode->node == node))
  61.             {
  62.                 conhash->ivnodes--;
  63.                 util_rbtree_delete(&(conhash->vnode_tree), rbnode);
  64.                 __conhash_del_rbnode(rbnode);
  65.             }
  66.         }
  67.     }
  68. }
  69. util_rbtree_node_t *__conhash_get_rbnode(struct node_s *node, long hash)//利用数据在红黑树里创造结点
  70. {
  71.     util_rbtree_node_t *rbnode;
  72.     rbnode = (util_rbtree_node_t *)malloc(sizeof(util_rbtree_node_t));
  73.     if(rbnode != NULL)
  74.     {
  75.         rbnode->key = hash;
  76.         rbnode->data = malloc(sizeof(struct virtual_node_s));
  77.         if(rbnode->data != NULL)//如果不为NULL有存入的必要再存
  78.         {
  79.             struct virtual_node_s *vnode = rbnode->data;
  80.             vnode->hash = hash;
  81.             vnode->node = node;
  82.         }
  83.         else//要不然就释放了
  84.         {
  85.             free(rbnode);
  86.             rbnode = NULL;
  87.         }
  88.     }
  89.     return rbnode;
  90. }

  91. void __conhash_del_rbnode(util_rbtree_node_t *rbnode)//释放红黑树结点
  92. {
  93.     struct virtual_node_s *node;
  94.     node = rbnode->data;
  95.     free(node);
  96.     free(rbnode);
  97. }


总结:此项目利用红黑树做每个高速缓存机器的底层框架,利用MD5来算哈希值实现。
阅读(5483) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

狼行China2016-06-08 14:02:10

nice