1 // Copyright 2010 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_SPLAY_TREE_H_ 29 #define V8_SPLAY_TREE_H_ 30 31 #include "allocation.h" 32 33 namespace v8 { 34 namespace internal { 35 36 37 // A splay tree. The config type parameter encapsulates the different 38 // configurations of a concrete splay tree: 39 // 40 // typedef Key: the key type 41 // typedef Value: the value type 42 // static const kNoKey: the dummy key used when no key is set 43 // static const kNoValue: the dummy value used to initialize nodes 44 // int (Compare)(Key& a, Key& b) -> {-1, 0, 1}: comparison function 45 // 46 // The tree is also parameterized by an allocation policy 47 // (Allocator). The policy is used for allocating lists in the C free 48 // store or the zone; see zone.h. 49 50 // Forward defined as 51 // template <typename Config, class Allocator = FreeStoreAllocationPolicy> 52 // class SplayTree; 53 template <typename Config, class Allocator> 54 class SplayTree { 55 public: 56 typedef typename Config::Key Key; 57 typedef typename Config::Value Value; 58 59 class Locator; 60 SplayTree()61 SplayTree() : root_(NULL) { } 62 ~SplayTree(); 63 INLINE(void * operator new (size_t size))64 INLINE(void* operator new(size_t size)) { 65 return Allocator::New(static_cast<int>(size)); 66 } INLINE(void operator delete (void * p,size_t))67 INLINE(void operator delete(void* p, size_t)) { return Allocator::Delete(p); } 68 69 // Inserts the given key in this tree with the given value. Returns 70 // true if a node was inserted, otherwise false. If found the locator 71 // is enabled and provides access to the mapping for the key. 72 bool Insert(const Key& key, Locator* locator); 73 74 // Looks up the key in this tree and returns true if it was found, 75 // otherwise false. If the node is found the locator is enabled and 76 // provides access to the mapping for the key. 77 bool Find(const Key& key, Locator* locator); 78 79 // Finds the mapping with the greatest key less than or equal to the 80 // given key. 81 bool FindGreatestLessThan(const Key& key, Locator* locator); 82 83 // Find the mapping with the greatest key in this tree. 84 bool FindGreatest(Locator* locator); 85 86 // Finds the mapping with the least key greater than or equal to the 87 // given key. 88 bool FindLeastGreaterThan(const Key& key, Locator* locator); 89 90 // Find the mapping with the least key in this tree. 91 bool FindLeast(Locator* locator); 92 93 // Move the node from one key to another. 94 bool Move(const Key& old_key, const Key& new_key); 95 96 // Remove the node with the given key from the tree. 97 bool Remove(const Key& key); 98 is_empty()99 bool is_empty() { return root_ == NULL; } 100 101 // Perform the splay operation for the given key. Moves the node with 102 // the given key to the top of the tree. If no node has the given 103 // key, the last node on the search path is moved to the top of the 104 // tree. 105 void Splay(const Key& key); 106 107 class Node { 108 public: Node(const Key & key,const Value & value)109 Node(const Key& key, const Value& value) 110 : key_(key), 111 value_(value), 112 left_(NULL), 113 right_(NULL) { } 114 INLINE(void * operator new (size_t size))115 INLINE(void* operator new(size_t size)) { 116 return Allocator::New(static_cast<int>(size)); 117 } INLINE(void operator delete (void * p,size_t))118 INLINE(void operator delete(void* p, size_t)) { 119 return Allocator::Delete(p); 120 } 121 key()122 Key key() { return key_; } value()123 Value value() { return value_; } left()124 Node* left() { return left_; } right()125 Node* right() { return right_; } 126 127 private: 128 friend class SplayTree; 129 friend class Locator; 130 Key key_; 131 Value value_; 132 Node* left_; 133 Node* right_; 134 }; 135 136 // A locator provides access to a node in the tree without actually 137 // exposing the node. 138 class Locator BASE_EMBEDDED { 139 public: Locator(Node * node)140 explicit Locator(Node* node) : node_(node) { } Locator()141 Locator() : node_(NULL) { } key()142 const Key& key() { return node_->key_; } value()143 Value& value() { return node_->value_; } set_value(const Value & value)144 void set_value(const Value& value) { node_->value_ = value; } bind(Node * node)145 inline void bind(Node* node) { node_ = node; } 146 147 private: 148 Node* node_; 149 }; 150 151 template <class Callback> 152 void ForEach(Callback* callback); 153 154 protected: 155 // Resets tree root. Existing nodes become unreachable. ResetRoot()156 void ResetRoot() { root_ = NULL; } 157 158 private: 159 // Search for a node with a given key. If found, root_ points 160 // to the node. 161 bool FindInternal(const Key& key); 162 163 // Inserts a node assuming that root_ is already set up. 164 void InsertInternal(int cmp, Node* node); 165 166 // Removes root_ node. 167 void RemoveRootNode(const Key& key); 168 169 template<class Callback> 170 class NodeToPairAdaptor BASE_EMBEDDED { 171 public: NodeToPairAdaptor(Callback * callback)172 explicit NodeToPairAdaptor(Callback* callback) 173 : callback_(callback) { } Call(Node * node)174 void Call(Node* node) { 175 callback_->Call(node->key(), node->value()); 176 } 177 178 private: 179 Callback* callback_; 180 181 DISALLOW_COPY_AND_ASSIGN(NodeToPairAdaptor); 182 }; 183 184 class NodeDeleter BASE_EMBEDDED { 185 public: NodeDeleter()186 NodeDeleter() { } Call(Node * node)187 void Call(Node* node) { delete node; } 188 189 private: 190 DISALLOW_COPY_AND_ASSIGN(NodeDeleter); 191 }; 192 193 template <class Callback> 194 void ForEachNode(Callback* callback); 195 196 Node* root_; 197 198 DISALLOW_COPY_AND_ASSIGN(SplayTree); 199 }; 200 201 202 } } // namespace v8::internal 203 204 #endif // V8_SPLAY_TREE_H_ 205