13
13
14
14
uint16_t NodeBlock::size () {
15
15
// keep an empty item as temp used when splitting a full block
16
+ #ifdef DEBUG_BTREE
16
17
return 4 ;
17
- // return ((BLOCK_SIZE - sizeof(BlockHeader)) / sizeof(KeyValue));
18
+ #else
19
+ return ((BLOCK_SIZE - sizeof (BlockHeader)) / sizeof (KeyValue));
20
+ #endif // DEBUG_BTREE
18
21
}
19
22
20
- bool NodeBlock::isFull () {
23
+ bool NodeBlock::full () {
21
24
assert (header.count <= NodeBlock::size ());
22
25
return header.count == NodeBlock::size ();
23
26
}
24
27
25
- bool NodeBlock::isEmpty () {
28
+ bool NodeBlock::empty () {
26
29
return header.count == 0 ;
27
30
}
28
31
32
+ bool NodeBlock::eMin () {
33
+ return header.count == size () / 2 ;
34
+ }
35
+
36
+ bool NodeBlock::geMin () {
37
+ return header.count >= size () / 2 ;
38
+ }
39
+
29
40
uint16_t NodeBlock::find (uint64_t key) {
30
- assert (!isEmpty ());
41
+ assert (!empty ());
31
42
// TODO: diff between interior node and leaf
32
43
uint16_t i = 0 ;
33
- if (header. type == BLOCK_TYPE_NODE ) i++;
44
+ if (! isLeaf () ) i++;
34
45
uint16_t j = header.count - 1 ;
35
46
if (kv[j].key < key) return header.count ;
47
+
36
48
while (i < j) {
37
49
uint16_t mid = (i + j) / 2 ;
38
50
if (kv[mid].key < key)
@@ -43,77 +55,46 @@ uint16_t NodeBlock::find(uint64_t key) {
43
55
return j;
44
56
}
45
57
46
- bool NodeBlock::insert (KeyValue item, uint16_t index) {
58
+ void NodeBlock::insert (KeyValue item, uint16_t index) {
47
59
assert (index <= header.count );
48
60
memmove (&kv[index + 1 ], &kv[index],
49
61
sizeof (KeyValue) * (header.count - index));
50
62
kv[index] = item;
51
63
header.count ++;
52
- return true ;
53
64
}
54
65
55
- void NodeBlock::split (NodeBlock* nextNode, uint32_t index ) {
66
+ void NodeBlock::split (NodeBlock* nextNode) {
56
67
nextNode->header .type = header.type ;
57
68
58
69
// move kv
59
70
memcpy (&nextNode->kv [0 ], &kv[(NodeBlock::size () + 1 ) / 2 ], NodeBlock::size () / 2 * sizeof (KeyValue));
60
71
this ->header .count = (NodeBlock::size () + 1 ) / 2 ;
61
72
nextNode->header .count = NodeBlock::size () / 2 ;
62
73
63
- if (nextNode->header .type == BLOCK_TYPE_LEAF) {
64
- nextNode->header .next = this ->header .next ;
65
- this ->header .next = index;
66
- }
74
+ // chain brother
75
+ nextNode->header .next = this ->header .next ;
76
+ this ->header .next = nextNode->header .index ;
67
77
}
68
78
69
- // void BTree::setRootIndex(uint32_t index) {
70
- // rootIndex = index;
71
- // storage.setIndexOfRoot(rootIndex);
72
- // }
79
+ void NodeBlock::merge (NodeBlock * nextNode) {
80
+ memcpy (&kv[0 ], &nextNode->kv [0 ], nextNode->header .count );
73
81
74
- // 如果没有分裂,返回的value值为0。否则,返回要插入的值
75
- KeyValue BTree::insert (KeyValue kv, NodeBlock* cur) {
76
- assert (cur->header .type == BLOCK_TYPE_LEAF ||
77
- cur->header .type == BLOCK_TYPE_NODE);
78
-
79
- KeyValue res;
80
- res.value = 0 ;
81
-
82
- uint16_t i = cur->find (kv.key );
83
-
84
- if (cur->header .type == BLOCK_TYPE_LEAF) {
85
- cur->insert (kv, i);
86
- }
87
- else {
88
- if (cur->kv [i].key > kv.key ) {
89
- i--;
90
- }
91
- NodeBlock* t = (NodeBlock*)storage.getBlock (cur->kv [i].value );
92
- KeyValue r = insert (kv, t);
93
- if (r.value != 0 )
94
- cur->insert (r, cur->find (r.key ));
95
- }
96
- if (cur->isFull ()) {
97
- uint32_t index = 0 ;
82
+ header.count += nextNode->header .count ;
98
83
99
- NodeBlock* nextNode = (NodeBlock*)storage.getFreeBlock (&index);
100
- if (nextNode == NULL ) {
101
- // TODO: failed to allocate a new block
102
- }
103
- cur->split (nextNode, index);
104
- res = nextNode->kv [0 ];
105
- res.value = index;
106
- return res;
107
- }
108
- return res;
84
+ header.next = nextNode->header .next ;
109
85
}
110
86
111
- int BTree::remove (KeyValue kv, NodeBlock* cur) {
112
- return 0 ;
87
+ bool NodeBlock::isLeaf () {
88
+ assert (header.type == BLOCK_TYPE_LEAF ||
89
+ header.type == BLOCK_TYPE_NODE);
90
+ return header.type == BLOCK_TYPE_LEAF;
113
91
}
114
92
115
- int BTree::search (KeyValue kv, NodeBlock* cur) {
116
- return 0 ;
93
+ void NodeBlock::remove (uint16_t index) {
94
+ assert (index < header.count );
95
+ memmove (&kv[index], &kv[index + 1 ],
96
+ sizeof (KeyValue) * (header.count - index - 1 ));
97
+ header.count --;
117
98
}
118
99
119
100
BTree::BTree (StorageManager &s) :root(NULL ), storage(s) {
@@ -136,8 +117,9 @@ BTree::BTree(StorageManager &s) :root(NULL), storage(s) {
136
117
}
137
118
138
119
120
+ // 如果没有分裂,返回的value值为0。否则,返回要插入的值
139
121
int BTree::insert (KeyValue kv) {
140
- if (root->isEmpty ()) {
122
+ if (root->empty ()) {
141
123
root->insert (kv, 0 );
142
124
return 1 ;
143
125
}
@@ -148,7 +130,7 @@ int BTree::insert(KeyValue kv) {
148
130
if (newRoot == NULL ) {
149
131
// TODO: failed to allocate a new block
150
132
}
151
- newRoot->header .count = 1 ;
133
+ newRoot->header .count = 2 ;
152
134
newRoot->header .type = BLOCK_TYPE_NODE;
153
135
newRoot->kv [1 ] = r;
154
136
newRoot->kv [0 ].value = root->header .index ;
@@ -159,10 +141,127 @@ int BTree::insert(KeyValue kv) {
159
141
return 1 ;
160
142
}
161
143
144
+ KeyValue BTree::insert (KeyValue kv, NodeBlock* cur) {
145
+ KeyValue res;
146
+ res.value = 0 ;
147
+
148
+ uint16_t i = cur->find (kv.key );
149
+
150
+ if (cur->isLeaf ()) {
151
+ cur->insert (kv, i);
152
+ }
153
+ else {
154
+ if (cur->kv [i].key > kv.key ) {
155
+ i--;
156
+ }
157
+ NodeBlock* t = (NodeBlock*)storage.getBlock (cur->kv [i].value );
158
+ KeyValue r = insert (kv, t);
159
+ if (r.value != 0 )
160
+ cur->insert (r, cur->find (r.key ));
161
+ }
162
+
163
+
164
+ if (cur->full ()) {
165
+ uint32_t index = 0 ;
166
+
167
+ NodeBlock* nextNode = (NodeBlock*)storage.getFreeBlock (&index);
168
+ if (nextNode == NULL ) {
169
+ // TODO: failed to allocate a new block
170
+ }
171
+ cur->split (nextNode);
172
+ res = nextNode->kv [0 ];
173
+ res.value = index;
174
+ return res;
175
+ }
176
+ return res;
177
+ }
178
+
179
+ void BTree::remove (uint64_t key, NodeBlock* cur) {
180
+ uint16_t i = cur->find (key);
181
+
182
+ if (cur->isLeaf ()) {
183
+ if (cur->kv [i].key > key) return ;
184
+ else {
185
+ cur->remove (i);
186
+ }
187
+ }
188
+ else {
189
+ if (cur->kv [i].key > key) {
190
+ i--;
191
+ }
192
+ NodeBlock* s = (NodeBlock*)storage.getBlock (cur->kv [i].value );
193
+ remove (key, s);
194
+
195
+ // update the key in parent
196
+ cur->kv [i].key = s->kv [0 ].key ;
197
+
198
+ if (s->geMin ()) return ;
199
+
200
+ // maintain
201
+ if (i > 0 ) {
202
+ NodeBlock *left = (NodeBlock*)storage.getBlock (cur->kv [i - 1 ].value );
203
+ if (left->eMin ()) {
204
+ // merge
205
+ left->merge (s);
206
+ cur->remove (i);
207
+
208
+ storage.freeBlock (s->header .index );
209
+ }
210
+ else {
211
+ s->insert (left->kv [left->header .count - 1 ], 0 );
212
+ left->remove (left->header .count - 1 );
213
+ }
214
+ }
215
+ else {
216
+ NodeBlock *right = (NodeBlock*)storage.getBlock (cur->kv [i + 1 ].value );
217
+ if (right->eMin ()) {
218
+ // merge
219
+ s->merge (right);
220
+ cur->remove (i + 1 );
221
+
222
+ storage.freeBlock (right->header .index );
223
+ }
224
+ else {
225
+ s->insert (right->kv [0 ], s->header .count );
226
+ right->remove (0 );
227
+ cur->kv [i + 1 ].key = right->kv [0 ].key ;
228
+ }
229
+ }
230
+ }
231
+ }
232
+
233
+
162
234
int BTree::remove (uint64_t key) {
235
+ if (root->empty ()) {
236
+ return 0 ;
237
+ }
238
+ remove (key, root);
239
+ if (!root->isLeaf () && root->header .count == 1 ) {
240
+ NodeBlock* s = (NodeBlock*)storage.getBlock (root->kv [0 ].value );
241
+ root = s;
242
+ storage.freeBlock (s->header .index );
243
+ }
163
244
return 0 ;
164
245
}
165
246
166
- int BTree::search (uint64_t key, uint32_t * value) {
167
- return 0 ;
247
+
248
+ KeyValue BTree::search (uint64_t key, NodeBlock* cur) {
249
+ uint16_t i = cur->find (key);
250
+ if (cur->isLeaf ()) {
251
+ if (cur->kv [i].key == key)
252
+ return cur->kv [i];
253
+ }
254
+ else {
255
+ if (cur->kv [i].key > key) i--;
256
+ NodeBlock* s = (NodeBlock*)storage.getBlock (root->kv [i].value );
257
+ return search (key, s);
258
+ }
259
+ KeyValue res;
260
+ res.value = 0 ;
261
+ return res;
262
+ }
263
+
264
+
265
+ KeyValue BTree::search (uint64_t key) {
266
+ return search (key, root);
168
267
}
0 commit comments