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 typedef bool _Predicate<T>(T value); | 7 typedef bool _Predicate<T>(T value); |
8 | 8 |
9 /** | 9 /** |
10 * A node in a splay tree. It holds the sorting key and the left | 10 * A node in a splay tree. It holds the sorting key and the left |
(...skipping 18 matching lines...) Expand all Loading... |
29 } | 29 } |
30 | 30 |
31 /** | 31 /** |
32 * A splay tree is a self-balancing binary search tree. | 32 * A splay tree is a self-balancing binary search tree. |
33 * | 33 * |
34 * It has the additional property that recently accessed elements | 34 * It has the additional property that recently accessed elements |
35 * are quick to access again. | 35 * are quick to access again. |
36 * It performs basic operations such as insertion, look-up and | 36 * It performs basic operations such as insertion, look-up and |
37 * removal, in O(log(n)) amortized time. | 37 * removal, in O(log(n)) amortized time. |
38 */ | 38 */ |
39 abstract class _SplayTree<K> { | 39 abstract class _SplayTree<K, Node extends _SplayTreeNode<K>> { |
40 // The root node of the splay tree. It will contain either the last | 40 // The root node of the splay tree. It will contain either the last |
41 // element inserted or the last element looked up. | 41 // element inserted or the last element looked up. |
42 _SplayTreeNode<K> _root; | 42 Node get _root; |
| 43 set _root(Node newValue); |
43 | 44 |
44 // The dummy node used when performing a splay on the tree. Reusing it | 45 // The dummy node used when performing a splay on the tree. Reusing it |
45 // avoids allocating a node each time a splay is performed. | 46 // avoids allocating a node each time a splay is performed. |
46 _SplayTreeNode<K> _dummy = new _SplayTreeNode<K>(null); | 47 Node get _dummy; |
47 | 48 |
48 // Number of elements in the splay tree. | 49 // Number of elements in the splay tree. |
49 int _count = 0; | 50 int _count = 0; |
50 | 51 |
51 /** | 52 /** |
52 * Counter incremented whenever the keys in the map changes. | 53 * Counter incremented whenever the keys in the map changes. |
53 * | 54 * |
54 * Used to detect concurrent modifications. | 55 * Used to detect concurrent modifications. |
55 */ | 56 */ |
56 int _modificationCount = 0; | 57 int _modificationCount = 0; |
57 | 58 |
58 /** | 59 /** |
59 * Counter incremented whenever the tree structure changes. | 60 * Counter incremented whenever the tree structure changes. |
60 * | 61 * |
61 * Used to detect that an in-place traversal cannot use | 62 * Used to detect that an in-place traversal cannot use |
62 * cached information that relies on the tree structure. | 63 * cached information that relies on the tree structure. |
63 */ | 64 */ |
64 int _splayCount = 0; | 65 int _splayCount = 0; |
65 | 66 |
| 67 /** The comparator that is used for this splay tree. */ |
| 68 Comparator<K> get _comparator; |
| 69 |
| 70 /** The predicate to determine that a given object is a valid key. */ |
| 71 _Predicate get _validKey; |
| 72 |
66 /** Comparison used to compare keys. */ | 73 /** Comparison used to compare keys. */ |
67 int _compare(K key1, K key2); | 74 int _compare(K key1, K key2); |
68 | 75 |
69 /** | 76 /** |
70 * Perform the splay operation for the given key. Moves the node with | 77 * Perform the splay operation for the given key. Moves the node with |
71 * the given key to the top of the tree. If no node has the given | 78 * the given key to the top of the tree. If no node has the given |
72 * key, the last node on the search path is moved to the top of the | 79 * key, the last node on the search path is moved to the top of the |
73 * tree. This is the simplified top-down splaying algorithm from: | 80 * tree. This is the simplified top-down splaying algorithm from: |
74 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan. | 81 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan. |
75 * | 82 * |
76 * Returns the result of comparing the new root of the tree to [key]. | 83 * Returns the result of comparing the new root of the tree to [key]. |
77 * Returns -1 if the table is empty. | 84 * Returns -1 if the table is empty. |
78 */ | 85 */ |
79 int _splay(K key) { | 86 int _splay(K key) { |
80 if (_root == null) return -1; | 87 if (_root == null) return -1; |
81 | 88 |
82 // The right child of the dummy node will hold | 89 // The right child of the dummy node will hold |
83 // the L tree of the algorithm. The left child of the dummy node | 90 // the L tree of the algorithm. The left child of the dummy node |
84 // will hold the R tree of the algorithm. Using a dummy node, left | 91 // will hold the R tree of the algorithm. Using a dummy node, left |
85 // and right will always be nodes and we avoid special cases. | 92 // and right will always be nodes and we avoid special cases. |
86 _SplayTreeNode<K> left = _dummy; | 93 Node left = _dummy; |
87 _SplayTreeNode<K> right = _dummy; | 94 Node right = _dummy; |
88 _SplayTreeNode<K> current = _root; | 95 Node current = _root; |
89 int comp; | 96 int comp; |
90 while (true) { | 97 while (true) { |
91 comp = _compare(current.key, key); | 98 comp = _compare(current.key, key); |
92 if (comp > 0) { | 99 if (comp > 0) { |
93 if (current.left == null) break; | 100 if (current.left == null) break; |
94 comp = _compare(current.left.key, key); | 101 comp = _compare(current.left.key, key); |
95 if (comp > 0) { | 102 if (comp > 0) { |
96 // Rotate right. | 103 // Rotate right. |
97 _SplayTreeNode<K> tmp = current.left; | 104 _SplayTreeNode<K> tmp = current.left; |
98 current.left = tmp.right; | 105 current.left = tmp.right; |
99 tmp.right = current; | 106 tmp.right = current; |
100 current = tmp; | 107 current = tmp; |
101 if (current.left == null) break; | 108 if (current.left == null) break; |
102 } | 109 } |
103 // Link right. | 110 // Link right. |
104 right.left = current; | 111 right.left = current; |
105 right = current; | 112 right = current; |
106 current = current.left; | 113 current = current.left; |
107 } else if (comp < 0) { | 114 } else if (comp < 0) { |
108 if (current.right == null) break; | 115 if (current.right == null) break; |
109 comp = _compare(current.right.key, key); | 116 comp = _compare(current.right.key, key); |
110 if (comp < 0) { | 117 if (comp < 0) { |
111 // Rotate left. | 118 // Rotate left. |
112 _SplayTreeNode<K> tmp = current.right; | 119 Node tmp = current.right; |
113 current.right = tmp.left; | 120 current.right = tmp.left; |
114 tmp.left = current; | 121 tmp.left = current; |
115 current = tmp; | 122 current = tmp; |
116 if (current.right == null) break; | 123 if (current.right == null) break; |
117 } | 124 } |
118 // Link left. | 125 // Link left. |
119 left.right = current; | 126 left.right = current; |
120 left = current; | 127 left = current; |
121 current = current.right; | 128 current = current.right; |
122 } else { | 129 } else { |
(...skipping 10 matching lines...) Expand all Loading... |
133 _dummy.right = null; | 140 _dummy.right = null; |
134 _dummy.left = null; | 141 _dummy.left = null; |
135 _splayCount++; | 142 _splayCount++; |
136 return comp; | 143 return comp; |
137 } | 144 } |
138 | 145 |
139 // Emulates splaying with a key that is smaller than any in the subtree | 146 // Emulates splaying with a key that is smaller than any in the subtree |
140 // anchored at [node]. | 147 // anchored at [node]. |
141 // and that node is returned. It should replace the reference to [node] | 148 // and that node is returned. It should replace the reference to [node] |
142 // in any parent tree or root pointer. | 149 // in any parent tree or root pointer. |
143 _SplayTreeNode<K> _splayMin(_SplayTreeNode<K> node) { | 150 Node _splayMin(Node node) { |
144 _SplayTreeNode current = node; | 151 Node current = node; |
145 while (current.left != null) { | 152 while (current.left != null) { |
146 _SplayTreeNode left = current.left; | 153 Node left = current.left; |
147 current.left = left.right; | 154 current.left = left.right; |
148 left.right = current; | 155 left.right = current; |
149 current = left; | 156 current = left; |
150 } | 157 } |
151 return current; | 158 return current; |
152 } | 159 } |
153 | 160 |
154 // Emulates splaying with a key that is greater than any in the subtree | 161 // Emulates splaying with a key that is greater than any in the subtree |
155 // anchored at [node]. | 162 // anchored at [node]. |
156 // After this, the largest element in the tree is the root of the subtree, | 163 // After this, the largest element in the tree is the root of the subtree, |
157 // and that node is returned. It should replace the reference to [node] | 164 // and that node is returned. It should replace the reference to [node] |
158 // in any parent tree or root pointer. | 165 // in any parent tree or root pointer. |
159 _SplayTreeNode<K> _splayMax(_SplayTreeNode<K> node) { | 166 Node _splayMax(Node node) { |
160 _SplayTreeNode current = node; | 167 Node current = node; |
161 while (current.right != null) { | 168 while (current.right != null) { |
162 _SplayTreeNode right = current.right; | 169 Node right = current.right; |
163 current.right = right.left; | 170 current.right = right.left; |
164 right.left = current; | 171 right.left = current; |
165 current = right; | 172 current = right; |
166 } | 173 } |
167 return current; | 174 return current; |
168 } | 175 } |
169 | 176 |
170 _SplayTreeNode _remove(K key) { | 177 Node _remove(K key) { |
171 if (_root == null) return null; | 178 if (_root == null) return null; |
172 int comp = _splay(key); | 179 int comp = _splay(key); |
173 if (comp != 0) return null; | 180 if (comp != 0) return null; |
174 _SplayTreeNode result = _root; | 181 Node result = _root; |
175 _count--; | 182 _count--; |
176 // assert(_count >= 0); | 183 // assert(_count >= 0); |
177 if (_root.left == null) { | 184 if (_root.left == null) { |
178 _root = _root.right; | 185 _root = _root.right; |
179 } else { | 186 } else { |
180 _SplayTreeNode<K> right = _root.right; | 187 Node right = _root.right; |
181 // Splay to make sure that the new root has an empty right child. | 188 // Splay to make sure that the new root has an empty right child. |
182 _root = _splayMax(_root.left); | 189 _root = _splayMax(_root.left); |
183 // Insert the original right child as the right child of the new | 190 // Insert the original right child as the right child of the new |
184 // root. | 191 // root. |
185 _root.right = right; | 192 _root.right = right; |
186 } | 193 } |
187 _modificationCount++; | 194 _modificationCount++; |
188 return result; | 195 return result; |
189 } | 196 } |
190 | 197 |
191 /** | 198 /** |
192 * Adds a new root node with the given [key] or [value]. | 199 * Adds a new root node with the given [key] or [value]. |
193 * | 200 * |
194 * The [comp] value is the result of comparing the existing root's key | 201 * The [comp] value is the result of comparing the existing root's key |
195 * with key. | 202 * with key. |
196 */ | 203 */ |
197 void _addNewRoot(_SplayTreeNode<K> node, int comp) { | 204 void _addNewRoot(Node node, int comp) { |
198 _count++; | 205 _count++; |
199 _modificationCount++; | 206 _modificationCount++; |
200 if (_root == null) { | 207 if (_root == null) { |
201 _root = node; | 208 _root = node; |
202 return; | 209 return; |
203 } | 210 } |
204 // assert(_count >= 0); | 211 // assert(_count >= 0); |
205 if (comp < 0) { | 212 if (comp < 0) { |
206 node.left = _root; | 213 node.left = _root; |
207 node.right = _root.right; | 214 node.right = _root.right; |
208 _root.right = null; | 215 _root.right = null; |
209 } else { | 216 } else { |
210 node.right = _root; | 217 node.right = _root; |
211 node.left = _root.left; | 218 node.left = _root.left; |
212 _root.left = null; | 219 _root.left = null; |
213 } | 220 } |
214 _root = node; | 221 _root = node; |
215 } | 222 } |
216 | 223 |
217 _SplayTreeNode get _first { | 224 Node get _first { |
218 if (_root == null) return null; | 225 if (_root == null) return null; |
219 _root = _splayMin(_root); | 226 _root = _splayMin(_root); |
220 return _root; | 227 return _root; |
221 } | 228 } |
222 | 229 |
223 _SplayTreeNode get _last { | 230 Node get _last { |
224 if (_root == null) return null; | 231 if (_root == null) return null; |
225 _root = _splayMax(_root); | 232 _root = _splayMax(_root); |
226 return _root; | 233 return _root; |
227 } | 234 } |
228 | 235 |
229 void _clear() { | 236 void _clear() { |
230 _root = null; | 237 _root = null; |
231 _count = 0; | 238 _count = 0; |
232 _modificationCount++; | 239 _modificationCount++; |
233 } | 240 } |
(...skipping 19 matching lines...) Expand all Loading... |
253 * Non-comparable objects (including `null`) will not work as keys | 260 * Non-comparable objects (including `null`) will not work as keys |
254 * in that case. | 261 * in that case. |
255 * | 262 * |
256 * To allow calling [operator[]], [remove] or [containsKey] with objects | 263 * To allow calling [operator[]], [remove] or [containsKey] with objects |
257 * that are not supported by the `compare` function, an extra `isValidKey` | 264 * that are not supported by the `compare` function, an extra `isValidKey` |
258 * predicate function can be supplied. This function is tested before | 265 * predicate function can be supplied. This function is tested before |
259 * using the `compare` function on an argument value that may not be a [K] | 266 * using the `compare` function on an argument value that may not be a [K] |
260 * value. If omitted, the `isValidKey` function defaults to testing if the | 267 * value. If omitted, the `isValidKey` function defaults to testing if the |
261 * value is a [K]. | 268 * value is a [K]. |
262 */ | 269 */ |
263 class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> { | 270 class SplayTreeMap<K, V> extends _SplayTree<K, _SplayTreeMapNode<K, V>> |
| 271 implements Map<K, V> { |
| 272 _SplayTreeMapNode<K, V> _root; |
| 273 final _SplayTreeMapNode<K, V> _dummy = |
| 274 new _SplayTreeMapNode<K, V>(null, null); |
| 275 |
264 Comparator<K> _comparator; | 276 Comparator<K> _comparator; |
265 _Predicate _validKey; | 277 _Predicate _validKey; |
266 | 278 |
267 SplayTreeMap([int compare(K key1, K key2), bool isValidKey(potentialKey)]) | 279 SplayTreeMap([int compare(K key1, K key2), bool isValidKey(potentialKey)]) |
268 : _comparator = (compare == null) ? Comparable.compare : compare, | 280 : _comparator = compare ?? Comparable.compare as Comparator<K>, |
269 _validKey = (isValidKey != null) ? isValidKey : ((v) => v is K); | 281 _validKey = isValidKey ?? ((v) => v is K); |
270 | 282 |
271 /** | 283 /** |
272 * Creates a [SplayTreeMap] that contains all key/value pairs of [other]. | 284 * Creates a [SplayTreeMap] that contains all key/value pairs of [other]. |
273 */ | 285 */ |
274 factory SplayTreeMap.from(Map other, | 286 factory SplayTreeMap.from(Map other, |
275 [int compare(K key1, K key2), | 287 [int compare(K key1, K key2), |
276 bool isValidKey(potentialKey)]) { | 288 bool isValidKey(potentialKey)]) { |
277 SplayTreeMap<K, V> result = new SplayTreeMap<K, V>(compare, isValidKey); | 289 SplayTreeMap<K, V> result = new SplayTreeMap<K, V>(compare, isValidKey); |
278 other.forEach((k, v) { result[k] = v; }); | 290 other.forEach((k, v) { result[k as Object/*=K*/] = v as Object/*=V*/; }); |
279 return result; | 291 return result; |
280 } | 292 } |
281 | 293 |
282 /** | 294 /** |
283 * Creates a [SplayTreeMap] where the keys and values are computed from the | 295 * Creates a [SplayTreeMap] where the keys and values are computed from the |
284 * [iterable]. | 296 * [iterable]. |
285 * | 297 * |
286 * For each element of the [iterable] this constructor computes a key/value | 298 * For each element of the [iterable] this constructor computes a key/value |
287 * pair, by applying [key] and [value] respectively. | 299 * pair, by applying [key] and [value] respectively. |
288 * | 300 * |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 return map; | 332 return map; |
321 } | 333 } |
322 | 334 |
323 int _compare(K key1, K key2) => _comparator(key1, key2); | 335 int _compare(K key1, K key2) => _comparator(key1, key2); |
324 | 336 |
325 SplayTreeMap._internal(); | 337 SplayTreeMap._internal(); |
326 | 338 |
327 V operator [](Object key) { | 339 V operator [](Object key) { |
328 if (!_validKey(key)) return null; | 340 if (!_validKey(key)) return null; |
329 if (_root != null) { | 341 if (_root != null) { |
330 int comp = _splay(key); | 342 int comp = _splay(key as dynamic/*=K*/); |
331 if (comp == 0) { | 343 if (comp == 0) { |
332 _SplayTreeMapNode mapRoot = _root; | 344 return _root.value; |
333 return mapRoot.value; | |
334 } | 345 } |
335 } | 346 } |
336 return null; | 347 return null; |
337 } | 348 } |
338 | 349 |
339 V remove(Object key) { | 350 V remove(Object key) { |
340 if (!_validKey(key)) return null; | 351 if (!_validKey(key)) return null; |
341 _SplayTreeMapNode mapRoot = _remove(key); | 352 _SplayTreeMapNode<K, V> mapRoot = _remove(key as dynamic/*=K*/); |
342 if (mapRoot != null) return mapRoot.value; | 353 if (mapRoot != null) return mapRoot.value; |
343 return null; | 354 return null; |
344 } | 355 } |
345 | 356 |
346 void operator []=(K key, V value) { | 357 void operator []=(K key, V value) { |
347 if (key == null) throw new ArgumentError(key); | 358 if (key == null) throw new ArgumentError(key); |
348 // Splay on the key to move the last node on the search path for | 359 // Splay on the key to move the last node on the search path for |
349 // the key to the root of the tree. | 360 // the key to the root of the tree. |
350 int comp = _splay(key); | 361 int comp = _splay(key); |
351 if (comp == 0) { | 362 if (comp == 0) { |
352 _SplayTreeMapNode mapRoot = _root; | 363 _root.value = value; |
353 mapRoot.value = value; | |
354 return; | 364 return; |
355 } | 365 } |
356 _addNewRoot(new _SplayTreeMapNode(key, value), comp); | 366 _addNewRoot(new _SplayTreeMapNode(key, value), comp); |
357 } | 367 } |
358 | 368 |
359 | 369 |
360 V putIfAbsent(K key, V ifAbsent()) { | 370 V putIfAbsent(K key, V ifAbsent()) { |
361 if (key == null) throw new ArgumentError(key); | 371 if (key == null) throw new ArgumentError(key); |
362 int comp = _splay(key); | 372 int comp = _splay(key); |
363 if (comp == 0) { | 373 if (comp == 0) { |
364 _SplayTreeMapNode mapRoot = _root; | 374 return _root.value; |
365 return mapRoot.value; | |
366 } | 375 } |
367 int modificationCount = _modificationCount; | 376 int modificationCount = _modificationCount; |
368 int splayCount = _splayCount; | 377 int splayCount = _splayCount; |
369 V value = ifAbsent(); | 378 V value = ifAbsent(); |
370 if (modificationCount != _modificationCount) { | 379 if (modificationCount != _modificationCount) { |
371 throw new ConcurrentModificationError(this); | 380 throw new ConcurrentModificationError(this); |
372 } | 381 } |
373 if (splayCount != _splayCount) { | 382 if (splayCount != _splayCount) { |
374 comp = _splay(key); | 383 comp = _splay(key); |
375 // Key is still not there, otherwise _modificationCount would be changed. | 384 // Key is still not there, otherwise _modificationCount would be changed. |
(...skipping 24 matching lines...) Expand all Loading... |
400 | 409 |
401 int get length { | 410 int get length { |
402 return _count; | 411 return _count; |
403 } | 412 } |
404 | 413 |
405 void clear() { | 414 void clear() { |
406 _clear(); | 415 _clear(); |
407 } | 416 } |
408 | 417 |
409 bool containsKey(Object key) { | 418 bool containsKey(Object key) { |
410 return _validKey(key) && _splay(key) == 0; | 419 return _validKey(key) && _splay(key as dynamic/*=K*/) == 0; |
411 } | 420 } |
412 | 421 |
413 bool containsValue(Object value) { | 422 bool containsValue(Object value) { |
414 bool found = false; | 423 bool found = false; |
415 int initialSplayCount = _splayCount; | 424 int initialSplayCount = _splayCount; |
416 bool visit(_SplayTreeMapNode node) { | 425 bool visit(_SplayTreeMapNode node) { |
417 while (node != null) { | 426 while (node != null) { |
418 if (node.value == value) return true; | 427 if (node.value == value) return true; |
419 if (initialSplayCount != _splayCount) { | 428 if (initialSplayCount != _splayCount) { |
420 throw new ConcurrentModificationError(this); | 429 throw new ConcurrentModificationError(this); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 if (comp > 0) return _root.key; | 488 if (comp > 0) return _root.key; |
480 _SplayTreeNode<K> node = _root.right; | 489 _SplayTreeNode<K> node = _root.right; |
481 if (node == null) return null; | 490 if (node == null) return null; |
482 while (node.left != null) { | 491 while (node.left != null) { |
483 node = node.left; | 492 node = node.left; |
484 } | 493 } |
485 return node.key; | 494 return node.key; |
486 } | 495 } |
487 } | 496 } |
488 | 497 |
489 abstract class _SplayTreeIterator<T> implements Iterator<T> { | 498 abstract class _SplayTreeIterator<K, T> implements Iterator<T> { |
490 final _SplayTree _tree; | 499 final _SplayTree<K, _SplayTreeNode<K>> _tree; |
491 /** | 500 /** |
492 * Worklist of nodes to visit. | 501 * Worklist of nodes to visit. |
493 * | 502 * |
494 * These nodes have been passed over on the way down in a | 503 * These nodes have been passed over on the way down in a |
495 * depth-first left-to-right traversal. Visiting each node, | 504 * depth-first left-to-right traversal. Visiting each node, |
496 * and their right subtrees will visit the remainder of | 505 * and their right subtrees will visit the remainder of |
497 * the nodes of a full traversal. | 506 * the nodes of a full traversal. |
498 * | 507 * |
499 * Only valid as long as the original tree isn't reordered. | 508 * Only valid as long as the original tree isn't reordered. |
500 */ | 509 */ |
501 final List<_SplayTreeNode> _workList = <_SplayTreeNode>[]; | 510 final List<_SplayTreeNode<K>> _workList = <_SplayTreeNode<K>>[]; |
502 | 511 |
503 /** | 512 /** |
504 * Original modification counter of [_tree]. | 513 * Original modification counter of [_tree]. |
505 * | 514 * |
506 * Incremented on [_tree] when a key is added or removed. | 515 * Incremented on [_tree] when a key is added or removed. |
507 * If it changes, iteration is aborted. | 516 * If it changes, iteration is aborted. |
508 * | 517 * |
509 * Not final because some iterators may modify the tree knowingly, | 518 * Not final because some iterators may modify the tree knowingly, |
510 * and they update the modification count in that case. | 519 * and they update the modification count in that case. |
511 */ | 520 */ |
512 int _modificationCount; | 521 int _modificationCount; |
513 | 522 |
514 /** | 523 /** |
515 * Count of splay operations on [_tree] when [_workList] was built. | 524 * Count of splay operations on [_tree] when [_workList] was built. |
516 * | 525 * |
517 * If the splay count on [_tree] increases, [_workList] becomes invalid. | 526 * If the splay count on [_tree] increases, [_workList] becomes invalid. |
518 */ | 527 */ |
519 int _splayCount; | 528 int _splayCount; |
520 | 529 |
521 /** Current node. */ | 530 /** Current node. */ |
522 _SplayTreeNode _currentNode; | 531 _SplayTreeNode<K> _currentNode; |
523 | 532 |
524 _SplayTreeIterator(_SplayTree tree) | 533 _SplayTreeIterator(_SplayTree<K, _SplayTreeNode<K>> tree) |
525 : _tree = tree, | 534 : _tree = tree, |
526 _modificationCount = tree._modificationCount, | 535 _modificationCount = tree._modificationCount, |
527 _splayCount = tree._splayCount { | 536 _splayCount = tree._splayCount { |
528 _findLeftMostDescendent(tree._root); | 537 _findLeftMostDescendent(tree._root); |
529 } | 538 } |
530 | 539 |
531 _SplayTreeIterator.startAt(_SplayTree tree, var startKey) | 540 _SplayTreeIterator.startAt(_SplayTree<K, _SplayTreeNode<K>> tree, K startKey) |
532 : _tree = tree, | 541 : _tree = tree, |
533 _modificationCount = tree._modificationCount { | 542 _modificationCount = tree._modificationCount { |
534 if (tree._root == null) return; | 543 if (tree._root == null) return; |
535 int compare = tree._splay(startKey); | 544 int compare = tree._splay(startKey); |
536 _splayCount = tree._splayCount; | 545 _splayCount = tree._splayCount; |
537 if (compare < 0) { | 546 if (compare < 0) { |
538 // Don't include the root, start at the next element after the root. | 547 // Don't include the root, start at the next element after the root. |
539 _findLeftMostDescendent(tree._root.right); | 548 _findLeftMostDescendent(tree._root.right); |
540 } else { | 549 } else { |
541 _workList.add(tree._root); | 550 _workList.add(tree._root); |
542 } | 551 } |
543 } | 552 } |
544 | 553 |
545 T get current { | 554 T get current { |
546 if (_currentNode == null) return null; | 555 if (_currentNode == null) return null; |
547 return _getValue(_currentNode); | 556 return _getValue(_currentNode); |
548 } | 557 } |
549 | 558 |
550 void _findLeftMostDescendent(_SplayTreeNode node) { | 559 void _findLeftMostDescendent(_SplayTreeNode<K> node) { |
551 while (node != null) { | 560 while (node != null) { |
552 _workList.add(node); | 561 _workList.add(node); |
553 node = node.left; | 562 node = node.left; |
554 } | 563 } |
555 } | 564 } |
556 | 565 |
557 /** | 566 /** |
558 * Called when the tree structure of the tree has changed. | 567 * Called when the tree structure of the tree has changed. |
559 * | 568 * |
560 * This can be caused by a splay operation. | 569 * This can be caused by a splay operation. |
561 * If the key-set changes, iteration is aborted before getting | 570 * If the key-set changes, iteration is aborted before getting |
562 * here, so we know that the keys are the same as before, it's | 571 * here, so we know that the keys are the same as before, it's |
563 * only the tree that has been reordered. | 572 * only the tree that has been reordered. |
564 */ | 573 */ |
565 void _rebuildWorkList(_SplayTreeNode currentNode) { | 574 void _rebuildWorkList(_SplayTreeNode<K> currentNode) { |
566 assert(!_workList.isEmpty); | 575 assert(!_workList.isEmpty); |
567 _workList.clear(); | 576 _workList.clear(); |
568 if (currentNode == null) { | 577 if (currentNode == null) { |
569 _findLeftMostDescendent(_tree._root); | 578 _findLeftMostDescendent(_tree._root); |
570 } else { | 579 } else { |
571 _tree._splay(currentNode.key); | 580 _tree._splay(currentNode.key); |
572 _findLeftMostDescendent(_tree._root.right); | 581 _findLeftMostDescendent(_tree._root.right); |
573 assert(!_workList.isEmpty); | 582 assert(!_workList.isEmpty); |
574 } | 583 } |
575 } | 584 } |
(...skipping 12 matching lines...) Expand all Loading... |
588 return false; | 597 return false; |
589 } | 598 } |
590 if (_tree._splayCount != _splayCount && _currentNode != null) { | 599 if (_tree._splayCount != _splayCount && _currentNode != null) { |
591 _rebuildWorkList(_currentNode); | 600 _rebuildWorkList(_currentNode); |
592 } | 601 } |
593 _currentNode = _workList.removeLast(); | 602 _currentNode = _workList.removeLast(); |
594 _findLeftMostDescendent(_currentNode.right); | 603 _findLeftMostDescendent(_currentNode.right); |
595 return true; | 604 return true; |
596 } | 605 } |
597 | 606 |
598 T _getValue(_SplayTreeNode node); | 607 T _getValue(_SplayTreeNode<K> node); |
599 } | 608 } |
600 | 609 |
601 class _SplayTreeKeyIterable<K> extends Iterable<K> | 610 class _SplayTreeKeyIterable<K> extends Iterable<K> |
602 implements EfficientLength { | 611 implements EfficientLength { |
603 _SplayTree<K> _tree; | 612 _SplayTree<K, _SplayTreeNode<K>> _tree; |
604 _SplayTreeKeyIterable(this._tree); | 613 _SplayTreeKeyIterable(this._tree); |
605 int get length => _tree._count; | 614 int get length => _tree._count; |
606 bool get isEmpty => _tree._count == 0; | 615 bool get isEmpty => _tree._count == 0; |
607 Iterator<K> get iterator => new _SplayTreeKeyIterator<K>(_tree); | 616 Iterator<K> get iterator => new _SplayTreeKeyIterator<K>(_tree); |
608 | 617 |
609 Set<K> toSet() { | 618 Set<K> toSet() { |
610 var setOrMap = _tree; // Both have _comparator and _validKey. | |
611 SplayTreeSet<K> set = | 619 SplayTreeSet<K> set = |
612 new SplayTreeSet<K>(setOrMap._comparator, setOrMap._validKey); | 620 new SplayTreeSet<K>(_tree._comparator, _tree._validKey); |
613 set._count = _tree._count; | 621 set._count = _tree._count; |
614 set._root = set._copyNode(_tree._root); | 622 set._root = set._copyNode(_tree._root); |
615 return set; | 623 return set; |
616 } | 624 } |
617 } | 625 } |
618 | 626 |
619 class _SplayTreeValueIterable<K, V> extends Iterable<V> | 627 class _SplayTreeValueIterable<K, V> extends Iterable<V> |
620 implements EfficientLength { | 628 implements EfficientLength { |
621 SplayTreeMap<K, V> _map; | 629 SplayTreeMap<K, V> _map; |
622 _SplayTreeValueIterable(this._map); | 630 _SplayTreeValueIterable(this._map); |
623 int get length => _map._count; | 631 int get length => _map._count; |
624 bool get isEmpty => _map._count == 0; | 632 bool get isEmpty => _map._count == 0; |
625 Iterator<V> get iterator => new _SplayTreeValueIterator<K, V>(_map); | 633 Iterator<V> get iterator => new _SplayTreeValueIterator<K, V>(_map); |
626 } | 634 } |
627 | 635 |
628 class _SplayTreeKeyIterator<K> extends _SplayTreeIterator<K> { | 636 class _SplayTreeKeyIterator<K> extends _SplayTreeIterator<K, K> { |
629 _SplayTreeKeyIterator(_SplayTree<K> map): super(map); | 637 _SplayTreeKeyIterator(_SplayTree<K, _SplayTreeNode<K>> map): super(map); |
630 K _getValue(_SplayTreeNode node) => node.key; | 638 K _getValue(_SplayTreeNode<K> node) => node.key; |
631 } | 639 } |
632 | 640 |
633 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<V> { | 641 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<K, V> { |
634 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map); | 642 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map); |
635 V _getValue(_SplayTreeMapNode node) => node.value; | 643 V _getValue(_SplayTreeNode<K> node) { |
| 644 _SplayTreeMapNode<K, V> mapNode = |
| 645 node as dynamic/*=_SplayTreeMapNode<K, V>*/; |
| 646 return mapNode.value; |
| 647 } |
636 } | 648 } |
637 | 649 |
638 class _SplayTreeNodeIterator<K> | 650 class _SplayTreeNodeIterator<K> |
639 extends _SplayTreeIterator<_SplayTreeNode<K>> { | 651 extends _SplayTreeIterator<K, _SplayTreeNode<K>> { |
640 _SplayTreeNodeIterator(_SplayTree<K> tree): super(tree); | 652 _SplayTreeNodeIterator(_SplayTree<K, _SplayTreeNode<K>> tree): super(tree); |
641 _SplayTreeNodeIterator.startAt(_SplayTree<K> tree, var startKey) | 653 _SplayTreeNodeIterator.startAt( |
| 654 _SplayTree<K, _SplayTreeNode<K>> tree, K startKey) |
642 : super.startAt(tree, startKey); | 655 : super.startAt(tree, startKey); |
643 _SplayTreeNode<K> _getValue(_SplayTreeNode node) => node; | 656 _SplayTreeNode<K> _getValue(_SplayTreeNode<K> node) => node; |
644 } | 657 } |
645 | 658 |
646 | 659 |
647 /** | 660 /** |
648 * A [Set] of objects that can be ordered relative to each other. | 661 * A [Set] of objects that can be ordered relative to each other. |
649 * | 662 * |
650 * The set is based on a self-balancing binary tree. It allows most operations | 663 * The set is based on a self-balancing binary tree. It allows most operations |
651 * in amortized logarithmic time. | 664 * in amortized logarithmic time. |
652 * | 665 * |
653 * Elements of the set are compared using the `compare` function passed in | 666 * Elements of the set are compared using the `compare` function passed in |
654 * the constructor, both for ordering and for equality. | 667 * the constructor, both for ordering and for equality. |
655 * If the set contains only an object `a`, then `set.contains(b)` | 668 * If the set contains only an object `a`, then `set.contains(b)` |
656 * will return `true` if and only if `compare(a, b) == 0`, | 669 * will return `true` if and only if `compare(a, b) == 0`, |
657 * and the value of `a == b` is not even checked. | 670 * and the value of `a == b` is not even checked. |
658 * If the compare function is omitted, the objects are assumed to be | 671 * If the compare function is omitted, the objects are assumed to be |
659 * [Comparable], and are compared using their [Comparable.compareTo] method. | 672 * [Comparable], and are compared using their [Comparable.compareTo] method. |
660 * Non-comparable objects (including `null`) will not work as an element | 673 * Non-comparable objects (including `null`) will not work as an element |
661 * in that case. | 674 * in that case. |
662 */ | 675 */ |
663 class SplayTreeSet<E> extends _SplayTree<E> with IterableMixin<E>, SetMixin<E> { | 676 class SplayTreeSet<E> extends _SplayTree<E, _SplayTreeNode<E>> |
664 Comparator _comparator; | 677 with IterableMixin<E>, SetMixin<E> { |
| 678 _SplayTreeNode<E> _root; |
| 679 final _SplayTreeNode<E> _dummy = new _SplayTreeNode<E>(null); |
| 680 |
| 681 Comparator<E> _comparator; |
665 _Predicate _validKey; | 682 _Predicate _validKey; |
666 | 683 |
667 /** | 684 /** |
668 * Create a new [SplayTreeSet] with the given compare function. | 685 * Create a new [SplayTreeSet] with the given compare function. |
669 * | 686 * |
670 * If the [compare] function is omitted, it defaults to [Comparable.compare], | 687 * If the [compare] function is omitted, it defaults to [Comparable.compare], |
671 * and the elements must be comparable. | 688 * and the elements must be comparable. |
672 * | 689 * |
673 * A provided `compare` function may not work on all objects. It may not even | 690 * A provided `compare` function may not work on all objects. It may not even |
674 * work on all `E` instances. | 691 * work on all `E` instances. |
675 * | 692 * |
676 * For operations that add elements to the set, the user is supposed to not | 693 * For operations that add elements to the set, the user is supposed to not |
677 * pass in objects that doesn't work with the compare function. | 694 * pass in objects that doesn't work with the compare function. |
678 * | 695 * |
679 * The methods [contains], [remove], [lookup], [removeAll] or [retainAll] | 696 * The methods [contains], [remove], [lookup], [removeAll] or [retainAll] |
680 * are typed to accept any object(s), and the [isValidKey] test can used to | 697 * are typed to accept any object(s), and the [isValidKey] test can used to |
681 * filter those objects before handing them to the `compare` function. | 698 * filter those objects before handing them to the `compare` function. |
682 * | 699 * |
683 * If [isValidKey] is provided, only values satisfying `isValidKey(other)` | 700 * If [isValidKey] is provided, only values satisfying `isValidKey(other)` |
684 * are compared using the `compare` method in the methods mentioned above. | 701 * are compared using the `compare` method in the methods mentioned above. |
685 * If the `isValidKey` function returns false for an object, it is assumed to | 702 * If the `isValidKey` function returns false for an object, it is assumed to |
686 * not be in the set. | 703 * not be in the set. |
687 * | 704 * |
688 * If omitted, the `isValidKey` function defaults to checking against the | 705 * If omitted, the `isValidKey` function defaults to checking against the |
689 * type parameter: `other is E`. | 706 * type parameter: `other is E`. |
690 */ | 707 */ |
691 SplayTreeSet([int compare(E key1, E key2), bool isValidKey(potentialKey)]) | 708 SplayTreeSet([int compare(E key1, E key2), bool isValidKey(potentialKey)]) |
692 : _comparator = (compare == null) ? Comparable.compare : compare, | 709 : _comparator = |
693 _validKey = (isValidKey != null) ? isValidKey : ((v) => v is E); | 710 compare ?? Comparable.compare as dynamic/*=Comparator<E>*/, |
| 711 _validKey = isValidKey ?? ((v) => v is E); |
694 | 712 |
695 /** | 713 /** |
696 * Creates a [SplayTreeSet] that contains all [elements]. | 714 * Creates a [SplayTreeSet] that contains all [elements]. |
697 * | 715 * |
698 * The set works as if created by `new SplayTreeSet<E>(compare, isValidKey)`. | 716 * The set works as if created by `new SplayTreeSet<E>(compare, isValidKey)`. |
699 * | 717 * |
700 * All the [elements] should be valid as arguments to the [compare] function. | 718 * All the [elements] should be valid as arguments to the [compare] function. |
701 */ | 719 */ |
702 factory SplayTreeSet.from(Iterable elements, | 720 factory SplayTreeSet.from(Iterable elements, |
703 [int compare(E key1, E key2), | 721 [int compare(E key1, E key2), |
704 bool isValidKey(potentialKey)]) { | 722 bool isValidKey(potentialKey)]) { |
705 SplayTreeSet<E> result = new SplayTreeSet<E>(compare, isValidKey); | 723 SplayTreeSet<E> result = new SplayTreeSet<E>(compare, isValidKey); |
706 for (final E element in elements) { | 724 for (final element in elements) { |
707 result.add(element); | 725 E e = element as Object/*=E*/; |
| 726 result.add(e); |
708 } | 727 } |
709 return result; | 728 return result; |
710 } | 729 } |
711 | 730 |
712 int _compare(E e1, E e2) => _comparator(e1, e2); | 731 int _compare(E e1, E e2) => _comparator(e1, e2); |
713 | 732 |
714 // From Iterable. | 733 // From Iterable. |
715 | 734 |
716 Iterator<E> get iterator => new _SplayTreeKeyIterator<E>(this); | 735 Iterator<E> get iterator => new _SplayTreeKeyIterator<E>(this); |
717 | 736 |
(...skipping 12 matching lines...) Expand all Loading... |
730 } | 749 } |
731 | 750 |
732 E get single { | 751 E get single { |
733 if (_count == 0) throw IterableElementError.noElement(); | 752 if (_count == 0) throw IterableElementError.noElement(); |
734 if (_count > 1) throw IterableElementError.tooMany(); | 753 if (_count > 1) throw IterableElementError.tooMany(); |
735 return _root.key; | 754 return _root.key; |
736 } | 755 } |
737 | 756 |
738 // From Set. | 757 // From Set. |
739 bool contains(Object object) { | 758 bool contains(Object object) { |
740 return _validKey(object) && _splay(object) == 0; | 759 return _validKey(object) && _splay(object as dynamic/*=E*/) == 0; |
741 } | 760 } |
742 | 761 |
743 bool add(E element) { | 762 bool add(E element) { |
744 int compare = _splay(element); | 763 int compare = _splay(element); |
745 if (compare == 0) return false; | 764 if (compare == 0) return false; |
746 _addNewRoot(new _SplayTreeNode(element), compare); | 765 _addNewRoot(new _SplayTreeNode(element), compare); |
747 return true; | 766 return true; |
748 } | 767 } |
749 | 768 |
750 bool remove(Object object) { | 769 bool remove(Object object) { |
751 if (!_validKey(object)) return false; | 770 if (!_validKey(object)) return false; |
752 return _remove(object) != null; | 771 return _remove(object as dynamic/*=E*/) != null; |
753 } | 772 } |
754 | 773 |
755 void addAll(Iterable<E> elements) { | 774 void addAll(Iterable<E> elements) { |
756 for (E element in elements) { | 775 for (E element in elements) { |
757 int compare = _splay(element); | 776 int compare = _splay(element); |
758 if (compare != 0) { | 777 if (compare != 0) { |
759 _addNewRoot(new _SplayTreeNode(element), compare); | 778 _addNewRoot(new _SplayTreeNode(element), compare); |
760 } | 779 } |
761 } | 780 } |
762 } | 781 } |
763 | 782 |
764 void removeAll(Iterable<Object> elements) { | 783 void removeAll(Iterable<Object> elements) { |
765 for (Object element in elements) { | 784 for (Object element in elements) { |
766 if (_validKey(element)) _remove(element); | 785 if (_validKey(element)) _remove(element as dynamic/*=E*/); |
767 } | 786 } |
768 } | 787 } |
769 | 788 |
770 void retainAll(Iterable<Object> elements) { | 789 void retainAll(Iterable<Object> elements) { |
771 // Build a set with the same sense of equality as this set. | 790 // Build a set with the same sense of equality as this set. |
772 SplayTreeSet<E> retainSet = new SplayTreeSet<E>(_comparator, _validKey); | 791 SplayTreeSet<E> retainSet = new SplayTreeSet<E>(_comparator, _validKey); |
773 int modificationCount = _modificationCount; | 792 int modificationCount = _modificationCount; |
774 for (Object object in elements) { | 793 for (Object object in elements) { |
775 if (modificationCount != _modificationCount) { | 794 if (modificationCount != _modificationCount) { |
776 // The iterator should not have side effects. | 795 // The iterator should not have side effects. |
777 throw new ConcurrentModificationError(this); | 796 throw new ConcurrentModificationError(this); |
778 } | 797 } |
779 // Equivalent to this.contains(object). | 798 // Equivalent to this.contains(object). |
780 if (_validKey(object) && _splay(object) == 0) retainSet.add(_root.key); | 799 if (_validKey(object) && _splay(object as dynamic/*=E*/) == 0) { |
| 800 retainSet.add(_root.key); |
| 801 } |
781 } | 802 } |
782 // Take over the elements from the retained set, if it differs. | 803 // Take over the elements from the retained set, if it differs. |
783 if (retainSet._count != _count) { | 804 if (retainSet._count != _count) { |
784 _root = retainSet._root; | 805 _root = retainSet._root; |
785 _count = retainSet._count; | 806 _count = retainSet._count; |
786 _modificationCount++; | 807 _modificationCount++; |
787 } | 808 } |
788 } | 809 } |
789 | 810 |
790 E lookup(Object object) { | 811 E lookup(Object object) { |
791 if (!_validKey(object)) return null; | 812 if (!_validKey(object)) return null; |
792 int comp = _splay(object); | 813 int comp = _splay(object as dynamic/*=E*/); |
793 if (comp != 0) return null; | 814 if (comp != 0) return null; |
794 return _root.key; | 815 return _root.key; |
795 } | 816 } |
796 | 817 |
797 Set<E> intersection(Set<E> other) { | 818 Set<E> intersection(Set<Object> other) { |
798 Set<E> result = new SplayTreeSet<E>(_comparator, _validKey); | 819 Set<E> result = new SplayTreeSet<E>(_comparator, _validKey); |
799 for (E element in this) { | 820 for (E element in this) { |
800 if (other.contains(element)) result.add(element); | 821 if (other.contains(element)) result.add(element); |
801 } | 822 } |
802 return result; | 823 return result; |
803 } | 824 } |
804 | 825 |
805 Set<E> difference(Set<E> other) { | 826 Set<E> difference(Set<Object> other) { |
806 Set<E> result = new SplayTreeSet<E>(_comparator, _validKey); | 827 Set<E> result = new SplayTreeSet<E>(_comparator, _validKey); |
807 for (E element in this) { | 828 for (E element in this) { |
808 if (!other.contains(element)) result.add(element); | 829 if (!other.contains(element)) result.add(element); |
809 } | 830 } |
810 return result; | 831 return result; |
811 } | 832 } |
812 | 833 |
813 Set<E> union(Set<E> other) { | 834 Set<E> union(Set<E> other) { |
814 return _clone()..addAll(other); | 835 return _clone()..addAll(other); |
815 } | 836 } |
(...skipping 12 matching lines...) Expand all Loading... |
828 return new _SplayTreeNode<E>(node.key)..left = _copyNode(node.left) | 849 return new _SplayTreeNode<E>(node.key)..left = _copyNode(node.left) |
829 ..right = _copyNode(node.right); | 850 ..right = _copyNode(node.right); |
830 } | 851 } |
831 | 852 |
832 void clear() { _clear(); } | 853 void clear() { _clear(); } |
833 | 854 |
834 Set<E> toSet() => _clone(); | 855 Set<E> toSet() => _clone(); |
835 | 856 |
836 String toString() => IterableBase.iterableToFullString(this, '{', '}'); | 857 String toString() => IterableBase.iterableToFullString(this, '{', '}'); |
837 } | 858 } |
OLD | NEW |