OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.collection; | 5 part of dart.collection; |
6 | 6 |
7 /** | 7 /** |
8 * A node in a splay tree. It holds the key, the value and the left | 8 * A node in a splay tree. It holds the sorting key and the left |
9 * and right children in the tree. | 9 * and right children in the tree. |
10 */ | 10 */ |
11 class SplayTreeNode<K, V> { | 11 class _SplayTreeNode<K> { |
12 final K key; | 12 final K key; |
13 V value; | 13 _SplayTreeNode<K> left; |
14 SplayTreeNode<K, V> left; | 14 _SplayTreeNode<K> right; |
15 SplayTreeNode<K, V> right; | |
16 | 15 |
17 SplayTreeNode(K this.key, V this.value); | 16 _SplayTreeNode(K this.key); |
18 } | 17 } |
19 | 18 |
20 /** | 19 /** |
21 * A splay tree is a self-balancing binary | 20 * A node in a splay tree based map. |
22 * search tree with the additional property that recently accessed | |
23 * elements are quick to access again. It performs basic operations | |
24 * such as insertion, look-up and removal in O(log(n)) amortized time. | |
25 * | 21 * |
26 * This implementation is a Dart version of the JavaScript | 22 * A [_SplayTreeNode] that also contains a value |
27 * implementation in the V8 project. | |
28 */ | 23 */ |
29 class SplayTreeMap<K extends Comparable<K>, V> implements Map<K, V> { | 24 class _SplayTreeMapNode<K, V> extends _SplayTreeNode<K> { |
| 25 V value; |
| 26 _SplayTreeMapNode(K key, V this.value) : super(key); |
| 27 } |
30 | 28 |
| 29 /** |
| 30 * A splay tree is a self-balancing binary search tree. |
| 31 * |
| 32 * It has the additional property that recently accessed elements |
| 33 * are quick to access again. |
| 34 * It performs basic operations such as insertion, look-up and |
| 35 * removal, in O(log(n)) amortized time. |
| 36 */ |
| 37 abstract class _SplayTree<K> { |
31 // The root node of the splay tree. It will contain either the last | 38 // The root node of the splay tree. It will contain either the last |
32 // element inserted, or the last element looked up. | 39 // element inserted, or the last element looked up. |
33 SplayTreeNode<K, V> _root; | 40 _SplayTreeNode<K> _root; |
34 | 41 |
35 // The dummy node used when performing a splay on the tree. It is a | 42 // The dummy node used when performing a splay on the tree. It is a |
36 // local field of the class to avoid allocating a node each time a | 43 // local field of the class to avoid allocating a node each time a |
37 // splay is performed. | 44 // splay is performed. |
38 SplayTreeNode<K, V> _dummy; | 45 // TODO(lrn); Should it be a getter backed by a static instead? |
| 46 _SplayTreeNode<K> _dummy = new _SplayTreeNode<K>(null); |
39 | 47 |
40 // Number of elements in the splay tree. | 48 // Number of elements in the splay tree. |
41 int _count; | 49 int _count = 0; |
42 | 50 |
43 /** | 51 /** |
44 * Counter incremented whenever the keys in the map changes. | 52 * Counter incremented whenever the keys in the map changes. |
45 * | 53 * |
46 * Used to detect concurrent modifications. | 54 * Used to detect concurrent modifications. |
47 */ | 55 */ |
48 int _modificationCount = 0; | 56 int _modificationCount = 0; |
| 57 |
49 /** | 58 /** |
50 * Counter incremented whenever the tree structure changes. | 59 * Counter incremented whenever the tree structure changes. |
51 * | 60 * |
52 * Used to detect that an in-place traversal cannot use | 61 * Used to detect that an in-place traversal cannot use |
53 * cached information that relies on the tree structure. | 62 * cached information that relies on the tree structure. |
54 */ | 63 */ |
55 int _splayCount = 0; | 64 int _splayCount = 0; |
56 | 65 |
57 SplayTreeMap() : | 66 /** Comparison used to compare keys. */ |
58 _dummy = new SplayTreeNode<K, V>(null, null), | 67 int _compare(K key1, K key2); |
59 _count = 0; | |
60 | 68 |
61 /** | 69 /** |
62 * Perform the splay operation for the given key. Moves the node with | 70 * Perform the splay operation for the given key. Moves the node with |
63 * the given key to the top of the tree. If no node has the given | 71 * the given key to the top of the tree. If no node has the given |
64 * key, the last node on the search path is moved to the top of the | 72 * key, the last node on the search path is moved to the top of the |
65 * tree. This is the simplified top-down splaying algorithm from: | 73 * tree. This is the simplified top-down splaying algorithm from: |
66 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan. | 74 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan. |
67 * | 75 * |
68 * Returns the result of comparing the new root of the tree to [key]. | 76 * Returns the result of comparing the new root of the tree to [key]. |
69 * Returns -1 if the table is empty. | 77 * Returns -1 if the table is empty. |
70 */ | 78 */ |
71 int _splay(K key) { | 79 int _splay(K key) { |
72 if (_root == null) return -1; | 80 if (_root == null) return -1; |
73 | 81 |
74 // The right child of the dummy node will hold | 82 // The right child of the dummy node will hold |
75 // the L tree of the algorithm. The left child of the dummy node | 83 // the L tree of the algorithm. The left child of the dummy node |
76 // will hold the R tree of the algorithm. Using a dummy node, left | 84 // will hold the R tree of the algorithm. Using a dummy node, left |
77 // and right will always be nodes and we avoid special cases. | 85 // and right will always be nodes and we avoid special cases. |
78 SplayTreeNode<K, V> left = _dummy; | 86 _SplayTreeNode<K> left = _dummy; |
79 SplayTreeNode<K, V> right = _dummy; | 87 _SplayTreeNode<K> right = _dummy; |
80 SplayTreeNode<K, V> current = _root; | 88 _SplayTreeNode<K> current = _root; |
81 int comp; | 89 int comp; |
82 while (true) { | 90 while (true) { |
83 comp = current.key.compareTo(key); | 91 comp = current.key.compareTo(key); |
84 if (comp > 0) { | 92 if (comp > 0) { |
85 if (current.left == null) break; | 93 if (current.left == null) break; |
86 comp = current.left.key.compareTo(key); | 94 comp = current.left.key.compareTo(key); |
87 if (comp > 0) { | 95 if (comp > 0) { |
88 // Rotate right. | 96 // Rotate right. |
89 SplayTreeNode<K, V> tmp = current.left; | 97 _SplayTreeNode<K> tmp = current.left; |
90 current.left = tmp.right; | 98 current.left = tmp.right; |
91 tmp.right = current; | 99 tmp.right = current; |
92 current = tmp; | 100 current = tmp; |
93 if (current.left == null) break; | 101 if (current.left == null) break; |
94 } | 102 } |
95 // Link right. | 103 // Link right. |
96 right.left = current; | 104 right.left = current; |
97 right = current; | 105 right = current; |
98 current = current.left; | 106 current = current.left; |
99 } else if (comp < 0) { | 107 } else if (comp < 0) { |
100 if (current.right == null) break; | 108 if (current.right == null) break; |
101 comp = current.right.key.compareTo(key); | 109 comp = current.right.key.compareTo(key); |
102 if (comp < 0) { | 110 if (comp < 0) { |
103 // Rotate left. | 111 // Rotate left. |
104 SplayTreeNode<K, V> tmp = current.right; | 112 _SplayTreeNode<K> tmp = current.right; |
105 current.right = tmp.left; | 113 current.right = tmp.left; |
106 tmp.left = current; | 114 tmp.left = current; |
107 current = tmp; | 115 current = tmp; |
108 if (current.right == null) break; | 116 if (current.right == null) break; |
109 } | 117 } |
110 // Link left. | 118 // Link left. |
111 left.right = current; | 119 left.right = current; |
112 left = current; | 120 left = current; |
113 current = current.right; | 121 current = current.right; |
114 } else { | 122 } else { |
115 break; | 123 break; |
116 } | 124 } |
117 } | 125 } |
118 // Assemble. | 126 // Assemble. |
119 left.right = current.left; | 127 left.right = current.left; |
120 right.left = current.right; | 128 right.left = current.right; |
121 current.left = _dummy.right; | 129 current.left = _dummy.right; |
122 current.right = _dummy.left; | 130 current.right = _dummy.left; |
123 _root = current; | 131 _root = current; |
124 | 132 |
125 _dummy.right = null; | 133 _dummy.right = null; |
126 _dummy.left = null; | 134 _dummy.left = null; |
127 _splayCount++; | 135 _splayCount++; |
128 return comp; | 136 return comp; |
129 } | 137 } |
130 | 138 |
131 V operator [](K key) { | 139 _SplayTreeNode _remove(K key) { |
132 if (_root != null) { | |
133 int comp = _splay(key); | |
134 if (comp == 0) return _root.value; | |
135 } | |
136 return null; | |
137 } | |
138 | |
139 V remove(K key) { | |
140 if (_root == null) return null; | 140 if (_root == null) return null; |
141 int comp = _splay(key); | 141 int comp = _splay(key); |
142 if (comp != 0) return null; | 142 if (comp != 0) return null; |
143 V value = _root.value; | 143 _SplayTreeNode result = _root; |
144 | |
145 _count--; | 144 _count--; |
146 // assert(_count >= 0); | 145 // assert(_count >= 0); |
147 if (_root.left == null) { | 146 if (_root.left == null) { |
148 _root = _root.right; | 147 _root = _root.right; |
149 } else { | 148 } else { |
150 SplayTreeNode<K, V> right = _root.right; | 149 _SplayTreeNode<K> right = _root.right; |
151 _root = _root.left; | 150 _root = _root.left; |
152 // Splay to make sure that the new root has an empty right child. | 151 // Splay to make sure that the new root has an empty right child. |
153 _splay(key); | 152 _splay(key); |
154 // Insert the original right child as the right child of the new | 153 // Insert the original right child as the right child of the new |
155 // root. | 154 // root. |
156 _root.right = right; | 155 _root.right = right; |
157 } | 156 } |
158 _modificationCount++; | 157 _modificationCount++; |
159 return value; | 158 return result; |
160 } | |
161 | |
162 void operator []=(K key, V value) { | |
163 if (_root == null) { | |
164 _count++; | |
165 _root = new SplayTreeNode(key, value); | |
166 _modificationCount++; | |
167 return; | |
168 } | |
169 // Splay on the key to move the last node on the search path for | |
170 // the key to the root of the tree. | |
171 int comp = _splay(key); | |
172 if (comp == 0) { | |
173 _root.value = value; | |
174 return; | |
175 } | |
176 _addNewRoot(key, value, comp); | |
177 } | 159 } |
178 | 160 |
179 /** | 161 /** |
180 * Adds a new root node with the given [key] or [value]. | 162 * Adds a new root node with the given [key] or [value]. |
181 * | 163 * |
182 * The [comp] value is the result of comparing the existing root's key | 164 * The [comp] value is the result of comparing the existing root's key |
183 * with key. | 165 * with key. |
184 */ | 166 */ |
185 void _addNewRoot(K key, V value, int comp) { | 167 void _addNewRoot(_SplayTreeNode<K> node, int comp) { |
186 SplayTreeNode<K, V> node = new SplayTreeNode(key, value); | 168 _count++; |
| 169 _modificationCount++; |
| 170 if (_root == null) { |
| 171 _root = node; |
| 172 return; |
| 173 } |
187 // assert(_count >= 0); | 174 // assert(_count >= 0); |
188 _count++; | |
189 if (comp < 0) { | 175 if (comp < 0) { |
190 node.left = _root; | 176 node.left = _root; |
191 node.right = _root.right; | 177 node.right = _root.right; |
192 _root.right = null; | 178 _root.right = null; |
193 } else { | 179 } else { |
194 node.right = _root; | 180 node.right = _root; |
195 node.left = _root.left; | 181 node.left = _root.left; |
196 _root.left = null; | 182 _root.left = null; |
197 } | 183 } |
198 _root = node; | 184 _root = node; |
| 185 } |
| 186 |
| 187 _SplayTreeNode get _first { |
| 188 if (_root == null) return null; |
| 189 _SplayTreeNode<K> node = _root; |
| 190 while (node.left != null) { |
| 191 node = node.left; |
| 192 } |
| 193 // Maybe implement a splay-method that can splay the minimum without |
| 194 // performing comparisons. |
| 195 _splay(node.key); |
| 196 return node; |
| 197 } |
| 198 |
| 199 _SplayTreeNode get _last { |
| 200 if (_root == null) return null; |
| 201 _SplayTreeNode<K> node = _root; |
| 202 while (node.right != null) { |
| 203 node = node.right; |
| 204 } |
| 205 // Maybe implement a splay-method that can splay the minimum without |
| 206 // performing comparisons. |
| 207 _splay(node.key); |
| 208 return node; |
| 209 } |
| 210 |
| 211 void _clear() { |
| 212 _root = null; |
| 213 _count = 0; |
199 _modificationCount++; | 214 _modificationCount++; |
200 } | 215 } |
| 216 } |
| 217 |
| 218 /* |
| 219 * A [Map] of objects that can be ordered relative to each other. |
| 220 * |
| 221 * The map is based on a self-balancing binary tree. It allows most operations |
| 222 * in amortized logarithmic time. |
| 223 * |
| 224 * Keys of the map are compared using the `compare` function passed in |
| 225 * the constructor. If that is omitted, the objects are assumed to be |
| 226 * [Comparable], and are compared using their [Comparable.compareTo] |
| 227 * method. |
| 228 */ |
| 229 class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> { |
| 230 Comparator<K> _comparator; |
| 231 |
| 232 SplayTreeMap([int compare(K key1, K key2)]) |
| 233 : _comparator = (compare == null) ? Comparable.compare : compare; |
| 234 |
| 235 int _compare(K key1, K key2) => _comparator(key1, key2); |
| 236 |
| 237 SplayTreeMap._internal(); |
| 238 |
| 239 V operator [](K key) { |
| 240 if (_root != null) { |
| 241 int comp = _splay(key); |
| 242 if (comp == 0) return _root.value; |
| 243 } |
| 244 return null; |
| 245 } |
| 246 |
| 247 V remove(K key) { |
| 248 _SplayTreeMapNode root = _remove(key); |
| 249 if (root != null) return root.value; |
| 250 return null; |
| 251 } |
| 252 |
| 253 void operator []=(K key, V value) { |
| 254 // Splay on the key to move the last node on the search path for |
| 255 // the key to the root of the tree. |
| 256 int comp = _splay(key); |
| 257 if (comp == 0) { |
| 258 _root.value = value; |
| 259 return; |
| 260 } |
| 261 _addNewRoot(new _SplayTreeMapNode(key, value), comp); |
| 262 } |
| 263 |
201 | 264 |
202 V putIfAbsent(K key, V ifAbsent()) { | 265 V putIfAbsent(K key, V ifAbsent()) { |
203 if (_root == null) { | |
204 V value = ifAbsent(); | |
205 if (_root != null) { | |
206 throw new ConcurrentModificationError(this); | |
207 } | |
208 _root = new SplayTreeNode(key, value); | |
209 _count++; | |
210 _modificationCount++; | |
211 return value; | |
212 } | |
213 int comp = _splay(key); | 266 int comp = _splay(key); |
214 if (comp == 0) return _root.value; | 267 if (comp == 0) return _root.value; |
215 int modificationCount = _modificationCount; | 268 int modificationCount = _modificationCount; |
216 int splayCount = _splayCount; | 269 int splayCount = _splayCount; |
217 V value = ifAbsent(); | 270 V value = ifAbsent(); |
218 if (modificationCount != _modificationCount) { | 271 if (modificationCount != _modificationCount) { |
219 throw new ConcurrentModificationError(this); | 272 throw new ConcurrentModificationError(this); |
220 } | 273 } |
221 if (splayCount != _splayCount) { | 274 if (splayCount != _splayCount) { |
222 comp = _splay(key); | 275 comp = _splay(key); |
223 // Key is still not there, otherwise _modificationCount would be changed. | 276 // Key is still not there, otherwise _modificationCount would be changed. |
224 assert(comp != 0); | 277 assert(comp != 0); |
225 } | 278 } |
226 _addNewRoot(key, value, comp); | 279 _addNewRoot(new _SplayTreeMapNode(key, value), comp); |
227 return value; | 280 return value; |
228 } | 281 } |
229 | 282 |
230 bool get isEmpty { | 283 bool get isEmpty { |
231 // assert(!((_root == null) && (_count != 0))); | 284 // assert(!((_root == null) && (_count != 0))); |
232 // assert(!((_count == 0) && (_root != null))); | 285 // assert(!((_count == 0) && (_root != null))); |
233 return (_root == null); | 286 return (_root == null); |
234 } | 287 } |
235 | 288 |
236 void forEach(void f(K key, V value)) { | 289 void forEach(void f(K key, V value)) { |
237 Iterator<SplayTreeNode<K, V>> nodes = | 290 Iterator<_SplayTreeNode<K>> nodes = |
238 new _SplayTreeNodeIterator<K, V>(this); | 291 new _SplayTreeNodeIterator<K>(this); |
239 while (nodes.moveNext()) { | 292 while (nodes.moveNext()) { |
240 SplayTreeNode<K, V> node = nodes.current; | 293 _SplayTreeMapNode<K, V> node = nodes.current; |
241 f(node.key, node.value); | 294 f(node.key, node.value); |
242 } | 295 } |
243 } | 296 } |
244 | 297 |
245 int get length { | 298 int get length { |
246 return _count; | 299 return _count; |
247 } | 300 } |
248 | 301 |
249 void clear() { | 302 void clear() { |
250 _root = null; | 303 _clear(); |
251 _count = 0; | |
252 } | 304 } |
253 | 305 |
254 bool containsKey(K key) { | 306 bool containsKey(K key) { |
255 return _splay(key) == 0; | 307 return _splay(key) == 0; |
256 } | 308 } |
257 | 309 |
258 bool containsValue(V value) { | 310 bool containsValue(V value) { |
259 bool found = false; | 311 bool found = false; |
260 bool visit(SplayTreeNode node) { | 312 bool visit(_SplayTreeNode node) { |
261 if (node == null) return false; | 313 if (node == null) return false; |
262 if (node.value == value) return true; | 314 if (node.value == value) return true; |
263 // TODO(lrn): Do we want to handle the case where node.value.operator== | 315 // TODO(lrn): Do we want to handle the case where node.value.operator== |
264 // modifies the map? | 316 // modifies the map? |
265 return visit(node.left) || visit(node.right); | 317 return visit(node.left) || visit(node.right); |
266 } | 318 } |
267 return visit(_root); | 319 return visit(_root); |
268 } | 320 } |
269 | 321 |
270 Iterable<K> get keys => new _SplayTreeKeyIterable(this); | 322 Iterable<K> get keys => new _SplayTreeKeyIterable<K>(this); |
271 | 323 |
272 Iterable<V> get values => new _SplayTreeValueIterable(this); | 324 Iterable<V> get values => new _SplayTreeValueIterable<K, V>(this); |
273 | 325 |
274 String toString() { | 326 String toString() { |
275 return Maps.mapToString(this); | 327 return Maps.mapToString(this); |
276 } | 328 } |
277 | 329 |
278 /** | 330 /** |
279 * Get the first key in the map. Returns [null] if the map is empty. | 331 * Get the first key in the map. Returns [null] if the map is empty. |
280 */ | 332 */ |
281 K firstKey() { | 333 K firstKey() { |
282 if (_root == null) return null; | 334 _SplayTreeNode node = _first; |
283 SplayTreeNode<K, V> node = _root; | 335 return (node == null) ? null : node.key; |
284 while (node.left != null) { | |
285 node = node.left; | |
286 } | |
287 // Maybe implement a splay-method that can splay the minimum without | |
288 // performing comparisons. | |
289 _splay(node.key); | |
290 return node.key; | |
291 } | 336 } |
292 | 337 |
293 /** | 338 /** |
294 * Get the last key in the map. Returns [null] if the map is empty. | 339 * Get the last key in the map. Returns [null] if the map is empty. |
295 */ | 340 */ |
296 K lastKey() { | 341 K lastKey() { |
297 if (_root == null) return null; | 342 _SplayTreeNode node = _last; |
298 SplayTreeNode<K, V> node = _root; | 343 return (node == null) ? null : node.key; |
299 while (node.right != null) { | |
300 node = node.right; | |
301 } | |
302 // Maybe implement a splay-method that can splay the maximum without | |
303 // performing comparisons. | |
304 _splay(node.key); | |
305 return node.key; | |
306 } | 344 } |
307 | 345 |
308 /** | 346 /** |
309 * Get the last key in the map that is strictly smaller than [key]. Returns | 347 * Get the last key in the map that is strictly smaller than [key]. Returns |
310 * [null] if no key was not found. | 348 * [null] if no key was not found. |
311 */ | 349 */ |
312 K lastKeyBefore(K key) { | 350 K lastKeyBefore(K key) { |
313 if (_root == null) return null; | 351 if (_root == null) return null; |
314 int comp = _splay(key); | 352 int comp = _splay(key); |
315 if (comp < 0) return _root.key; | 353 if (comp < 0) return _root.key; |
316 SplayTreeNode<K, V> node = _root.left; | 354 _SplayTreeNode<K> node = _root.left; |
317 if (node == null) return null; | 355 if (node == null) return null; |
318 while (node.right != null) { | 356 while (node.right != null) { |
319 node = node.right; | 357 node = node.right; |
320 } | 358 } |
321 return node.key; | 359 return node.key; |
322 } | 360 } |
323 | 361 |
324 /** | 362 /** |
325 * Get the first key in the map that is strictly larger than [key]. Returns | 363 * Get the first key in the map that is strictly larger than [key]. Returns |
326 * [null] if no key was not found. | 364 * [null] if no key was not found. |
327 */ | 365 */ |
328 K firstKeyAfter(K key) { | 366 K firstKeyAfter(K key) { |
329 if (_root == null) return null; | 367 if (_root == null) return null; |
330 int comp = _splay(key); | 368 int comp = _splay(key); |
331 if (comp > 0) return _root.key; | 369 if (comp > 0) return _root.key; |
332 SplayTreeNode<K, V> node = _root.right; | 370 _SplayTreeNode<K> node = _root.right; |
333 if (node == null) return null; | 371 if (node == null) return null; |
334 while (node.left != null) { | 372 while (node.left != null) { |
335 node = node.left; | 373 node = node.left; |
336 } | 374 } |
337 return node.key; | 375 return node.key; |
338 } | 376 } |
339 } | 377 } |
340 | 378 |
341 abstract class _SplayTreeIterator<T> implements Iterator<T> { | 379 abstract class _SplayTreeIterator<T> implements Iterator<T> { |
342 final SplayTreeMap _map; | 380 final _SplayTree _tree; |
343 /** | 381 /** |
344 * Worklist of nodes to visit. | 382 * Worklist of nodes to visit. |
345 * | 383 * |
346 * These nodes have been passed over on the way down in a | 384 * These nodes have been passed over on the way down in a |
347 * depth-first left-to-right traversal. Visiting each node, | 385 * depth-first left-to-right traversal. Visiting each node, |
348 * and their right subtrees will visit the remainder of | 386 * and their right subtrees will visit the remainder of |
349 * the nodes of a full traversal. | 387 * the nodes of a full traversal. |
350 * | 388 * |
351 * Only valid as long as the original tree map isn't reordered. | 389 * Only valid as long as the original tree isn't reordered. |
352 */ | 390 */ |
353 final List<SplayTreeNode> _workList = <SplayTreeNode>[]; | 391 final List<_SplayTreeNode> _workList = <_SplayTreeNode>[]; |
354 | 392 |
355 /** | 393 /** |
356 * Original modification counter of [_map]. | 394 * Original modification counter of [_tree]. |
357 * | 395 * |
358 * Incremented on [_map] when a key is added or removed. | 396 * Incremented on [_tree] when a key is added or removed. |
359 * If it changes, iteration is aborted. | 397 * If it changes, iteration is aborted. |
360 */ | 398 */ |
361 final int _modificationCount; | 399 final int _modificationCount; |
362 | 400 |
363 /** | 401 /** |
364 * Count of splay operations on [_map] when [_workList] was built. | 402 * Count of splay operations on [_tree] when [_workList] was built. |
365 * | 403 * |
366 * If the splay count on [_map] increases, [_workList] becomes invalid. | 404 * If the splay count on [_tree] increases, [_workList] becomes invalid. |
367 */ | 405 */ |
368 int _splayCount; | 406 int _splayCount; |
369 | 407 |
370 /** Current node. */ | 408 /** Current node. */ |
371 SplayTreeNode _currentNode; | 409 _SplayTreeNode _currentNode; |
372 | 410 |
373 _SplayTreeIterator(SplayTreeMap map) | 411 _SplayTreeIterator(_SplayTree tree) |
374 : _map = map, | 412 : _tree = tree, |
375 _modificationCount = map._modificationCount, | 413 _modificationCount = tree._modificationCount, |
376 _splayCount = map._splayCount { | 414 _splayCount = tree._splayCount { |
377 _findLeftMostDescendent(map._root); | 415 _findLeftMostDescendent(tree._root); |
378 } | 416 } |
379 | 417 |
380 T get current { | 418 T get current { |
381 if (_currentNode == null) return null; | 419 if (_currentNode == null) return null; |
382 return _getValue(_currentNode); | 420 return _getValue(_currentNode); |
383 } | 421 } |
384 | 422 |
385 void _findLeftMostDescendent(SplayTreeNode node) { | 423 void _findLeftMostDescendent(_SplayTreeNode node) { |
386 while (node != null) { | 424 while (node != null) { |
387 _workList.add(node); | 425 _workList.add(node); |
388 node = node.left; | 426 node = node.left; |
389 } | 427 } |
390 } | 428 } |
391 | 429 |
392 /** | 430 /** |
393 * Called when the tree structure of the map has changed. | 431 * Called when the tree structure of the tree has changed. |
394 * | 432 * |
395 * This can be caused by a splay operation. | 433 * This can be caused by a splay operation. |
396 * If the key-set changes, iteration is aborted before getting | 434 * If the key-set changes, iteration is aborted before getting |
397 * here, so we know that the keys are the same as before, it's | 435 * here, so we know that the keys are the same as before, it's |
398 * only the tree that has been reordered. | 436 * only the tree that has been reordered. |
399 */ | 437 */ |
400 void _rebuildWorkList(SplayTreeNode currentNode) { | 438 void _rebuildWorkList(_SplayTreeNode currentNode) { |
401 assert(!_workList.isEmpty); | 439 assert(!_workList.isEmpty); |
402 _workList.clear(); | 440 _workList.clear(); |
403 if (currentNode == null) { | 441 if (currentNode == null) { |
404 _findLeftMostDescendent(_map._root); | 442 _findLeftMostDescendent(_tree._root); |
405 } else { | 443 } else { |
406 _map._splay(currentNode.key); | 444 _tree._splay(currentNode.key); |
407 _findLeftMostDescendent(_map._root.right); | 445 _findLeftMostDescendent(_tree._root.right); |
408 assert(!_workList.isEmpty); | 446 assert(!_workList.isEmpty); |
409 } | 447 } |
410 } | 448 } |
411 | 449 |
412 bool moveNext() { | 450 bool moveNext() { |
413 if (_modificationCount != _map._modificationCount) { | 451 if (_modificationCount != _tree._modificationCount) { |
414 throw new ConcurrentModificationError(_map); | 452 throw new ConcurrentModificationError(_tree); |
415 } | 453 } |
416 // Picks the next element in the worklist as current. | 454 // Picks the next element in the worklist as current. |
417 // Updates the worklist with the left-most path of the current node's | 455 // Updates the worklist with the left-most path of the current node's |
418 // right-hand child. | 456 // right-hand child. |
419 // If the worklist is no longer valid (after a splay), it is rebuild | 457 // If the worklist is no longer valid (after a splay), it is rebuild |
420 // from scratch. | 458 // from scratch. |
421 if (_workList.isEmpty) { | 459 if (_workList.isEmpty) { |
422 _currentNode = null; | 460 _currentNode = null; |
423 return false; | 461 return false; |
424 } | 462 } |
425 if (_map._splayCount != _splayCount) { | 463 if (_tree._splayCount != _splayCount) { |
426 _rebuildWorkList(_currentNode); | 464 _rebuildWorkList(_currentNode); |
427 } | 465 } |
428 _currentNode = _workList.removeLast(); | 466 _currentNode = _workList.removeLast(); |
429 _findLeftMostDescendent(_currentNode.right); | 467 _findLeftMostDescendent(_currentNode.right); |
430 return true; | 468 return true; |
431 } | 469 } |
432 | 470 |
433 T _getValue(SplayTreeNode node); | 471 T _getValue(_SplayTreeNode node); |
434 } | 472 } |
435 | 473 |
436 | 474 class _SplayTreeKeyIterable<K> extends Iterable<K> { |
437 class _SplayTreeKeyIterable<K, V> extends Iterable<K> { | 475 _SplayTree<K> _tree; |
438 SplayTreeMap<K, V> _map; | 476 _SplayTreeKeyIterable(this._tree); |
439 _SplayTreeKeyIterable(this._map); | 477 Iterator<K> get iterator => new _SplayTreeKeyIterator<K>(_tree); |
440 Iterator<K> get iterator => new _SplayTreeKeyIterator<K, V>(_map); | |
441 } | 478 } |
442 | 479 |
443 class _SplayTreeValueIterable<K, V> extends Iterable<V> { | 480 class _SplayTreeValueIterable<K, V> extends Iterable<V> { |
444 SplayTreeMap<K, V> _map; | 481 SplayTreeMap<K, V> _map; |
445 _SplayTreeValueIterable(this._map) ; | 482 _SplayTreeValueIterable(this._map); |
446 Iterator<V> get iterator => new _SplayTreeValueIterator<K, V>(_map); | 483 Iterator<V> get iterator => new _SplayTreeValueIterator<K, V>(_map); |
447 } | 484 } |
448 | 485 |
449 class _SplayTreeKeyIterator<K, V> extends _SplayTreeIterator<K> { | 486 class _SplayTreeKeyIterator<K> extends _SplayTreeIterator<K> { |
450 _SplayTreeKeyIterator(SplayTreeMap<K, V> map): super(map); | 487 _SplayTreeKeyIterator(_SplayTree<K> map): super(map); |
451 K _getValue(SplayTreeNode node) => node.key; | 488 K _getValue(_SplayTreeNode node) => node.key; |
452 } | 489 } |
453 | 490 |
454 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<V> { | 491 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<V> { |
455 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map); | 492 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map); |
456 V _getValue(SplayTreeNode node) => node.value; | 493 V _getValue(_SplayTreeMapNode node) => node.value; |
457 } | 494 } |
458 | 495 |
459 class _SplayTreeNodeIterator<K, V> | 496 class _SplayTreeNodeIterator<K> |
460 extends _SplayTreeIterator<SplayTreeNode<K, V>> { | 497 extends _SplayTreeIterator<_SplayTreeNode<K>> { |
461 _SplayTreeNodeIterator(SplayTreeMap<K, V> map): super(map); | 498 _SplayTreeNodeIterator(_SplayTree<K> map): super(map); |
462 SplayTreeNode<K, V> _getValue(SplayTreeNode node) => node; | 499 _SplayTreeNode<K> _getValue(_SplayTreeNode node) => node; |
463 } | 500 } |
OLD | NEW |