Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(363)

Side by Side Diff: content/browser/indexed_db/leveldb/avltree.h

Issue 15564008: Migrate the IndexedDB backend from Blink to Chromium (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More linting/formatting c/o alec Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
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 MASK_HIGH_BIT = (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) & MASK_HIGH_BIT)) {
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 if (unbal != null()) {
681 unbal = balance(unbal);
682 if (parent_unbal == null()) {
683 abs.root = unbal;
684 } else {
685 depth = unbal_depth - 1;
686 cmp = branch[depth] ? 1 : -1;
687 if (cmp < 0)
688 set_lt(parent_unbal, unbal);
689 else // cmp > 0
690 set_gt(parent_unbal, unbal);
691 }
692 }
693 }
694
695 return h;
696 }
697
698 template <class Abstractor, unsigned maxDepth, class BSet>
699 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
700 AVLTree<Abstractor, maxDepth, BSet>::search(
701 key k,
702 typename AVLTree<Abstractor, maxDepth, BSet>::SearchType st) {
703 const int MASK_HIGH_BIT = (int) ~((~(unsigned) 0) >> 1);
704
705 int cmp, target_cmp;
706 handle match_h = null();
707 handle h = abs.root;
708
709 if (st & LESS)
710 target_cmp = 1;
711 else if (st & GREATER)
712 target_cmp = -1;
713 else
714 target_cmp = 0;
715
716 while (h != null()) {
717 cmp = cmp_k_n(k, h);
718 if (cmp == 0) {
719 if (st & EQUAL) {
720 match_h = h;
721 break;
722 }
723 cmp = -target_cmp;
724 } else if (target_cmp != 0) {
725 if (!((cmp ^ target_cmp) & MASK_HIGH_BIT)) {
726 // cmp and target_cmp are both positive or both negative.
727 match_h = h;
728 }
729 }
730 h = cmp < 0 ? get_lt(h) : get_gt(h);
731 }
732
733 return match_h;
734 }
735
736 template <class Abstractor, unsigned maxDepth, class BSet>
737 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
738 AVLTree<Abstractor, maxDepth, BSet>::search_least() {
739 handle h = abs.root, parent = null();
740
741 while (h != null()) {
742 parent = h;
743 h = get_lt(h);
744 }
745
746 return parent;
747 }
748
749 template <class Abstractor, unsigned maxDepth, class BSet>
750 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
751 AVLTree<Abstractor, maxDepth, BSet>::search_greatest() {
752 handle h = abs.root, parent = null();
753
754 while (h != null()) {
755 parent = h;
756 h = get_gt(h);
757 }
758
759 return parent;
760 }
761
762 template <class Abstractor, unsigned maxDepth, class BSet>
763 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
764 AVLTree<Abstractor, maxDepth, BSet>::remove(key k) {
765 // Zero-based depth in tree.
766 unsigned depth = 0, rm_depth;
767
768 // Records a path into the tree. If branch[n] is true, indicates
769 // take greater branch from the nth node in the path, otherwise
770 // take the less branch. branch[0] gives branch from root, and
771 // so on.
772 BSet branch;
773
774 handle h = abs.root;
775 handle parent = null(), child;
776 int cmp, cmp_shortened_sub_with_path = 0;
777
778 for (;;) {
779 if (h == null()) {
780 // No node in tree with given key.
781 return null();
782 }
783 cmp = cmp_k_n(k, h);
784 if (cmp == 0) {
785 // Found node to remove.
786 break;
787 }
788 parent = h;
789 h = cmp < 0 ? get_lt(h) : get_gt(h);
790 branch[depth++] = cmp > 0;
791 cmp_shortened_sub_with_path = cmp;
792 }
793 handle rm = h;
794 handle parent_rm = parent;
795 rm_depth = depth;
796
797 // If the node to remove is not a leaf node, we need to get a
798 // leaf node, or a node with a single leaf as its child, to put
799 // in the place of the node to remove. We will get the greatest
800 // node in the less subtree (of the node to remove), or the least
801 // node in the greater subtree. We take the leaf node from the
802 // deeper subtree, if there is one.
803
804 if (get_bf(h) < 0) {
805 child = get_lt(h);
806 branch[depth] = false;
807 cmp = -1;
808 } else {
809 child = get_gt(h);
810 branch[depth] = true;
811 cmp = 1;
812 }
813 depth++;
814
815 if (child != null()) {
816 cmp = -cmp;
817 do {
818 parent = h;
819 h = child;
820 if (cmp < 0) {
821 child = get_lt(h);
822 branch[depth] = false;
823 } else {
824 child = get_gt(h);
825 branch[depth] = true;
826 }
827 depth++;
828 } while (child != null());
829
830 if (parent == rm) {
831 // Only went through do loop once. Deleted node will be replaced
832 // in the tree structure by one of its immediate children.
833 cmp_shortened_sub_with_path = -cmp;
834 } else {
835 cmp_shortened_sub_with_path = cmp;
836 }
837
838 // Get the handle of the opposite child, which may not be null.
839 child = cmp > 0 ? get_lt(h) : get_gt(h);
840 }
841
842 if (parent == null()) {
843 // There were only 1 or 2 nodes in this tree.
844 abs.root = child;
845 } else if (cmp_shortened_sub_with_path < 0) {
846 set_lt(parent, child);
847 } else {
848 set_gt(parent, child);
849 }
850
851 // "path" is the parent of the subtree being eliminated or reduced
852 // from a depth of 2 to 1. If "path" is the node to be removed, we
853 // set path to the node we're about to poke into the position of the
854 // node to be removed.
855 handle path = parent == rm ? h : parent;
856
857 if (h != rm) {
858 // Poke in the replacement for the node to be removed.
859 set_lt(h, get_lt(rm));
860 set_gt(h, get_gt(rm));
861 set_bf(h, get_bf(rm));
862 if (parent_rm == null()) {
863 abs.root = h;
864 } else {
865 depth = rm_depth - 1;
866 if (branch[depth])
867 set_gt(parent_rm, h);
868 else
869 set_lt(parent_rm, h);
870 }
871 }
872
873 if (path != null()) {
874 // Create a temporary linked list from the parent of the path node
875 // to the root node.
876 h = abs.root;
877 parent = null();
878 depth = 0;
879 while (h != path) {
880 if (branch[depth++]) {
881 child = get_gt(h);
882 set_gt(h, parent);
883 } else {
884 child = get_lt(h);
885 set_lt(h, parent);
886 }
887 parent = h;
888 h = child;
889 }
890
891 // Climb from the path node to the root node using the linked
892 // list, restoring the tree structure and rebalancing as necessary.
893 bool reduced_depth = true;
894 int bf;
895 cmp = cmp_shortened_sub_with_path;
896 for (;;) {
897 if (reduced_depth) {
898 bf = get_bf(h);
899 if (cmp < 0)
900 bf++;
901 else // cmp > 0
902 bf--;
903 if ((bf == -2) || (bf == 2)) {
904 h = balance(h);
905 bf = get_bf(h);
906 } else {
907 set_bf(h, bf);
908 }
909 reduced_depth = (bf == 0);
910 }
911 if (parent == null())
912 break;
913 child = h;
914 h = parent;
915 cmp = branch[--depth] ? 1 : -1;
916 if (cmp < 0) {
917 parent = get_lt(h);
918 set_lt(h, child);
919 } else {
920 parent = get_gt(h);
921 set_gt(h, child);
922 }
923 }
924 abs.root = h;
925 }
926
927 return rm;
928 }
929
930 template <class Abstractor, unsigned maxDepth, class BSet>
931 inline typename AVLTree<Abstractor, maxDepth, BSet>::handle
932 AVLTree<Abstractor, maxDepth, BSet>::subst(handle new_node) {
933 handle h = abs.root;
934 handle parent = null();
935 int cmp, last_cmp;
936
937 // Search for node already in tree with same key.
938 for (;;) {
939 if (h == null()) {
940 // No node in tree with same key as new node.
941 return null();
942 }
943 cmp = cmp_n_n(new_node, h);
944 if (cmp == 0) {
945 // Found the node to substitute new one for.
946 break;
947 }
948 last_cmp = cmp;
949 parent = h;
950 h = cmp < 0 ? get_lt(h) : get_gt(h);
951 }
952
953 // Copy tree housekeeping fields from node in tree to new node.
954 set_lt(new_node, get_lt(h));
955 set_gt(new_node, get_gt(h));
956 set_bf(new_node, get_bf(h));
957
958 if (parent == null()) {
959 // New node is also new root.
960 abs.root = new_node;
961 } else {
962 // Make parent point to new node.
963 if (last_cmp < 0)
964 set_lt(parent, new_node);
965 else
966 set_gt(parent, new_node);
967 }
968
969 return h;
970 }
971
972 } // namespace content
973
974 #endif // CONTENT_BROWSER_INDEXED_DB_LEVELDB_AVLTREE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698