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