blob: bee8429e39d82494d853ee423eedb156162c43cc [file] [log] [blame]
Steve Block6ded16b2010-05-10 14:33:55 +01001// Copyright 2010 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Block6ded16b2010-05-10 14:33:55 +01004
5#ifndef V8_SPLAY_TREE_H_
6#define V8_SPLAY_TREE_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/allocation.h"
Ben Murdoch257744e2011-11-30 15:57:28 +00009
Steve Block6ded16b2010-05-10 14:33:55 +010010namespace v8 {
11namespace 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019// 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
Steve Block6ded16b2010-05-10 14:33:55 +010022//
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;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030template <typename Config, class AllocationPolicy>
Steve Block6ded16b2010-05-10 14:33:55 +010031class SplayTree {
32 public:
33 typedef typename Config::Key Key;
34 typedef typename Config::Value Value;
35
36 class Locator;
37
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038 explicit SplayTree(AllocationPolicy allocator = AllocationPolicy())
39 : root_(NULL), allocator_(allocator) {}
Steve Block6ded16b2010-05-10 14:33:55 +010040 ~SplayTree();
41
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042 INLINE(void* operator new(size_t size,
43 AllocationPolicy allocator = AllocationPolicy())) {
44 return allocator.New(static_cast<int>(size));
Steve Block6ded16b2010-05-10 14:33:55 +010045 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046 INLINE(void operator delete(void* p)) {
47 AllocationPolicy::Delete(p);
48 }
49 // Please the MSVC compiler. We should never have to execute this.
50 INLINE(void operator delete(void* p, AllocationPolicy policy)) {
51 UNREACHABLE();
52 }
53
54 AllocationPolicy allocator() { return allocator_; }
55
56 // Checks if there is a mapping for the key.
57 bool Contains(const Key& key);
Steve Block6ded16b2010-05-10 14:33:55 +010058
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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000089 // Remove all keys from the tree.
90 void Clear() { ResetRoot(); }
91
Steve Block6ded16b2010-05-10 14:33:55 +010092 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:
102 Node(const Key& key, const Value& value)
103 : key_(key),
104 value_(value),
105 left_(NULL),
106 right_(NULL) { }
107
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000108 INLINE(void* operator new(size_t size, AllocationPolicy allocator)) {
109 return allocator.New(static_cast<int>(size));
Steve Block6ded16b2010-05-10 14:33:55 +0100110 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 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.
116 INLINE(void operator delete(void* p, AllocationPolicy allocator)) {
117 UNREACHABLE();
Steve Block6ded16b2010-05-10 14:33:55 +0100118 }
119
120 Key key() { return key_; }
121 Value value() { return value_; }
122 Node* left() { return left_; }
123 Node* right() { return right_; }
Steve Block6ded16b2010-05-10 14:33:55 +0100124
Ben Murdoch589d6972011-11-30 16:04:58 +0000125 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100126 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; }
Ben Murdoch589d6972011-11-30 16:04:58 +0000144
Steve Block6ded16b2010-05-10 14:33:55 +0100145 private:
146 Node* node_;
147 };
148
149 template <class Callback>
150 void ForEach(Callback* callback);
151
152 protected:
Steve Block6ded16b2010-05-10 14:33:55 +0100153 // 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() { }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185 void Call(Node* node) { AllocationPolicy::Delete(node); }
Steve Block6ded16b2010-05-10 14:33:55 +0100186
187 private:
Steve Block6ded16b2010-05-10 14:33:55 +0100188 DISALLOW_COPY_AND_ASSIGN(NodeDeleter);
189 };
190
191 template <class Callback>
192 void ForEachNode(Callback* callback);
193
194 Node* root_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000195 AllocationPolicy allocator_;
Steve Block6ded16b2010-05-10 14:33:55 +0100196
197 DISALLOW_COPY_AND_ASSIGN(SplayTree);
198};
199
200
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201} // namespace internal
202} // namespace v8
Steve Block6ded16b2010-05-10 14:33:55 +0100203
204#endif // V8_SPLAY_TREE_H_