-
Notifications
You must be signed in to change notification settings - Fork 4
/
cbt.c
145 lines (123 loc) · 3.07 KB
/
cbt.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
134
135
136
137
138
139
140
141
142
143
144
145
#ifdef __KERNEL__
#include <linux/slab.h>
#include <linux/list.h>
#else
#include "include/list.h"
#endif
#include "include/cbt.h"
static int __gfp_kernel = GFP_KERNEL;
#ifdef __KERNEL__
#define ukfree(ptr) kfree(ptr)
#define ukmalloc(size) kmalloc(size, __gfp_kernel)
#else
#define ukfree(ptr) free(ptr)
#define ukmalloc(size) malloc(size)
#endif
cbt_t *cbt_init(void)
{
cbt_t *cbt = ukmalloc(sizeof(cbt_t));
cbt->root = NULL;
INIT_LIST_HEAD(&cbt->nodes);
return cbt;
}
struct cbt_node *cbt_get_sibling(struct cbt_node *node)
{
if(node->position == LEFT) {
return node->parent->right;
} else {
return node->parent->left;
}
}
void cbt_remove_node(struct cbt_node *node)
{
struct cbt_node *parent = node->parent;
if(!parent) {
ukfree(node);
return;
}
if(parent->parent) {
struct cbt_node *pp = parent->parent;
if(parent->position == LEFT) {
ukfree(parent);
pp->left = cbt_get_sibling(node);
ukfree(node);
pp->left->parent = pp;
pp->left->position = LEFT;
} else {
ukfree(parent);
pp->right = cbt_get_sibling(node);
ukfree(node);
pp->right->parent = pp;
pp->right->position = RIGHT;
}
}
}
void cbt_clean(cbt_t *cbt, int clean_data)
{
struct cbt_node *node, *tmp;
list_for_each_entry_safe(node, tmp, &cbt->nodes, list_node) {
if(clean_data) {
ukfree(node->data);
}
list_del_init(&node->list_node);
cbt_remove_node(node);
}
ukfree(cbt);
}
struct cbt_node *cbt_node_init(uint64_t seq, const void *data)
{
struct cbt_node *node = ukmalloc(sizeof(struct cbt_node));
node->left = NULL;
node->right = NULL;
node->parent = NULL;
node->data = (void*)data;
node->seq = seq;
return node;
}
int cbt_add_node(cbt_t *cbt, struct cbt_node *node, uint64_t seq)
{
/*pn is the leaf node*/
struct cbt_node *pn = cbt->root;
uint64_t mask = 1;
struct cbt_node *new_node;
/*find the leaf pn to split*/
while(pn->is_leaf == 0) {
if((node->seq & mask) == LEFT) {
pn = pn->left;
} else {
pn = pn->right;
}
mask*=2;
}
new_node = cbt_node_init(pn->seq, pn->data);
new_node->is_leaf = 1;
new_node->parent = pn;
pn->is_leaf = 0;
pn->data = NULL;
/*if the nodes has the same position bit in the next level, returns error*/
if((node->seq & mask) == (pn->seq & mask)) {
cbt_remove_node(new_node);
return -1;
}
pn->right = node;
pn->left = new_node;
node->parent = pn;
list_add_tail(&node->list_node, &cbt->nodes);
return 0;
}
void cbt_build(struct server_meta *servers, int number)
{
}
struct cbt_node *cbt_search(cbt_t *cbt, uint64_t seq)
{
struct cbt_node *node = cbt->root;
uint64_t mask = 1;
while(node->is_leaf == 1) {
if((seq & mask) == LEFT) {
node = node->left;
} else {
node = node->right;
}
}
return node;
}