-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathconhash_inter.c
133 lines (120 loc) · 3.58 KB
/
conhash_inter.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* Copyright (C) 2010. [email protected]. All rights reserved. */
#include "conhash_inter.h"
#include "conhash.h"
/*
* the default hash function, using md5 algorithm
* @instr: input string
*/
unsigned long __conhash_hash_def(const char *instr)
{
int i;
long hash = 0;
unsigned char digest[16];
unsigned long a = 0;
conhash_md5_digest((const u_char*)instr, digest);
/* use successive 4-bytes from hash as numbers */
for(i = 0; i < 4; i++)
{
hash += ((long)(digest[i*4 + 3]&0xFF) << 24)
| ((long)(digest[i*4 + 2]&0xFF) << 16)
| ((long)(digest[i*4 + 1]&0xFF) << 8)
| ((long)(digest[i*4 + 0]&0xFF));
}
a = hash;
a = (a+0x7ed55d16) + (a<<12);
a = (a^0xc761c23c) ^ (a>>19);
a = (a+0x165667b1) + (a<<5);
a = (a+0xd3a2646c) ^ (a<<9);
a = (a+0xfd7046c5) + (a<<3);
a = (a^0xb55a4f09) ^ (a>>16);
/* ensure values are better spread all around the tree by multiplying
* by a large prime close to 3/4 of the tree.
*/
a = a * 3221225473U;
return a;
}
void __conhash_node2string(const struct node_s *node, u_int replica_idx, char buf[128], u_int *len)
{
#if (defined (WIN32) || defined (__WIN32))
_snprintf_s(buf, 127, _TRUNCATE, "%s-%03d", node->iden, replica_idx);
#else
snprintf(buf, 127, "%s-%03d", node->iden, replica_idx);
#endif
}
void __conhash_add_replicas(struct conhash_s *conhash, struct node_s *node)
{
u_int i, len;
long hash;
char buff[128];
util_rbtree_node_t *rbnode;
for(i = 0; i < node->replicas; i++)
{
/* calc hash value of all virtual nodes */
__conhash_node2string(node, i, buff, &len);
hash = conhash->cb_hashfunc(buff);
/* add virtual node, check duplication */
if(util_rbtree_search(&(conhash->vnode_tree), hash) == NULL)
{
rbnode = __conhash_get_rbnode(node, hash);
if(rbnode != NULL)
{
util_rbtree_insert(&(conhash->vnode_tree), rbnode);
conhash->ivnodes++;
}
}
}
}
void __conhash_del_replicas(struct conhash_s *conhash, struct node_s *node)
{
u_int i, len;
long hash;
char buff[128];
struct virtual_node_s *vnode;
util_rbtree_node_t *rbnode;
for(i = 0; i < node->replicas; i++)
{
/* calc hash value of all virtual nodes */
__conhash_node2string(node, i, buff, &len);
hash = conhash->cb_hashfunc(buff);
rbnode = util_rbtree_search(&(conhash->vnode_tree), hash);
if(rbnode != NULL)
{
vnode = rbnode->data;
if((vnode->hash == hash) && (vnode->node == node))
{
conhash->ivnodes--;
util_rbtree_delete(&(conhash->vnode_tree), rbnode);
__conhash_del_rbnode(rbnode);
}
}
}
}
util_rbtree_node_t *__conhash_get_rbnode(struct node_s *node, long hash)
{
util_rbtree_node_t *rbnode;
rbnode = (util_rbtree_node_t *)kmalloc(sizeof(util_rbtree_node_t),GFP_ATOMIC);
if(rbnode != NULL)
{
rbnode->key = hash;
rbnode->data = kmalloc(sizeof(struct virtual_node_s),GFP_ATOMIC);
if(rbnode->data != NULL)
{
struct virtual_node_s *vnode = rbnode->data;
vnode->hash = hash;
vnode->node = node;
}
else
{
kfree(rbnode);
rbnode = NULL;
}
}
return rbnode;
}
void __conhash_del_rbnode(util_rbtree_node_t *rbnode)
{
struct virtual_node_s *node;
node = rbnode->data;
kfree(node);
kfree(rbnode);
}