OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (C) 2008 Apple Inc. All rights reserved. | |
dgrogan
2013/05/22 18:22:06
This turned out to be ok?
jamesr
2013/05/22 18:59:44
this doesn't look like the right copyright header.
jsbell
2013/05/22 19:13:04
I asked the lawyerly types what to do here in adva
| |
3 * | |
4 * Based on Abstract AVL Tree Template v1.5 by Walt Karas | |
5 * <http://geocities.com/wkaras/gen_cpp/avl_tree.html>. | |
6 * | |
7 * Redistribution and use in source and binary forms, with or without | |
8 * modification, are permitted provided that the following conditions | |
9 * are met: | |
10 * | |
11 * 1. Redistributions of source code must retain the above copyright | |
12 * notice, this list of conditions and the following disclaimer. | |
13 * 2. Redistributions in binary form must reproduce the above copyright | |
14 * notice, this list of conditions and the following disclaimer in the | |
15 * documentation and/or other materials provided with the distribution. | |
16 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of | |
17 * its contributors may be used to endorse or promote products derived | |
18 * from this software without specific prior written permission. | |
19 * | |
20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | |
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | |
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
30 */ | |
31 | |
32 #ifndef CONTENT_BROWSER_INDEXED_DB_LEVELDB_AVLTREE_H_ | |
33 #define CONTENT_BROWSER_INDEXED_DB_LEVELDB_AVLTREE_H_ | |
34 | |
35 #include "base/logging.h" | |
36 #include "content/browser/indexed_db/leveldb/fixed_array.h" | |
37 | |
38 namespace content { | |
39 | |
40 // Here is the reference class for BSet. | |
41 // | |
42 // class BSet | |
43 // { | |
44 // public: | |
45 // | |
46 // class ANY_bitref | |
47 // { | |
48 // public: | |
49 // operator bool (); | |
50 // void operator = (bool b); | |
51 // }; | |
52 // | |
53 // // Does not have to initialize bits. | |
54 // BSet(); | |
55 // | |
56 // // Must return a valid value for index when 0 <= index < maxDepth | |
57 // ANY_bitref operator [] (unsigned index); | |
58 // | |
59 // // Set all bits to 1. | |
60 // void set(); | |
61 // | |
62 // // Set all bits to 0. | |
63 // void reset(); | |
64 // }; | |
65 | |
66 template <unsigned maxDepth> class AVLTreeDefaultBSet { | |
67 public: | |
68 bool& operator[](unsigned i) { | |
69 #if defined(ADDRESS_SANITIZER) | |
70 CHECK(i < maxDepth); | |
71 #endif | |
72 return m_data[i]; | |
73 } | |
74 void set() { | |
75 for (unsigned i = 0; i < maxDepth; ++i) | |
76 m_data[i] = true; | |
77 } | |
78 void reset() { | |
79 for (unsigned i = 0; i < maxDepth; ++i) | |
80 m_data[i] = false; | |
81 } | |
82 | |
83 private: | |
84 FixedArray<bool, maxDepth> m_data; | |
85 }; | |
86 | |
87 // How to determine maxDepth: | |
88 // d Minimum number of nodes | |
89 // 2 2 | |
90 // 3 4 | |
91 // 4 7 | |
92 // 5 12 | |
93 // 6 20 | |
94 // 7 33 | |
95 // 8 54 | |
96 // 9 88 | |
97 // 10 143 | |
98 // 11 232 | |
99 // 12 376 | |
100 // 13 609 | |
101 // 14 986 | |
102 // 15 1,596 | |
103 // 16 2,583 | |
104 // 17 4,180 | |
105 // 18 6,764 | |
106 // 19 10,945 | |
107 // 20 17,710 | |
108 // 21 28,656 | |
109 // 22 46,367 | |
110 // 23 75,024 | |
111 // 24 121,392 | |
112 // 25 196,417 | |
113 // 26 317,810 | |
114 // 27 514,228 | |
115 // 28 832,039 | |
116 // 29 1,346,268 | |
117 // 30 2,178,308 | |
118 // 31 3,524,577 | |
119 // 32 5,702,886 | |
120 // 33 9,227,464 | |
121 // 34 14,930,351 | |
122 // 35 24,157,816 | |
123 // 36 39,088,168 | |
124 // 37 63,245,985 | |
125 // 38 102,334,154 | |
126 // 39 165,580,140 | |
127 // 40 267,914,295 | |
128 // 41 433,494,436 | |
129 // 42 701,408,732 | |
130 // 43 1,134,903,169 | |
131 // 44 1,836,311,902 | |
132 // 45 2,971,215,072 | |
133 // | |
134 // E.g., if, in a particular instantiation, the maximum number of nodes in a | |
135 // tree instance is 1,000,000, the maximum depth should be 28. | |
136 // You pick 28 because MN(28) is 832,039, which is less than or equal to | |
137 // 1,000,000, and MN(29) is 1,346,268, which is strictly greater than 1,000,000. | |
138 | |
139 template <class Abstractor, | |
140 unsigned maxDepth = 32, | |
141 class BSet = AVLTreeDefaultBSet<maxDepth> > | |
142 class AVLTree { | |
143 public: | |
144 typedef typename Abstractor::key key; | |
145 typedef typename Abstractor::handle handle; | |
146 typedef typename Abstractor::size size; | |
147 | |
148 enum SearchType { | |
149 EQUAL = 1, | |
150 LESS = 2, | |
151 GREATER = 4, | |
152 LESS_EQUAL = EQUAL | LESS, | |
153 GREATER_EQUAL = EQUAL | GREATER | |
154 }; | |
155 | |
156 Abstractor& abstractor() { return abs; } | |
157 | |
158 inline handle insert(handle h); | |
159 | |
160 inline handle search(key k, SearchType st = EQUAL); | |
161 inline handle search_least(); | |
162 inline handle search_greatest(); | |
163 | |
164 inline handle remove(key k); | |
165 | |
166 inline handle subst(handle new_node); | |
167 | |
168 void purge() { abs.root = null(); } | |
169 | |
170 bool is_empty() { return abs.root == null(); } | |
171 | |
172 AVLTree() { abs.root = null(); } | |
173 | |
174 class Iterator { | |
175 public: | |
176 // Initialize depth to invalid value, to indicate iterator is | |
177 // invalid. (Depth is zero-base.) | |
178 Iterator() { depth = ~0U; } | |
179 | |
180 void start_iter(AVLTree& tree, key k, SearchType st = EQUAL) { | |
181 // Mask of high bit in an int. | |
182 const int kMaskHighBit = (int) ~((~(unsigned) 0) >> 1); | |
183 | |
184 // Save the tree that we're going to iterate through in a | |
185 // member variable. | |
186 tree_ = &tree; | |
187 | |
188 int cmp, target_cmp; | |
189 handle h = tree_->abs.root; | |
190 unsigned d = 0; | |
191 | |
192 depth = ~0U; | |
193 | |
194 if (h == null()) { | |
195 // Tree is empty. | |
196 return; | |
197 } | |
198 | |
199 if (st & LESS) { | |
200 // Key can be greater than key of starting node. | |
201 target_cmp = 1; | |
202 } else if (st & GREATER) { | |
203 // Key can be less than key of starting node. | |
204 target_cmp = -1; | |
205 } else { | |
206 // Key must be same as key of starting node. | |
207 target_cmp = 0; | |
208 } | |
209 | |
210 for (;;) { | |
211 cmp = cmp_k_n(k, h); | |
212 if (cmp == 0) { | |
213 if (st & EQUAL) { | |
214 // Equal node was sought and found as starting node. | |
215 depth = d; | |
216 break; | |
217 } | |
218 cmp = -target_cmp; | |
219 } else if (target_cmp != 0) { | |
220 if (!((cmp ^ target_cmp) & kMaskHighBit)) { | |
221 // cmp and target_cmp are both negative or both positive. | |
222 depth = d; | |
223 } | |
224 } | |
225 h = cmp < 0 ? get_lt(h) : get_gt(h); | |
226 if (h == null()) | |
227 break; | |
228 branch[d] = cmp > 0; | |
229 path_h[d++] = h; | |
230 } | |
231 } | |
232 | |
233 void start_iter_least(AVLTree& tree) { | |
234 tree_ = &tree; | |
235 | |
236 handle h = tree_->abs.root; | |
237 | |
238 depth = ~0U; | |
239 | |
240 branch.reset(); | |
241 | |
242 while (h != null()) { | |
243 if (depth != ~0U) | |
244 path_h[depth] = h; | |
245 depth++; | |
246 h = get_lt(h); | |
247 } | |
248 } | |
249 | |
250 void start_iter_greatest(AVLTree& tree) { | |
251 tree_ = &tree; | |
252 | |
253 handle h = tree_->abs.root; | |
254 | |
255 depth = ~0U; | |
256 | |
257 branch.set(); | |
258 | |
259 while (h != null()) { | |
260 if (depth != ~0U) | |
261 path_h[depth] = h; | |
262 depth++; | |
263 h = get_gt(h); | |
264 } | |
265 } | |
266 | |
267 handle operator*() { | |
268 if (depth == ~0U) | |
269 return null(); | |
270 | |
271 return depth == 0 ? tree_->abs.root : path_h[depth - 1]; | |
272 } | |
273 | |
274 void operator++() { | |
275 if (depth != ~0U) { | |
276 handle h = get_gt(**this); | |
277 if (h == null()) { | |
278 do { | |
279 if (depth == 0) { | |
280 depth = ~0U; | |
281 break; | |
282 } | |
283 depth--; | |
284 } while (branch[depth]); | |
285 } else { | |
286 branch[depth] = true; | |
287 path_h[depth++] = h; | |
288 for (;;) { | |
289 h = get_lt(h); | |
290 if (h == null()) | |
291 break; | |
292 branch[depth] = false; | |
293 path_h[depth++] = h; | |
294 } | |
295 } | |
296 } | |
297 } | |
298 | |
299 void operator--() { | |
300 if (depth != ~0U) { | |
301 handle h = get_lt(**this); | |
302 if (h == null()) { | |
303 do { | |
304 if (depth == 0) { | |
305 depth = ~0U; | |
306 break; | |
307 } | |
308 depth--; | |
309 } while (!branch[depth]); | |
310 } else { | |
311 branch[depth] = false; | |
312 path_h[depth++] = h; | |
313 for (;;) { | |
314 h = get_gt(h); | |
315 if (h == null()) | |
316 break; | |
317 branch[depth] = true; | |
318 path_h[depth++] = h; | |
319 } | |
320 } | |
321 } | |
322 } | |
323 | |
324 void operator++(int) { ++(*this); } | |
325 void operator--(int) { --(*this); } | |
326 | |
327 protected: | |
328 | |
329 // Tree being iterated over. | |
330 AVLTree* tree_; | |
331 | |
332 // Records a path into the tree. If branch[n] is true, indicates | |
333 // take greater branch from the nth node in the path, otherwise | |
334 // take the less branch. branch[0] gives branch from root, and | |
335 // so on. | |
336 BSet branch; | |
337 | |
338 // Zero-based depth of path into tree. | |
339 unsigned depth; | |
340 | |
341 // Handles of nodes in path from root to current node (returned by *). | |
342 handle path_h[maxDepth - 1]; | |
343 | |
344 int cmp_k_n(key k, handle h) { return tree_->abs.compare_key_node(k, h); } | |
345 int cmp_n_n(handle h1, handle h2) { | |
346 return tree_->abs.compare_node_node(h1, h2); | |
347 } | |
348 handle get_lt(handle h) { return tree_->abs.get_less(h); } | |
349 handle get_gt(handle h) { return tree_->abs.get_greater(h); } | |
350 handle null() { return tree_->abs.null(); } | |
351 }; | |
352 | |
353 template <typename fwd_iter> bool build(fwd_iter p, size num_nodes) { | |
354 if (num_nodes == 0) { | |
355 abs.root = null(); | |
356 return true; | |
357 } | |
358 | |
359 // Gives path to subtree being built. If branch[N] is false, branch | |
360 // less from the node at depth N, if true branch greater. | |
361 BSet branch; | |
362 | |
363 // If rem[N] is true, then for the current subtree at depth N, it's | |
364 // greater subtree has one more node than it's less subtree. | |
365 BSet rem; | |
366 | |
367 // Depth of root node of current subtree. | |
368 unsigned depth = 0; | |
369 | |
370 // Number of nodes in current subtree. | |
371 size num_sub = num_nodes; | |
372 | |
373 // The algorithm relies on a stack of nodes whose less subtree has | |
374 // been built, but whose right subtree has not yet been built. The | |
375 // stack is implemented as linked list. The nodes are linked | |
376 // together by having the "greater" handle of a node set to the | |
377 // next node in the list. "less_parent" is the handle of the first | |
378 // node in the list. | |
379 handle less_parent = null(); | |
380 | |
381 // h is root of current subtree, child is one of its children. | |
382 handle h, child; | |
383 | |
384 for (;;) { | |
385 while (num_sub > 2) { | |
386 // Subtract one for root of subtree. | |
387 num_sub--; | |
388 rem[depth] = !!(num_sub & 1); | |
389 branch[depth++] = false; | |
390 num_sub >>= 1; | |
391 } | |
392 | |
393 if (num_sub == 2) { | |
394 // Build a subtree with two nodes, slanting to greater. | |
395 // I arbitrarily chose to always have the extra node in the | |
396 // greater subtree when there is an odd number of nodes to | |
397 // split between the two subtrees. | |
398 | |
399 h = *p; | |
400 p++; | |
401 child = *p; | |
402 p++; | |
403 set_lt(child, null()); | |
404 set_gt(child, null()); | |
405 set_bf(child, 0); | |
406 set_gt(h, child); | |
407 set_lt(h, null()); | |
408 set_bf(h, 1); | |
409 } else { // num_sub == 1 | |
410 // Build a subtree with one node. | |
411 | |
412 h = *p; | |
413 p++; | |
414 set_lt(h, null()); | |
415 set_gt(h, null()); | |
416 set_bf(h, 0); | |
417 } | |
418 | |
419 while (depth) { | |
420 depth--; | |
421 if (!branch[depth]) { | |
422 // We've completed a less subtree. | |
423 break; | |
424 } | |
425 | |
426 // We've completed a greater subtree, so attach it to | |
427 // its parent (that is less than it). We pop the parent | |
428 // off the stack of less parents. | |
429 child = h; | |
430 h = less_parent; | |
431 less_parent = get_gt(h); | |
432 set_gt(h, child); | |
433 // num_sub = 2 * (num_sub - rem[depth]) + rem[depth] + 1 | |
434 num_sub <<= 1; | |
435 num_sub += 1 - rem[depth]; | |
436 if (num_sub & (num_sub - 1)) { | |
437 // num_sub is not a power of 2 | |
438 set_bf(h, 0); | |
439 } else { | |
440 // num_sub is a power of 2 | |
441 set_bf(h, 1); | |
442 } | |
443 } | |
444 | |
445 if (num_sub == num_nodes) { | |
446 // We've completed the full tree. | |
447 break; | |
448 } | |
449 | |
450 // The subtree we've completed is the less subtree of the | |
451 // next node in the sequence. | |
452 | |
453 child = h; | |
454 h = *p; | |
455 p++; | |
456 set_lt(h, child); | |
457 | |
458 // Put h into stack of less parents. | |
459 set_gt(h, less_parent); | |
460 less_parent = h; | |
461 | |
462 // Proceed to creating greater than subtree of h. | |
463 branch[depth] = true; | |
464 num_sub += rem[depth++]; | |
465 | |
466 } // end for (;;) | |
467 | |
468 abs.root = h; | |
469 | |
470 return true; | |
471 } | |
472 | |
473 protected: | |
474 | |
475 friend class Iterator; | |
476 | |
477 // Create a class whose sole purpose is to take advantage of | |
478 // the "empty member" optimization. | |
479 struct abs_plus_root : public Abstractor { | |
480 // The handle of the root element in the AVL tree. | |
481 handle root; | |
482 }; | |
483 | |
484 abs_plus_root abs; | |
485 | |
486 handle get_lt(handle h) { return abs.get_less(h); } | |
487 void set_lt(handle h, handle lh) { abs.set_less(h, lh); } | |
488 | |
489 handle get_gt(handle h) { return abs.get_greater(h); } | |
490 void set_gt(handle h, handle gh) { abs.set_greater(h, gh); } | |
491 | |
492 int get_bf(handle h) { return abs.get_balance_factor(h); } | |
493 void set_bf(handle h, int bf) { abs.set_balance_factor(h, bf); } | |
494 | |
495 int cmp_k_n(key k, handle h) { return abs.compare_key_node(k, h); } | |
496 int cmp_n_n(handle h1, handle h2) { return abs.compare_node_node(h1, h2); } | |
497 | |
498 handle null() { return abs.null(); } | |
499 | |
500 private: | |
501 | |
502 // Balances subtree, returns handle of root node of subtree | |
503 // after balancing. | |
504 handle balance(handle bal_h) { | |
505 handle deep_h; | |
506 | |
507 // Either the "greater than" or the "less than" subtree of | |
508 // this node has to be 2 levels deeper (or else it wouldn't | |
509 // need balancing). | |
510 | |
511 if (get_bf(bal_h) > 0) { | |
512 // "Greater than" subtree is deeper. | |
513 | |
514 deep_h = get_gt(bal_h); | |
515 | |
516 if (get_bf(deep_h) < 0) { | |
517 handle old_h = bal_h; | |
518 bal_h = get_lt(deep_h); | |
519 | |
520 set_gt(old_h, get_lt(bal_h)); | |
521 set_lt(deep_h, get_gt(bal_h)); | |
522 set_lt(bal_h, old_h); | |
523 set_gt(bal_h, deep_h); | |
524 | |
525 int bf = get_bf(bal_h); | |
526 if (bf != 0) { | |
527 if (bf > 0) { | |
528 set_bf(old_h, -1); | |
529 set_bf(deep_h, 0); | |
530 } else { | |
531 set_bf(deep_h, 1); | |
532 set_bf(old_h, 0); | |
533 } | |
534 set_bf(bal_h, 0); | |
535 } else { | |
536 set_bf(old_h, 0); | |
537 set_bf(deep_h, 0); | |
538 } | |
539 } else { | |
540 set_gt(bal_h, get_lt(deep_h)); | |
541 set_lt(deep_h, bal_h); | |
542 if (get_bf(deep_h) == 0) { | |
543 set_bf(deep_h, -1); | |
544 set_bf(bal_h, 1); | |
545 } else { | |
546 set_bf(deep_h, 0); | |
547 set_bf(bal_h, 0); | |
548 } | |
549 bal_h = deep_h; | |
550 } | |
551 } else { | |
552 // "Less than" subtree is deeper. | |
553 | |
554 deep_h = get_lt(bal_h); | |
555 | |
556 if (get_bf(deep_h) > 0) { | |
557 handle old_h = bal_h; | |
558 bal_h = get_gt(deep_h); | |
559 set_lt(old_h, get_gt(bal_h)); | |
560 set_gt(deep_h, get_lt(bal_h)); | |
561 set_gt(bal_h, old_h); | |
562 set_lt(bal_h, deep_h); | |
563 | |
564 int bf = get_bf(bal_h); | |
565 if (bf != 0) { | |
566 if (bf < 0) { | |
567 set_bf(old_h, 1); | |
568 set_bf(deep_h, 0); | |
569 } else { | |
570 set_bf(deep_h, -1); | |
571 set_bf(old_h, 0); | |
572 } | |
573 set_bf(bal_h, 0); | |
574 } else { | |
575 set_bf(old_h, 0); | |
576 set_bf(deep_h, 0); | |
577 } | |
578 } else { | |
579 set_lt(bal_h, get_gt(deep_h)); | |
580 set_gt(deep_h, bal_h); | |
581 if (get_bf(deep_h) == 0) { | |
582 set_bf(deep_h, 1); | |
583 set_bf(bal_h, -1); | |
584 } else { | |
585 set_bf(deep_h, 0); | |
586 set_bf(bal_h, 0); | |
587 } | |
588 bal_h = deep_h; | |
589 } | |
590 } | |
591 | |
592 return bal_h; | |
593 } | |
594 | |
595 }; | |
596 | |
597 template <class Abstractor, unsigned maxDepth, class BSet> | |
598 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle | |
599 AVLTree<Abstractor, maxDepth, BSet>::insert(handle h) { | |
600 set_lt(h, null()); | |
601 set_gt(h, null()); | |
602 set_bf(h, 0); | |
603 | |
604 if (abs.root == null()) { | |
605 abs.root = h; | |
606 } else { | |
607 // Last unbalanced node encountered in search for insertion point. | |
608 handle unbal = null(); | |
609 // Parent of last unbalanced node. | |
610 handle parent_unbal = null(); | |
611 // Balance factor of last unbalanced node. | |
612 int unbal_bf; | |
613 | |
614 // Zero-based depth in tree. | |
615 unsigned depth = 0, unbal_depth = 0; | |
616 | |
617 // Records a path into the tree. If branch[n] is true, indicates | |
618 // take greater branch from the nth node in the path, otherwise | |
619 // take the less branch. branch[0] gives branch from root, and | |
620 // so on. | |
621 BSet branch; | |
622 | |
623 handle hh = abs.root; | |
624 handle parent = null(); | |
625 int cmp; | |
626 | |
627 do { | |
628 if (get_bf(hh) != 0) { | |
629 unbal = hh; | |
630 parent_unbal = parent; | |
631 unbal_depth = depth; | |
632 } | |
633 cmp = cmp_n_n(h, hh); | |
634 if (cmp == 0) { | |
635 // Duplicate key. | |
636 return hh; | |
637 } | |
638 parent = hh; | |
639 hh = cmp < 0 ? get_lt(hh) : get_gt(hh); | |
640 branch[depth++] = cmp > 0; | |
641 } while (hh != null()); | |
642 | |
643 // Add node to insert as leaf of tree. | |
644 if (cmp < 0) | |
645 set_lt(parent, h); | |
646 else | |
647 set_gt(parent, h); | |
648 | |
649 depth = unbal_depth; | |
650 | |
651 if (unbal == null()) { | |
652 hh = abs.root; | |
653 } else { | |
654 cmp = branch[depth++] ? 1 : -1; | |
655 unbal_bf = get_bf(unbal); | |
656 if (cmp < 0) | |
657 unbal_bf--; | |
658 else // cmp > 0 | |
659 unbal_bf++; | |
660 hh = cmp < 0 ? get_lt(unbal) : get_gt(unbal); | |
661 if ((unbal_bf != -2) && (unbal_bf != 2)) { | |
662 // No rebalancing of tree is necessary. | |
663 set_bf(unbal, unbal_bf); | |
664 unbal = null(); | |
665 } | |
666 } | |
667 | |
668 if (hh != null()) { | |
669 while (h != hh) { | |
670 cmp = branch[depth++] ? 1 : -1; | |
671 if (cmp < 0) { | |
672 set_bf(hh, -1); | |
673 hh = get_lt(hh); | |
674 } else { // cmp > 0 | |
675 set_bf(hh, 1); | |
676 hh = get_gt(hh); | |
677 } | |
678 } | |
679 } | |
680 | |
681 if (unbal != null()) { | |
682 unbal = balance(unbal); | |
683 if (parent_unbal == null()) { | |
684 abs.root = unbal; | |
685 } else { | |
686 depth = unbal_depth - 1; | |
687 cmp = branch[depth] ? 1 : -1; | |
688 if (cmp < 0) | |
689 set_lt(parent_unbal, unbal); | |
690 else // cmp > 0 | |
691 set_gt(parent_unbal, unbal); | |
692 } | |
693 } | |
694 } | |
695 | |
696 return h; | |
697 } | |
698 | |
699 template <class Abstractor, unsigned maxDepth, class BSet> | |
700 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle | |
701 AVLTree<Abstractor, maxDepth, BSet>::search( | |
702 key k, | |
703 typename AVLTree<Abstractor, maxDepth, BSet>::SearchType st) { | |
704 const int kMaskHighBit = (int) ~((~(unsigned) 0) >> 1); | |
705 | |
706 int cmp, target_cmp; | |
707 handle match_h = null(); | |
708 handle h = abs.root; | |
709 | |
710 if (st & LESS) | |
711 target_cmp = 1; | |
712 else if (st & GREATER) | |
713 target_cmp = -1; | |
714 else | |
715 target_cmp = 0; | |
716 | |
717 while (h != null()) { | |
718 cmp = cmp_k_n(k, h); | |
719 if (cmp == 0) { | |
720 if (st & EQUAL) { | |
721 match_h = h; | |
722 break; | |
723 } | |
724 cmp = -target_cmp; | |
725 } else if (target_cmp != 0) { | |
726 if (!((cmp ^ target_cmp) & kMaskHighBit)) { | |
727 // cmp and target_cmp are both positive or both negative. | |
728 match_h = h; | |
729 } | |
730 } | |
731 h = cmp < 0 ? get_lt(h) : get_gt(h); | |
732 } | |
733 | |
734 return match_h; | |
735 } | |
736 | |
737 template <class Abstractor, unsigned maxDepth, class BSet> | |
738 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle | |
739 AVLTree<Abstractor, maxDepth, BSet>::search_least() { | |
740 handle h = abs.root, parent = null(); | |
741 | |
742 while (h != null()) { | |
743 parent = h; | |
744 h = get_lt(h); | |
745 } | |
746 | |
747 return parent; | |
748 } | |
749 | |
750 template <class Abstractor, unsigned maxDepth, class BSet> | |
751 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle | |
752 AVLTree<Abstractor, maxDepth, BSet>::search_greatest() { | |
753 handle h = abs.root, parent = null(); | |
754 | |
755 while (h != null()) { | |
756 parent = h; | |
757 h = get_gt(h); | |
758 } | |
759 | |
760 return parent; | |
761 } | |
762 | |
763 template <class Abstractor, unsigned maxDepth, class BSet> | |
764 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle | |
765 AVLTree<Abstractor, maxDepth, BSet>::remove(key k) { | |
766 // Zero-based depth in tree. | |
767 unsigned depth = 0, rm_depth; | |
768 | |
769 // Records a path into the tree. If branch[n] is true, indicates | |
770 // take greater branch from the nth node in the path, otherwise | |
771 // take the less branch. branch[0] gives branch from root, and | |
772 // so on. | |
773 BSet branch; | |
774 | |
775 handle h = abs.root; | |
776 handle parent = null(), child; | |
777 int cmp, cmp_shortened_sub_with_path = 0; | |
778 | |
779 for (;;) { | |
780 if (h == null()) { | |
781 // No node in tree with given key. | |
782 return null(); | |
783 } | |
784 cmp = cmp_k_n(k, h); | |
785 if (cmp == 0) { | |
786 // Found node to remove. | |
787 break; | |
788 } | |
789 parent = h; | |
790 h = cmp < 0 ? get_lt(h) : get_gt(h); | |
791 branch[depth++] = cmp > 0; | |
792 cmp_shortened_sub_with_path = cmp; | |
793 } | |
794 handle rm = h; | |
795 handle parent_rm = parent; | |
796 rm_depth = depth; | |
797 | |
798 // If the node to remove is not a leaf node, we need to get a | |
799 // leaf node, or a node with a single leaf as its child, to put | |
800 // in the place of the node to remove. We will get the greatest | |
801 // node in the less subtree (of the node to remove), or the least | |
802 // node in the greater subtree. We take the leaf node from the | |
803 // deeper subtree, if there is one. | |
804 | |
805 if (get_bf(h) < 0) { | |
806 child = get_lt(h); | |
807 branch[depth] = false; | |
808 cmp = -1; | |
809 } else { | |
810 child = get_gt(h); | |
811 branch[depth] = true; | |
812 cmp = 1; | |
813 } | |
814 depth++; | |
815 | |
816 if (child != null()) { | |
817 cmp = -cmp; | |
818 do { | |
819 parent = h; | |
820 h = child; | |
821 if (cmp < 0) { | |
822 child = get_lt(h); | |
823 branch[depth] = false; | |
824 } else { | |
825 child = get_gt(h); | |
826 branch[depth] = true; | |
827 } | |
828 depth++; | |
829 } while (child != null()); | |
830 | |
831 if (parent == rm) { | |
832 // Only went through do loop once. Deleted node will be replaced | |
833 // in the tree structure by one of its immediate children. | |
834 cmp_shortened_sub_with_path = -cmp; | |
835 } else { | |
836 cmp_shortened_sub_with_path = cmp; | |
837 } | |
838 | |
839 // Get the handle of the opposite child, which may not be null. | |
840 child = cmp > 0 ? get_lt(h) : get_gt(h); | |
841 } | |
842 | |
843 if (parent == null()) { | |
844 // There were only 1 or 2 nodes in this tree. | |
845 abs.root = child; | |
846 } else if (cmp_shortened_sub_with_path < 0) { | |
847 set_lt(parent, child); | |
848 } else { | |
849 set_gt(parent, child); | |
850 } | |
851 | |
852 // "path" is the parent of the subtree being eliminated or reduced | |
853 // from a depth of 2 to 1. If "path" is the node to be removed, we | |
854 // set path to the node we're about to poke into the position of the | |
855 // node to be removed. | |
856 handle path = parent == rm ? h : parent; | |
857 | |
858 if (h != rm) { | |
859 // Poke in the replacement for the node to be removed. | |
860 set_lt(h, get_lt(rm)); | |
861 set_gt(h, get_gt(rm)); | |
862 set_bf(h, get_bf(rm)); | |
863 if (parent_rm == null()) { | |
864 abs.root = h; | |
865 } else { | |
866 depth = rm_depth - 1; | |
867 if (branch[depth]) | |
868 set_gt(parent_rm, h); | |
869 else | |
870 set_lt(parent_rm, h); | |
871 } | |
872 } | |
873 | |
874 if (path != null()) { | |
875 // Create a temporary linked list from the parent of the path node | |
876 // to the root node. | |
877 h = abs.root; | |
878 parent = null(); | |
879 depth = 0; | |
880 while (h != path) { | |
881 if (branch[depth++]) { | |
882 child = get_gt(h); | |
883 set_gt(h, parent); | |
884 } else { | |
885 child = get_lt(h); | |
886 set_lt(h, parent); | |
887 } | |
888 parent = h; | |
889 h = child; | |
890 } | |
891 | |
892 // Climb from the path node to the root node using the linked | |
893 // list, restoring the tree structure and rebalancing as necessary. | |
894 bool reduced_depth = true; | |
895 int bf; | |
896 cmp = cmp_shortened_sub_with_path; | |
897 for (;;) { | |
898 if (reduced_depth) { | |
899 bf = get_bf(h); | |
900 if (cmp < 0) | |
901 bf++; | |
902 else // cmp > 0 | |
903 bf--; | |
904 if ((bf == -2) || (bf == 2)) { | |
905 h = balance(h); | |
906 bf = get_bf(h); | |
907 } else { | |
908 set_bf(h, bf); | |
909 } | |
910 reduced_depth = (bf == 0); | |
911 } | |
912 if (parent == null()) | |
913 break; | |
914 child = h; | |
915 h = parent; | |
916 cmp = branch[--depth] ? 1 : -1; | |
917 if (cmp < 0) { | |
918 parent = get_lt(h); | |
919 set_lt(h, child); | |
920 } else { | |
921 parent = get_gt(h); | |
922 set_gt(h, child); | |
923 } | |
924 } | |
925 abs.root = h; | |
926 } | |
927 | |
928 return rm; | |
929 } | |
930 | |
931 template <class Abstractor, unsigned maxDepth, class BSet> | |
932 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle | |
933 AVLTree<Abstractor, maxDepth, BSet>::subst(handle new_node) { | |
934 handle h = abs.root; | |
935 handle parent = null(); | |
936 int cmp, last_cmp; | |
937 | |
938 // Search for node already in tree with same key. | |
939 for (;;) { | |
940 if (h == null()) { | |
941 // No node in tree with same key as new node. | |
942 return null(); | |
943 } | |
944 cmp = cmp_n_n(new_node, h); | |
945 if (cmp == 0) { | |
946 // Found the node to substitute new one for. | |
947 break; | |
948 } | |
949 last_cmp = cmp; | |
950 parent = h; | |
951 h = cmp < 0 ? get_lt(h) : get_gt(h); | |
952 } | |
953 | |
954 // Copy tree housekeeping fields from node in tree to new node. | |
955 set_lt(new_node, get_lt(h)); | |
956 set_gt(new_node, get_gt(h)); | |
957 set_bf(new_node, get_bf(h)); | |
958 | |
959 if (parent == null()) { | |
960 // New node is also new root. | |
961 abs.root = new_node; | |
962 } else { | |
963 // Make parent point to new node. | |
964 if (last_cmp < 0) | |
965 set_lt(parent, new_node); | |
966 else | |
967 set_gt(parent, new_node); | |
968 } | |
969 | |
970 return h; | |
971 } | |
972 | |
973 } // namespace content | |
974 | |
975 #endif // CONTENT_BROWSER_INDEXED_DB_LEVELDB_AVLTREE_H_ | |
OLD | NEW |