ffi-radix_tree 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,536 @@
1
+ #ifndef RADIX_TREE_HPP
2
+ #define RADIX_TREE_HPP
3
+
4
+ #include <cassert>
5
+ #include <string>
6
+ #include <utility>
7
+ #include <vector>
8
+
9
+ #include "radix_tree_it.hpp"
10
+ #include "radix_tree_node.hpp"
11
+
12
+ template<typename K>
13
+ K radix_substr(const K &key, int begin, int num);
14
+
15
+ template<>
16
+ inline std::string radix_substr<std::string>(const std::string &key, int begin, int num)
17
+ {
18
+ return key.substr(begin, num);
19
+ }
20
+
21
+ template<typename K>
22
+ K radix_join(const K &key1, const K &key2);
23
+
24
+ template<>
25
+ inline std::string radix_join<std::string>(const std::string &key1, const std::string &key2)
26
+ {
27
+ return key1 + key2;
28
+ }
29
+
30
+ template<typename K>
31
+ int radix_length(const K &key);
32
+
33
+ template<>
34
+ inline int radix_length<std::string>(const std::string &key)
35
+ {
36
+ return key.size();
37
+ }
38
+
39
+ template <typename K, typename T>
40
+ class radix_tree {
41
+ public:
42
+ typedef K key_type;
43
+ typedef T mapped_type;
44
+ typedef std::pair<const K, T> value_type;
45
+ typedef radix_tree_it<K, T> iterator;
46
+ typedef std::size_t size_type;
47
+
48
+ radix_tree() : m_size(0), m_root(NULL) { }
49
+ ~radix_tree() {
50
+ delete m_root;
51
+ }
52
+
53
+ size_type size() const {
54
+ return m_size;
55
+ }
56
+ bool empty() const {
57
+ return m_size == 0;
58
+ }
59
+ void clear() {
60
+ delete m_root;
61
+ m_root = NULL;
62
+ m_size = 0;
63
+ }
64
+
65
+ iterator find(const K &key);
66
+ iterator begin();
67
+ iterator end();
68
+
69
+ std::pair<iterator, bool> insert(const value_type &val);
70
+ bool erase(const K &key);
71
+ void erase(iterator it);
72
+ void prefix_match(const K &key, std::vector<iterator> &vec);
73
+ void greedy_match(const K &key, std::vector<iterator> &vec);
74
+ iterator longest_match(const K &key);
75
+
76
+ T& operator[] (const K &lhs);
77
+
78
+ private:
79
+ size_type m_size;
80
+ radix_tree_node<K, T>* m_root;
81
+
82
+ radix_tree_node<K, T>* begin(radix_tree_node<K, T> *node);
83
+ radix_tree_node<K, T>* find_node(const K &key, radix_tree_node<K, T> *node, int depth);
84
+ radix_tree_node<K, T>* append(radix_tree_node<K, T> *parent, const value_type &val);
85
+ radix_tree_node<K, T>* prepend(radix_tree_node<K, T> *node, const value_type &val);
86
+ void greedy_match(radix_tree_node<K, T> *node, std::vector<iterator> &vec);
87
+
88
+ radix_tree(const radix_tree& other); // delete
89
+ radix_tree& operator =(const radix_tree other); // delete
90
+ };
91
+
92
+ template <typename K, typename T>
93
+ void radix_tree<K, T>::prefix_match(const K &key, std::vector<iterator> &vec)
94
+ {
95
+ vec.clear();
96
+
97
+ if (m_root == NULL)
98
+ return;
99
+
100
+ radix_tree_node<K, T> *node;
101
+ K key_sub1, key_sub2;
102
+
103
+ node = find_node(key, m_root, 0);
104
+
105
+ if (node->m_is_leaf)
106
+ node = node->m_parent;
107
+
108
+ int len = radix_length(key) - node->m_depth;
109
+ key_sub1 = radix_substr(key, node->m_depth, len);
110
+ key_sub2 = radix_substr(node->m_key, 0, len);
111
+
112
+ if (key_sub1 != key_sub2)
113
+ return;
114
+
115
+ greedy_match(node, vec);
116
+ }
117
+
118
+ template <typename K, typename T>
119
+ typename radix_tree<K, T>::iterator radix_tree<K, T>::longest_match(const K &key)
120
+ {
121
+ if (m_root == NULL)
122
+ return iterator(NULL);
123
+
124
+ radix_tree_node<K, T> *node;
125
+ K key_sub;
126
+
127
+ node = find_node(key, m_root, 0);
128
+
129
+ if (node->m_is_leaf)
130
+ return iterator(node);
131
+
132
+ key_sub = radix_substr(key, node->m_depth, radix_length(node->m_key));
133
+
134
+ if (! (key_sub == node->m_key))
135
+ node = node->m_parent;
136
+
137
+ K nul = radix_substr(key, 0, 0);
138
+
139
+ while (node != NULL) {
140
+ typename radix_tree_node<K, T>::it_child it;
141
+ it = node->m_children.find(nul);
142
+ if (it != node->m_children.end() && it->second->m_is_leaf)
143
+ return iterator(it->second);
144
+
145
+ node = node->m_parent;
146
+ }
147
+
148
+ return iterator(NULL);
149
+ }
150
+
151
+
152
+ template <typename K, typename T>
153
+ typename radix_tree<K, T>::iterator radix_tree<K, T>::end()
154
+ {
155
+ return iterator(NULL);
156
+ }
157
+
158
+ template <typename K, typename T>
159
+ typename radix_tree<K, T>::iterator radix_tree<K, T>::begin()
160
+ {
161
+ radix_tree_node<K, T> *node;
162
+
163
+ if (m_root == NULL)
164
+ node = NULL;
165
+ else
166
+ node = begin(m_root);
167
+
168
+ return iterator(node);
169
+ }
170
+
171
+ template <typename K, typename T>
172
+ radix_tree_node<K, T>* radix_tree<K, T>::begin(radix_tree_node<K, T> *node)
173
+ {
174
+ if (node->m_is_leaf)
175
+ return node;
176
+
177
+ assert(!node->m_children.empty());
178
+
179
+ return begin(node->m_children.begin()->second);
180
+ }
181
+
182
+ template <typename K, typename T>
183
+ T& radix_tree<K, T>::operator[] (const K &lhs)
184
+ {
185
+ iterator it = find(lhs);
186
+
187
+ if (it == end()) {
188
+ std::pair<K, T> val;
189
+ val.first = lhs;
190
+
191
+ std::pair<iterator, bool> ret;
192
+ ret = insert(val);
193
+
194
+ assert(ret.second == true);
195
+
196
+ it = ret.first;
197
+ }
198
+
199
+ return it->second;
200
+ }
201
+
202
+ template <typename K, typename T>
203
+ void radix_tree<K, T>::greedy_match(const K &key, std::vector<iterator> &vec)
204
+ {
205
+ radix_tree_node<K, T> *node;
206
+
207
+ vec.clear();
208
+
209
+ if (m_root == NULL)
210
+ return;
211
+
212
+ node = find_node(key, m_root, 0);
213
+
214
+ if (node->m_is_leaf)
215
+ node = node->m_parent;
216
+
217
+ greedy_match(node, vec);
218
+ }
219
+
220
+ template <typename K, typename T>
221
+ void radix_tree<K, T>::greedy_match(radix_tree_node<K, T> *node, std::vector<iterator> &vec)
222
+ {
223
+ if (node->m_is_leaf) {
224
+ vec.push_back(iterator(node));
225
+ return;
226
+ }
227
+
228
+ typename std::map<K, radix_tree_node<K, T>*>::iterator it;
229
+
230
+ for (it = node->m_children.begin(); it != node->m_children.end(); ++it) {
231
+ greedy_match(it->second, vec);
232
+ }
233
+ }
234
+
235
+ template <typename K, typename T>
236
+ void radix_tree<K, T>::erase(iterator it)
237
+ {
238
+ erase(it->first);
239
+ }
240
+
241
+ template <typename K, typename T>
242
+ bool radix_tree<K, T>::erase(const K &key)
243
+ {
244
+ if (m_root == NULL)
245
+ return 0;
246
+
247
+ radix_tree_node<K, T> *child;
248
+ radix_tree_node<K, T> *parent;
249
+ radix_tree_node<K, T> *grandparent;
250
+ K nul = radix_substr(key, 0, 0);
251
+
252
+ child = find_node(key, m_root, 0);
253
+
254
+ if (! child->m_is_leaf)
255
+ return 0;
256
+
257
+ parent = child->m_parent;
258
+ parent->m_children.erase(nul);
259
+
260
+ delete child;
261
+
262
+ m_size--;
263
+
264
+ if (parent == m_root)
265
+ return 1;
266
+
267
+ if (parent->m_children.size() > 1)
268
+ return 1;
269
+
270
+ if (parent->m_children.empty()) {
271
+ grandparent = parent->m_parent;
272
+ grandparent->m_children.erase(parent->m_key);
273
+ delete parent;
274
+ } else {
275
+ grandparent = parent;
276
+ }
277
+
278
+ if (grandparent == m_root) {
279
+ return 1;
280
+ }
281
+
282
+ if (grandparent->m_children.size() == 1) {
283
+ // merge grandparent with the uncle
284
+ typename std::map<K, radix_tree_node<K, T>*>::iterator it;
285
+ it = grandparent->m_children.begin();
286
+
287
+ radix_tree_node<K, T> *uncle = it->second;
288
+
289
+ if (uncle->m_is_leaf)
290
+ return 1;
291
+
292
+ uncle->m_depth = grandparent->m_depth;
293
+ uncle->m_key = radix_join(grandparent->m_key, uncle->m_key);
294
+ uncle->m_parent = grandparent->m_parent;
295
+
296
+ grandparent->m_children.erase(it);
297
+
298
+ grandparent->m_parent->m_children.erase(grandparent->m_key);
299
+ grandparent->m_parent->m_children[uncle->m_key] = uncle;
300
+
301
+ delete grandparent;
302
+ }
303
+
304
+ return 1;
305
+ }
306
+
307
+
308
+ template <typename K, typename T>
309
+ radix_tree_node<K, T>* radix_tree<K, T>::append(radix_tree_node<K, T> *parent, const value_type &val)
310
+ {
311
+ int depth;
312
+ int len;
313
+ K nul = radix_substr(val.first, 0, 0);
314
+ radix_tree_node<K, T> *node_c, *node_cc;
315
+
316
+ depth = parent->m_depth + radix_length(parent->m_key);
317
+ len = radix_length(val.first) - depth;
318
+
319
+ if (len == 0) {
320
+ node_c = new radix_tree_node<K, T>(val);
321
+
322
+ node_c->m_depth = depth;
323
+ node_c->m_parent = parent;
324
+ node_c->m_key = nul;
325
+ node_c->m_is_leaf = true;
326
+
327
+ parent->m_children[nul] = node_c;
328
+
329
+ return node_c;
330
+ } else {
331
+ node_c = new radix_tree_node<K, T>(val);
332
+
333
+ K key_sub = radix_substr(val.first, depth, len);
334
+
335
+ parent->m_children[key_sub] = node_c;
336
+
337
+ node_c->m_depth = depth;
338
+ node_c->m_parent = parent;
339
+ node_c->m_key = key_sub;
340
+
341
+
342
+ node_cc = new radix_tree_node<K, T>(val);
343
+ node_c->m_children[nul] = node_cc;
344
+
345
+ node_cc->m_depth = depth + len;
346
+ node_cc->m_parent = node_c;
347
+ node_cc->m_key = nul;
348
+ node_cc->m_is_leaf = true;
349
+
350
+ return node_cc;
351
+ }
352
+ }
353
+
354
+ template <typename K, typename T>
355
+ radix_tree_node<K, T>* radix_tree<K, T>::prepend(radix_tree_node<K, T> *node, const value_type &val)
356
+ {
357
+ int count;
358
+ int len1, len2;
359
+
360
+ len1 = radix_length(node->m_key);
361
+ len2 = radix_length(val.first) - node->m_depth;
362
+
363
+ for (count = 0; count < len1 && count < len2; count++) {
364
+ if (! (node->m_key[count] == val.first[count + node->m_depth]) )
365
+ break;
366
+ }
367
+
368
+ assert(count != 0);
369
+
370
+ node->m_parent->m_children.erase(node->m_key);
371
+
372
+ radix_tree_node<K, T> *node_a = new radix_tree_node<K, T>;
373
+
374
+ node_a->m_parent = node->m_parent;
375
+ node_a->m_key = radix_substr(node->m_key, 0, count);
376
+ node_a->m_depth = node->m_depth;
377
+ node_a->m_parent->m_children[node_a->m_key] = node_a;
378
+
379
+
380
+ node->m_depth += count;
381
+ node->m_parent = node_a;
382
+ node->m_key = radix_substr(node->m_key, count, len1 - count);
383
+ node->m_parent->m_children[node->m_key] = node;
384
+
385
+ K nul = radix_substr(val.first, 0, 0);
386
+ if (count == len2) {
387
+ radix_tree_node<K, T> *node_b;
388
+
389
+ node_b = new radix_tree_node<K, T>(val);
390
+
391
+ node_b->m_parent = node_a;
392
+ node_b->m_key = nul;
393
+ node_b->m_depth = node_a->m_depth + count;
394
+ node_b->m_is_leaf = true;
395
+ node_b->m_parent->m_children[nul] = node_b;
396
+
397
+ return node_b;
398
+ } else {
399
+ radix_tree_node<K, T> *node_b, *node_c;
400
+
401
+ node_b = new radix_tree_node<K, T>;
402
+
403
+ node_b->m_parent = node_a;
404
+ node_b->m_depth = node->m_depth;
405
+ node_b->m_key = radix_substr(val.first, node_b->m_depth, len2 - count);
406
+ node_b->m_parent->m_children[node_b->m_key] = node_b;
407
+
408
+ node_c = new radix_tree_node<K, T>(val);
409
+
410
+ node_c->m_parent = node_b;
411
+ node_c->m_depth = radix_length(val.first);
412
+ node_c->m_key = nul;
413
+ node_c->m_is_leaf = true;
414
+ node_c->m_parent->m_children[nul] = node_c;
415
+
416
+ return node_c;
417
+ }
418
+ }
419
+
420
+ template <typename K, typename T>
421
+ std::pair<typename radix_tree<K, T>::iterator, bool> radix_tree<K, T>::insert(const value_type &val)
422
+ {
423
+ if (m_root == NULL) {
424
+ K nul = radix_substr(val.first, 0, 0);
425
+
426
+ m_root = new radix_tree_node<K, T>;
427
+ m_root->m_key = nul;
428
+ }
429
+
430
+
431
+ radix_tree_node<K, T> *node = find_node(val.first, m_root, 0);
432
+
433
+ if (node->m_is_leaf) {
434
+ return std::pair<iterator, bool>(node, false);
435
+ } else if (node == m_root) {
436
+ m_size++;
437
+ return std::pair<iterator, bool>(append(m_root, val), true);
438
+ } else {
439
+ m_size++;
440
+ int len = radix_length(node->m_key);
441
+ K key_sub = radix_substr(val.first, node->m_depth, len);
442
+
443
+ if (key_sub == node->m_key) {
444
+ return std::pair<iterator, bool>(append(node, val), true);
445
+ } else {
446
+ return std::pair<iterator, bool>(prepend(node, val), true);
447
+ }
448
+ }
449
+ }
450
+
451
+ template <typename K, typename T>
452
+ typename radix_tree<K, T>::iterator radix_tree<K, T>::find(const K &key)
453
+ {
454
+ if (m_root == NULL)
455
+ return iterator(NULL);
456
+
457
+ radix_tree_node<K, T> *node = find_node(key, m_root, 0);
458
+
459
+ // if the node is a internal node, return NULL
460
+ if (! node->m_is_leaf)
461
+ return iterator(NULL);
462
+
463
+ return iterator(node);
464
+ }
465
+
466
+ template <typename K, typename T>
467
+ radix_tree_node<K, T>* radix_tree<K, T>::find_node(const K &key, radix_tree_node<K, T> *node, int depth)
468
+ {
469
+ if (node->m_children.empty())
470
+ return node;
471
+
472
+ typename radix_tree_node<K, T>::it_child it;
473
+ int len_key = radix_length(key) - depth;
474
+
475
+ for (it = node->m_children.begin(); it != node->m_children.end(); ++it) {
476
+ if (len_key == 0) {
477
+ if (it->second->m_is_leaf)
478
+ return it->second;
479
+ else
480
+ continue;
481
+ }
482
+
483
+ if (! it->second->m_is_leaf && key[depth] == it->first[0] ) {
484
+ int len_node = radix_length(it->first);
485
+ K key_sub = radix_substr(key, depth, len_node);
486
+
487
+ if (key_sub == it->first) {
488
+ return find_node(key, it->second, depth+len_node);
489
+ } else {
490
+ return it->second;
491
+ }
492
+ }
493
+ }
494
+
495
+ return node;
496
+ }
497
+
498
+ /*
499
+
500
+ (root)
501
+ |
502
+ |---------------
503
+ | | |
504
+ abcde bcdef c
505
+ | | | |------
506
+ | | $3 | | |
507
+ f ge d e $6
508
+ | | | |
509
+ $1 $2 $4 $5
510
+
511
+ find_node():
512
+ bcdef -> $3
513
+ bcdefa -> bcdef
514
+ c -> $6
515
+ cf -> c
516
+ abch -> abcde
517
+ abc -> abcde
518
+ abcde -> abcde
519
+ abcdef -> $1
520
+ abcdeh -> abcde
521
+ de -> (root)
522
+
523
+
524
+ (root)
525
+ |
526
+ abcd
527
+ |
528
+ $
529
+
530
+ (root)
531
+ |
532
+ $
533
+
534
+ */
535
+
536
+ #endif // RADIX_TREE_HPP