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 namespace v8 { 32 namespace internal { 33 34 35 // A splay tree. The config type parameter encapsulates the different 36 // configurations of a concrete splay tree: 37 // 38 // typedef Key: the key type 39 // typedef Value: the value type 40 // static const kNoKey: the dummy key used when no key is set 41 // static const kNoValue: the dummy value used to initialize nodes 42 // int (Compare)(Key& a, Key& b) -> {-1, 0, 1}: comparison function 43 // 44 // The tree is also parameterized by an allocation policy 45 // (Allocator). The policy is used for allocating lists in the C free 46 // store or the zone; see zone.h. 47 48 // Forward defined as 49 // template <typename Config, class Allocator = FreeStoreAllocationPolicy> 50 // class SplayTree; 51 template <typename Config, class Allocator> 52 class SplayTree { 53 public: 54 typedef typename Config::Key Key; 55 typedef typename Config::Value Value; 56 57 class Locator; 58 59 SplayTree() : root_(NULL) { } 60 ~SplayTree(); 61 62 INLINE(void* operator new(size_t size)) { 63 return Allocator::New(static_cast<int>(size)); 64 } 65 INLINE(void operator delete(void* p, size_t)) { return Allocator::Delete(p); } 66 67 // Inserts the given key in this tree with the given value. Returns 68 // true if a node was inserted, otherwise false. If found the locator 69 // is enabled and provides access to the mapping for the key. 70 bool Insert(const Key& key, Locator* locator); 71 72 // Looks up the key in this tree and returns true if it was found, 73 // otherwise false. If the node is found the locator is enabled and 74 // provides access to the mapping for the key. 75 bool Find(const Key& key, Locator* locator); 76 77 // Finds the mapping with the greatest key less than or equal to the 78 // given key. 79 bool FindGreatestLessThan(const Key& key, Locator* locator); 80 81 // Find the mapping with the greatest key in this tree. 82 bool FindGreatest(Locator* locator); 83 84 // Finds the mapping with the least key greater than or equal to the 85 // given key. 86 bool FindLeastGreaterThan(const Key& key, Locator* locator); 87 88 // Find the mapping with the least key in this tree. 89 bool FindLeast(Locator* locator); 90 91 // Move the node from one key to another. 92 bool Move(const Key& old_key, const Key& new_key); 93 94 // Remove the node with the given key from the tree. 95 bool Remove(const Key& key); 96 97 bool is_empty() { return root_ == NULL; } 98 99 // Perform the splay operation for the given key. Moves the node with 100 // the given key to the top of the tree. If no node has the given 101 // key, the last node on the search path is moved to the top of the 102 // tree. 103 void Splay(const Key& key); 104 105 class Node { 106 public: 107 Node(const Key& key, const Value& value) 108 : key_(key), 109 value_(value), 110 left_(NULL), 111 right_(NULL) { } 112 113 INLINE(void* operator new(size_t size)) { 114 return Allocator::New(static_cast<int>(size)); 115 } 116 INLINE(void operator delete(void* p, size_t)) { 117 return Allocator::Delete(p); 118 } 119 120 Key key() { return key_; } 121 Value value() { return value_; } 122 Node* left() { return left_; } 123 Node* right() { return right_; } 124 private: 125 126 friend class SplayTree; 127 friend class Locator; 128 Key key_; 129 Value value_; 130 Node* left_; 131 Node* right_; 132 }; 133 134 // A locator provides access to a node in the tree without actually 135 // exposing the node. 136 class Locator BASE_EMBEDDED { 137 public: 138 explicit Locator(Node* node) : node_(node) { } 139 Locator() : node_(NULL) { } 140 const Key& key() { return node_->key_; } 141 Value& value() { return node_->value_; } 142 void set_value(const Value& value) { node_->value_ = value; } 143 inline void bind(Node* node) { node_ = node; } 144 private: 145 Node* node_; 146 }; 147 148 template <class Callback> 149 void ForEach(Callback* callback); 150 151 protected: 152 153 // Resets tree root. Existing nodes become unreachable. 154 void ResetRoot() { root_ = NULL; } 155 156 private: 157 // Search for a node with a given key. If found, root_ points 158 // to the node. 159 bool FindInternal(const Key& key); 160 161 // Inserts a node assuming that root_ is already set up. 162 void InsertInternal(int cmp, Node* node); 163 164 // Removes root_ node. 165 void RemoveRootNode(const Key& key); 166 167 template<class Callback> 168 class NodeToPairAdaptor BASE_EMBEDDED { 169 public: 170 explicit NodeToPairAdaptor(Callback* callback) 171 : callback_(callback) { } 172 void Call(Node* node) { 173 callback_->Call(node->key(), node->value()); 174 } 175 176 private: 177 Callback* callback_; 178 179 DISALLOW_COPY_AND_ASSIGN(NodeToPairAdaptor); 180 }; 181 182 class NodeDeleter BASE_EMBEDDED { 183 public: 184 NodeDeleter() { } 185 void Call(Node* node) { delete node; } 186 187 private: 188 189 DISALLOW_COPY_AND_ASSIGN(NodeDeleter); 190 }; 191 192 template <class Callback> 193 void ForEachNode(Callback* callback); 194 195 Node* root_; 196 197 DISALLOW_COPY_AND_ASSIGN(SplayTree); 198 }; 199 200 201 } } // namespace v8::internal 202 203 #endif // V8_SPLAY_TREE_H_ 204