Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: sdk/lib/collection/splay_tree.dart

Issue 1937103002: Make dart:collection strong-mode clean. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: rebase Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698