1 // Copyright 2010 the V8 project 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 #ifndef V8_SPLAY_TREE_H_ 6 #define V8_SPLAY_TREE_H_ 7 8 #include "src/allocation.h" 9 10 namespace v8 { 11 namespace internal { 12 13 14 // A splay tree. The config type parameter encapsulates the different 15 // configurations of a concrete splay tree: 16 // 17 // typedef Key: the key type 18 // typedef Value: the value type 19 // static const Key kNoKey: the dummy key used when no key is set 20 // static Value kNoValue(): the dummy value used to initialize nodes 21 // static int (Compare)(Key& a, Key& b) -> {-1, 0, 1}: comparison function 22 // 23 // The tree is also parameterized by an allocation policy 24 // (Allocator). The policy is used for allocating lists in the C free 25 // store or the zone; see zone.h. 26 27 // Forward defined as 28 // template <typename Config, class Allocator = FreeStoreAllocationPolicy> 29 // class SplayTree; 30 template <typename Config, class AllocationPolicy> 31 class SplayTree { 32 public: 33 typedef typename Config::Key Key; 34 typedef typename Config::Value Value; 35 36 class Locator; 37 38 SplayTree(AllocationPolicy allocator = AllocationPolicy()) root_(NULL)39 : root_(NULL), allocator_(allocator) { } 40 ~SplayTree(); 41 42 INLINE(void* operator new(size_t size, 43 AllocationPolicy allocator = AllocationPolicy())) { 44 return allocator.New(static_cast<int>(size)); 45 } INLINE(void operator delete (void * p))46 INLINE(void operator delete(void* p)) { 47 AllocationPolicy::Delete(p); 48 } 49 // Please the MSVC compiler. We should never have to execute this. INLINE(void operator delete (void * p,AllocationPolicy policy))50 INLINE(void operator delete(void* p, AllocationPolicy policy)) { 51 UNREACHABLE(); 52 } 53 allocator()54 AllocationPolicy allocator() { return allocator_; } 55 56 // Checks if there is a mapping for the key. 57 bool Contains(const Key& key); 58 59 // Inserts the given key in this tree with the given value. Returns 60 // true if a node was inserted, otherwise false. If found the locator 61 // is enabled and provides access to the mapping for the key. 62 bool Insert(const Key& key, Locator* locator); 63 64 // Looks up the key in this tree and returns true if it was found, 65 // otherwise false. If the node is found the locator is enabled and 66 // provides access to the mapping for the key. 67 bool Find(const Key& key, Locator* locator); 68 69 // Finds the mapping with the greatest key less than or equal to the 70 // given key. 71 bool FindGreatestLessThan(const Key& key, Locator* locator); 72 73 // Find the mapping with the greatest key in this tree. 74 bool FindGreatest(Locator* locator); 75 76 // Finds the mapping with the least key greater than or equal to the 77 // given key. 78 bool FindLeastGreaterThan(const Key& key, Locator* locator); 79 80 // Find the mapping with the least key in this tree. 81 bool FindLeast(Locator* locator); 82 83 // Move the node from one key to another. 84 bool Move(const Key& old_key, const Key& new_key); 85 86 // Remove the node with the given key from the tree. 87 bool Remove(const Key& key); 88 89 // Remove all keys from the tree. Clear()90 void Clear() { ResetRoot(); } 91 is_empty()92 bool is_empty() { return root_ == NULL; } 93 94 // Perform the splay operation for the given key. Moves the node with 95 // the given key to the top of the tree. If no node has the given 96 // key, the last node on the search path is moved to the top of the 97 // tree. 98 void Splay(const Key& key); 99 100 class Node { 101 public: Node(const Key & key,const Value & value)102 Node(const Key& key, const Value& value) 103 : key_(key), 104 value_(value), 105 left_(NULL), 106 right_(NULL) { } 107 INLINE(void * operator new (size_t size,AllocationPolicy allocator))108 INLINE(void* operator new(size_t size, AllocationPolicy allocator)) { 109 return allocator.New(static_cast<int>(size)); 110 } INLINE(void operator delete (void * p))111 INLINE(void operator delete(void* p)) { 112 return AllocationPolicy::Delete(p); 113 } 114 // Please the MSVC compiler. We should never have to execute 115 // this. INLINE(void operator delete (void * p,AllocationPolicy allocator))116 INLINE(void operator delete(void* p, AllocationPolicy allocator)) { 117 UNREACHABLE(); 118 } 119 key()120 Key key() { return key_; } value()121 Value value() { return value_; } left()122 Node* left() { return left_; } right()123 Node* right() { return right_; } 124 125 private: 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: Locator(Node * node)138 explicit Locator(Node* node) : node_(node) { } Locator()139 Locator() : node_(NULL) { } key()140 const Key& key() { return node_->key_; } value()141 Value& value() { return node_->value_; } set_value(const Value & value)142 void set_value(const Value& value) { node_->value_ = value; } bind(Node * node)143 inline void bind(Node* node) { node_ = node; } 144 145 private: 146 Node* node_; 147 }; 148 149 template <class Callback> 150 void ForEach(Callback* callback); 151 152 protected: 153 // Resets tree root. Existing nodes become unreachable. ResetRoot()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: NodeToPairAdaptor(Callback * callback)170 explicit NodeToPairAdaptor(Callback* callback) 171 : callback_(callback) { } Call(Node * node)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: NodeDeleter()184 NodeDeleter() { } Call(Node * node)185 void Call(Node* node) { AllocationPolicy::Delete(node); } 186 187 private: 188 DISALLOW_COPY_AND_ASSIGN(NodeDeleter); 189 }; 190 191 template <class Callback> 192 void ForEachNode(Callback* callback); 193 194 Node* root_; 195 AllocationPolicy allocator_; 196 197 DISALLOW_COPY_AND_ASSIGN(SplayTree); 198 }; 199 200 201 } } // namespace v8::internal 202 203 #endif // V8_SPLAY_TREE_H_ 204