16ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Copyright 2010 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 46ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 56ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifndef V8_SPLAY_TREE_INL_H_ 66ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#define V8_SPLAY_TREE_INL_H_ 76ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/splay-tree.h" 96ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 106ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace v8 { 116ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocknamespace internal { 126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 146ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 156ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockSplayTree<Config, Allocator>::~SplayTree() { 166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block NodeDeleter deleter; 176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ForEachNode(&deleter); 186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 216ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool SplayTree<Config, Allocator>::Insert(const Key& key, 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Locator* locator) { 246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (is_empty()) { 256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // If the tree is empty, insert the new node. 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch root_ = new(allocator_) Node(key, Config::NoValue()); 276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Splay on the key to move the last node on the search path 296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // for the key to the root of the tree. 306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Splay(key); 316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Ignore repeated insertions with the same key. 326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int cmp = Config::Compare(key, root_->key_); 336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (cmp == 0) { 346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block locator->bind(root_); 356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Insert the new node. 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* node = new(allocator_) Node(key, Config::NoValue()); 396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block InsertInternal(cmp, node); 406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block locator->bind(root_); 426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 466ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 476ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid SplayTree<Config, Allocator>::InsertInternal(int cmp, Node* node) { 486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (cmp > 0) { 496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block node->left_ = root_; 506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block node->right_ = root_->right_; 516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_->right_ = NULL; 526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block node->right_ = root_; 546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block node->left_ = root_->left_; 556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_->left_ = NULL; 566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_ = node; 586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 616ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 626ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool SplayTree<Config, Allocator>::FindInternal(const Key& key) { 636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (is_empty()) 646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Splay(key); 666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Config::Compare(key, root_->key_) == 0; 676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 706ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool SplayTree<Config, Allocator>::Contains(const Key& key) { 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FindInternal(key); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename Config, class Allocator> 776ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool SplayTree<Config, Allocator>::Find(const Key& key, Locator* locator) { 786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (FindInternal(key)) { 796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block locator->bind(root_); 806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 876ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 886ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool SplayTree<Config, Allocator>::FindGreatestLessThan(const Key& key, 896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Locator* locator) { 906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (is_empty()) 916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Splay on the key to move the node with the given key or the last 936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // node on the search path to the top of the tree. 946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Splay(key); 956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Now the result is either the root node or the greatest node in 966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // the left subtree. 976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int cmp = Config::Compare(root_->key_, key); 986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (cmp <= 0) { 996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block locator->bind(root_); 1006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 1016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 1026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* temp = root_; 1036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_ = root_->left_; 1046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool result = FindGreatest(locator); 1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_ = temp; 1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1116ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool SplayTree<Config, Allocator>::FindLeastGreaterThan(const Key& key, 1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Locator* locator) { 1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (is_empty()) 1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Splay on the key to move the node with the given key or the last 1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // node on the search path to the top of the tree. 1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Splay(key); 1196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Now the result is either the root node or the least node in 1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // the right subtree. 1216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int cmp = Config::Compare(root_->key_, key); 1226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (cmp >= 0) { 1236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block locator->bind(root_); 1246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 1256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 1266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* temp = root_; 1276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_ = root_->right_; 1286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bool result = FindLeast(locator); 1296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_ = temp; 1306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 1316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1356ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool SplayTree<Config, Allocator>::FindGreatest(Locator* locator) { 1376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (is_empty()) 1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 1396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* current = root_; 1406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block while (current->right_ != NULL) 1416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current = current->right_; 1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block locator->bind(current); 1436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool SplayTree<Config, Allocator>::FindLeast(Locator* locator) { 1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (is_empty()) 1506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 1516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* current = root_; 1526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block while (current->left_ != NULL) 1536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current = current->left_; 1546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block locator->bind(current); 1556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 1566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 1576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1596ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 1606ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool SplayTree<Config, Allocator>::Move(const Key& old_key, 1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const Key& new_key) { 1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!FindInternal(old_key)) 1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* node_to_move = root_; 1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block RemoveRootNode(old_key); 1666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Splay(new_key); 1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int cmp = Config::Compare(new_key, root_->key_); 1686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (cmp == 0) { 1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // A node with the target key already exists. 1706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block delete node_to_move; 1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block node_to_move->key_ = new_key; 1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block InsertInternal(cmp, node_to_move); 1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1796ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 1806ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool SplayTree<Config, Allocator>::Remove(const Key& key) { 1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!FindInternal(key)) 1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return false; 1836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* node_to_remove = root_; 1846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block RemoveRootNode(key); 1856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block delete node_to_remove; 1866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return true; 1876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 1886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1906ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 1916ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid SplayTree<Config, Allocator>::RemoveRootNode(const Key& key) { 1926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (root_->left_ == NULL) { 1936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // No left child, so the new tree is just the right child. 1946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_ = root_->right_; 1956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 1966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Left child exists. 1976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* right = root_->right_; 1986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Make the original left child the new root. 1996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_ = root_->left_; 2006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Splay to make sure that the new root has an empty right child. 2016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Splay(key); 2026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Insert the original right child as the right child of the new 2036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // root. 2046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_->right_ = right; 2056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2096ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate<typename Config, class Allocator> 2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid SplayTree<Config, Allocator>::Splay(const Key& key) { 2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (is_empty()) 2126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return; 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Node dummy_node(Config::kNoKey, Config::NoValue()); 2146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Create a dummy node. The use of the dummy node is a bit 2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // counter-intuitive: The right child of the dummy node will hold 2166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // the L tree of the algorithm. The left child of the dummy node 2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // will hold the R tree of the algorithm. Using a dummy node, left 2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // and right will always be nodes and we avoid special cases. 2196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* dummy = &dummy_node; 2206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* left = dummy; 2216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* right = dummy; 2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* current = root_; 2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block while (true) { 2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int cmp = Config::Compare(key, current->key_); 2256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (cmp < 0) { 2266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (current->left_ == NULL) 2276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block break; 2286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (Config::Compare(key, current->left_->key_) < 0) { 2296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Rotate right. 2306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* temp = current->left_; 2316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current->left_ = temp->right_; 2326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block temp->right_ = current; 2336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current = temp; 2346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (current->left_ == NULL) 2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block break; 2366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Link right. 2386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block right->left_ = current; 2396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block right = current; 2406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current = current->left_; 2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (cmp > 0) { 2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (current->right_ == NULL) 2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block break; 2446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (Config::Compare(key, current->right_->key_) > 0) { 2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Rotate left. 2466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* temp = current->right_; 2476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current->right_ = temp->left_; 2486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block temp->left_ = current; 2496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current = temp; 2506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (current->right_ == NULL) 2516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block break; 2526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Link left. 2546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block left->right_ = current; 2556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block left = current; 2566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current = current->right_; 2576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block break; 2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Assemble. 2626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block left->right_ = current->left_; 2636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block right->left_ = current->right_; 2646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current->left_ = dummy->right_; 2656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block current->right_ = dummy->left_; 2666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block root_ = current; 2676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate <typename Config, class Allocator> template <class Callback> 2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid SplayTree<Config, Allocator>::ForEach(Callback* callback) { 2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block NodeToPairAdaptor<Callback> callback_adaptor(callback); 2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ForEachNode(&callback_adaptor); 2746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2776ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate <typename Config, class Allocator> template <class Callback> 2786ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid SplayTree<Config, Allocator>::ForEachNode(Callback* callback) { 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_ == NULL) return; 2806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Pre-allocate some space for tiny trees. 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<Node*, Allocator> nodes_to_visit(10, allocator_); 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch nodes_to_visit.Add(root_, allocator_); 2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int pos = 0; 2846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block while (pos < nodes_to_visit.length()) { 2856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Node* node = nodes_to_visit[pos++]; 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (node->left() != NULL) nodes_to_visit.Add(node->left(), allocator_); 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (node->right() != NULL) nodes_to_visit.Add(node->right(), allocator_); 2886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block callback->Call(node); 2896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 2916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 2956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif // V8_SPLAY_TREE_INL_H_ 297