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