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

Side by Side Diff: tool/input_sdk/lib/collection/splay_tree.dart

Issue 1966473002: Update linked_list, queue, splay_tree (Closed) Base URL: https://github.com/dart-lang/dev_compiler@master
Patch Set: 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
« no previous file with comments | « tool/input_sdk/lib/collection/queue.dart ('k') | tool/sdk_expected_errors.txt » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 Comparator<K> get _comparator;
70
71 _Predicate<Object> get _validKey;
72
73 /** 76 /**
74 * 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
75 * 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
76 * 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
77 * tree. This is the simplified top-down splaying algorithm from: 80 * tree. This is the simplified top-down splaying algorithm from:
78 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan. 81 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan.
79 * 82 *
80 * 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].
81 * Returns -1 if the table is empty. 84 * Returns -1 if the table is empty.
82 */ 85 */
83 int _splay(K key) { 86 int _splay(K key) {
84 if (_root == null) return -1; 87 if (_root == null) return -1;
85 88
86 // The right child of the dummy node will hold 89 // The right child of the dummy node will hold
87 // 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
88 // 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
89 // and right will always be nodes and we avoid special cases. 92 // and right will always be nodes and we avoid special cases.
90 _SplayTreeNode<K> left = _dummy; 93 Node left = _dummy;
91 _SplayTreeNode<K> right = _dummy; 94 Node right = _dummy;
92 _SplayTreeNode<K> current = _root; 95 Node current = _root;
93 int comp; 96 int comp;
94 while (true) { 97 while (true) {
95 comp = _compare(current.key, key); 98 comp = _compare(current.key, key);
96 if (comp > 0) { 99 if (comp > 0) {
97 if (current.left == null) break; 100 if (current.left == null) break;
98 comp = _compare(current.left.key, key); 101 comp = _compare(current.left.key, key);
99 if (comp > 0) { 102 if (comp > 0) {
100 // Rotate right. 103 // Rotate right.
101 _SplayTreeNode<K> tmp = current.left; 104 _SplayTreeNode<K> tmp = current.left;
102 current.left = tmp.right; 105 current.left = tmp.right;
103 tmp.right = current; 106 tmp.right = current;
104 current = tmp; 107 current = tmp;
105 if (current.left == null) break; 108 if (current.left == null) break;
106 } 109 }
107 // Link right. 110 // Link right.
108 right.left = current; 111 right.left = current;
109 right = current; 112 right = current;
110 current = current.left; 113 current = current.left;
111 } else if (comp < 0) { 114 } else if (comp < 0) {
112 if (current.right == null) break; 115 if (current.right == null) break;
113 comp = _compare(current.right.key, key); 116 comp = _compare(current.right.key, key);
114 if (comp < 0) { 117 if (comp < 0) {
115 // Rotate left. 118 // Rotate left.
116 _SplayTreeNode<K> tmp = current.right; 119 Node tmp = current.right;
117 current.right = tmp.left; 120 current.right = tmp.left;
118 tmp.left = current; 121 tmp.left = current;
119 current = tmp; 122 current = tmp;
120 if (current.right == null) break; 123 if (current.right == null) break;
121 } 124 }
122 // Link left. 125 // Link left.
123 left.right = current; 126 left.right = current;
124 left = current; 127 left = current;
125 current = current.right; 128 current = current.right;
126 } else { 129 } else {
(...skipping 10 matching lines...) Expand all
137 _dummy.right = null; 140 _dummy.right = null;
138 _dummy.left = null; 141 _dummy.left = null;
139 _splayCount++; 142 _splayCount++;
140 return comp; 143 return comp;
141 } 144 }
142 145
143 // 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
144 // anchored at [node]. 147 // anchored at [node].
145 // 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]
146 // in any parent tree or root pointer. 149 // in any parent tree or root pointer.
147 _SplayTreeNode<K> _splayMin(_SplayTreeNode<K> node) { 150 Node _splayMin(Node node) {
148 _SplayTreeNode current = node; 151 Node current = node;
149 while (current.left != null) { 152 while (current.left != null) {
150 _SplayTreeNode left = current.left; 153 Node left = current.left;
151 current.left = left.right; 154 current.left = left.right;
152 left.right = current; 155 left.right = current;
153 current = left; 156 current = left;
154 } 157 }
155 return current; 158 return current;
156 } 159 }
157 160
158 // 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
159 // anchored at [node]. 162 // anchored at [node].
160 // 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,
161 // 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]
162 // in any parent tree or root pointer. 165 // in any parent tree or root pointer.
163 _SplayTreeNode<K> _splayMax(_SplayTreeNode<K> node) { 166 Node _splayMax(Node node) {
164 _SplayTreeNode current = node; 167 Node current = node;
165 while (current.right != null) { 168 while (current.right != null) {
166 _SplayTreeNode right = current.right; 169 Node right = current.right;
167 current.right = right.left; 170 current.right = right.left;
168 right.left = current; 171 right.left = current;
169 current = right; 172 current = right;
170 } 173 }
171 return current; 174 return current;
172 } 175 }
173 176
174 _SplayTreeNode _remove(K key) { 177 Node _remove(K key) {
175 if (_root == null) return null; 178 if (_root == null) return null;
176 int comp = _splay(key); 179 int comp = _splay(key);
177 if (comp != 0) return null; 180 if (comp != 0) return null;
178 _SplayTreeNode result = _root; 181 Node result = _root;
179 _count--; 182 _count--;
180 // assert(_count >= 0); 183 // assert(_count >= 0);
181 if (_root.left == null) { 184 if (_root.left == null) {
182 _root = _root.right; 185 _root = _root.right;
183 } else { 186 } else {
184 _SplayTreeNode<K> right = _root.right; 187 Node right = _root.right;
185 // 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.
186 _root = _splayMax(_root.left); 189 _root = _splayMax(_root.left);
187 // 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
188 // root. 191 // root.
189 _root.right = right; 192 _root.right = right;
190 } 193 }
191 _modificationCount++; 194 _modificationCount++;
192 return result; 195 return result;
193 } 196 }
194 197
195 /** 198 /**
196 * Adds a new root node with the given [key] or [value]. 199 * Adds a new root node with the given [key] or [value].
197 * 200 *
198 * 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
199 * with key. 202 * with key.
200 */ 203 */
201 void _addNewRoot(_SplayTreeNode<K> node, int comp) { 204 void _addNewRoot(Node node, int comp) {
202 _count++; 205 _count++;
203 _modificationCount++; 206 _modificationCount++;
204 if (_root == null) { 207 if (_root == null) {
205 _root = node; 208 _root = node;
206 return; 209 return;
207 } 210 }
208 // assert(_count >= 0); 211 // assert(_count >= 0);
209 if (comp < 0) { 212 if (comp < 0) {
210 node.left = _root; 213 node.left = _root;
211 node.right = _root.right; 214 node.right = _root.right;
212 _root.right = null; 215 _root.right = null;
213 } else { 216 } else {
214 node.right = _root; 217 node.right = _root;
215 node.left = _root.left; 218 node.left = _root.left;
216 _root.left = null; 219 _root.left = null;
217 } 220 }
218 _root = node; 221 _root = node;
219 } 222 }
220 223
221 _SplayTreeNode get _first { 224 Node get _first {
222 if (_root == null) return null; 225 if (_root == null) return null;
223 _root = _splayMin(_root); 226 _root = _splayMin(_root);
224 return _root; 227 return _root;
225 } 228 }
226 229
227 _SplayTreeNode get _last { 230 Node get _last {
228 if (_root == null) return null; 231 if (_root == null) return null;
229 _root = _splayMax(_root); 232 _root = _splayMax(_root);
230 return _root; 233 return _root;
231 } 234 }
232 235
233 void _clear() { 236 void _clear() {
234 _root = null; 237 _root = null;
235 _count = 0; 238 _count = 0;
236 _modificationCount++; 239 _modificationCount++;
237 } 240 }
238 } 241 }
239 242
243 class _TypeTest<T> {
244 bool test(v) => v is T;
245 }
246
240 /** 247 /**
241 * A [Map] of objects that can be ordered relative to each other. 248 * A [Map] of objects that can be ordered relative to each other.
242 * 249 *
243 * The map is based on a self-balancing binary tree. It allows most operations 250 * The map is based on a self-balancing binary tree. It allows most operations
244 * in amortized logarithmic time. 251 * in amortized logarithmic time.
245 * 252 *
246 * Keys of the map are compared using the `compare` function passed in 253 * Keys of the map are compared using the `compare` function passed in
247 * the constructor, both for ordering and for equality. 254 * the constructor, both for ordering and for equality.
248 * If the map contains only the key `a`, then `map.containsKey(b)` 255 * If the map contains only the key `a`, then `map.containsKey(b)`
249 * will return `true` if and only if `compare(a, b) == 0`, 256 * will return `true` if and only if `compare(a, b) == 0`,
250 * and the value of `a == b` is not even checked. 257 * and the value of `a == b` is not even checked.
251 * If the compare function is omitted, the objects are assumed to be 258 * If the compare function is omitted, the objects are assumed to be
252 * [Comparable], and are compared using their [Comparable.compareTo] method. 259 * [Comparable], and are compared using their [Comparable.compareTo] method.
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<Object> _validKey; 277 _Predicate _validKey;
266 278
267 SplayTreeMap([int compare(K key1, K key2), 279 SplayTreeMap([int compare(K key1, K key2), bool isValidKey(potentialKey)])
268 bool isValidKey(Object potentialKey)]) 280 : _comparator = compare ?? Comparable.compare as Comparator<K>,
269 : _comparator = (compare == null) ? Comparable.compare : compare, 281 _validKey = isValidKey ?? ((v) => v is K);
270 _validKey = (isValidKey != null) ? isValidKey : ((v) => v is K);
271 282
272 /** 283 /**
273 * Creates a [SplayTreeMap] that contains all key/value pairs of [other]. 284 * Creates a [SplayTreeMap] that contains all key/value pairs of [other].
274 */ 285 */
275 factory SplayTreeMap.from(Map other, 286 factory SplayTreeMap.from(Map other,
276 [int compare(K key1, K key2), 287 [int compare(K key1, K key2),
277 bool isValidKey(Object potentialKey)]) { 288 bool isValidKey(potentialKey)]) {
278 SplayTreeMap<K, V> result = new SplayTreeMap<K, V>(); 289 SplayTreeMap<K, V> result = new SplayTreeMap<K, V>(compare, isValidKey);
279 other.forEach((k, v) { result[k] = v; }); 290 other.forEach((k, v) { result[k as K] = v as V; });
280 return result; 291 return result;
281 } 292 }
282 293
283 /** 294 /**
284 * 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
285 * [iterable]. 296 * [iterable].
286 * 297 *
287 * 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
288 * pair, by applying [key] and [value] respectively. 299 * pair, by applying [key] and [value] respectively.
289 * 300 *
290 * The keys of the key/value pairs do not need to be unique. The last 301 * The keys of the key/value pairs do not need to be unique. The last
291 * occurrence of a key will simply overwrite any previous value. 302 * occurrence of a key will simply overwrite any previous value.
292 * 303 *
293 * If no functions are specified for [key] and [value] the default is to 304 * If no functions are specified for [key] and [value] the default is to
294 * use the iterable value itself. 305 * use the iterable value itself.
295 */ 306 */
296 factory SplayTreeMap.fromIterable(Iterable iterable, 307 factory SplayTreeMap.fromIterable(Iterable iterable,
297 {K key(element), 308 {K key(element),
298 V value(element), 309 V value(element),
299 int compare(K key1, K key2), 310 int compare(K key1, K key2),
300 bool isValidKey(Object potentialKey) }) { 311 bool isValidKey(potentialKey) }) {
301 SplayTreeMap<K, V> map = new SplayTreeMap<K, V>(compare, isValidKey); 312 SplayTreeMap<K, V> map = new SplayTreeMap<K, V>(compare, isValidKey);
302 Maps._fillMapWithMappedIterable(map, iterable, key, value); 313 Maps._fillMapWithMappedIterable(map, iterable, key, value);
303 return map; 314 return map;
304 } 315 }
305 316
306 /** 317 /**
307 * Creates a [SplayTreeMap] associating the given [keys] to [values]. 318 * Creates a [SplayTreeMap] associating the given [keys] to [values].
308 * 319 *
309 * This constructor iterates over [keys] and [values] and maps each element of 320 * This constructor iterates over [keys] and [values] and maps each element of
310 * [keys] to the corresponding element of [values]. 321 * [keys] to the corresponding element of [values].
311 * 322 *
312 * If [keys] contains the same object multiple times, the last occurrence 323 * If [keys] contains the same object multiple times, the last occurrence
313 * overwrites the previous value. 324 * overwrites the previous value.
314 * 325 *
315 * It is an error if the two [Iterable]s don't have the same length. 326 * It is an error if the two [Iterable]s don't have the same length.
316 */ 327 */
317 factory SplayTreeMap.fromIterables(Iterable<K> keys, Iterable<V> values, 328 factory SplayTreeMap.fromIterables(Iterable<K> keys, Iterable<V> values,
318 [int compare(K key1, K key2), bool isValidKey(Object potentialKey)]) { 329 [int compare(K key1, K key2), bool isValidKey(potentialKey)]) {
319 SplayTreeMap<K, V> map = new SplayTreeMap<K, V>(compare, isValidKey); 330 SplayTreeMap<K, V> map = new SplayTreeMap<K, V>(compare, isValidKey);
320 Maps._fillMapWithIterables(map, keys, values); 331 Maps._fillMapWithIterables(map, keys, values);
321 return map; 332 return map;
322 } 333 }
323 334
324 int _compare(K key1, K key2) => _comparator(key1, key2); 335 int _compare(K key1, K key2) => _comparator(key1, key2);
325 336
326 SplayTreeMap._internal(); 337 SplayTreeMap._internal();
327 338
328 V operator [](Object key) { 339 V operator [](Object key) {
329 if (key == null) throw new ArgumentError(key);
330 if (!_validKey(key)) return null; 340 if (!_validKey(key)) return null;
331 if (_root != null) { 341 if (_root != null) {
332 int comp = _splay(key); 342 int comp = _splay(key as K);
333 if (comp == 0) { 343 if (comp == 0) {
334 _SplayTreeMapNode mapRoot = _root; 344 return _root.value;
335 return mapRoot.value;
336 } 345 }
337 } 346 }
338 return null; 347 return null;
339 } 348 }
340 349
341 V remove(Object key) { 350 V remove(Object key) {
342 if (!_validKey(key)) return null; 351 if (!_validKey(key)) return null;
343 _SplayTreeMapNode mapRoot = _remove(key); 352 _SplayTreeMapNode<K, V> mapRoot = _remove(key as K);
344 if (mapRoot != null) return mapRoot.value; 353 if (mapRoot != null) return mapRoot.value;
345 return null; 354 return null;
346 } 355 }
347 356
348 void operator []=(K key, V value) { 357 void operator []=(K key, V value) {
349 if (key == null) throw new ArgumentError(key); 358 if (key == null) throw new ArgumentError(key);
350 // 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
351 // the key to the root of the tree. 360 // the key to the root of the tree.
352 int comp = _splay(key); 361 int comp = _splay(key);
353 if (comp == 0) { 362 if (comp == 0) {
354 _SplayTreeMapNode mapRoot = _root; 363 _root.value = value;
355 mapRoot.value = value;
356 return; 364 return;
357 } 365 }
358 _addNewRoot(new _SplayTreeMapNode(key, value), comp); 366 _addNewRoot(new _SplayTreeMapNode(key, value), comp);
359 } 367 }
360 368
361 369
362 V putIfAbsent(K key, V ifAbsent()) { 370 V putIfAbsent(K key, V ifAbsent()) {
363 if (key == null) throw new ArgumentError(key); 371 if (key == null) throw new ArgumentError(key);
364 int comp = _splay(key); 372 int comp = _splay(key);
365 if (comp == 0) { 373 if (comp == 0) {
366 _SplayTreeMapNode mapRoot = _root; 374 return _root.value;
367 return mapRoot.value;
368 } 375 }
369 int modificationCount = _modificationCount; 376 int modificationCount = _modificationCount;
370 int splayCount = _splayCount; 377 int splayCount = _splayCount;
371 V value = ifAbsent(); 378 V value = ifAbsent();
372 if (modificationCount != _modificationCount) { 379 if (modificationCount != _modificationCount) {
373 throw new ConcurrentModificationError(this); 380 throw new ConcurrentModificationError(this);
374 } 381 }
375 if (splayCount != _splayCount) { 382 if (splayCount != _splayCount) {
376 comp = _splay(key); 383 comp = _splay(key);
377 // 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
402 409
403 int get length { 410 int get length {
404 return _count; 411 return _count;
405 } 412 }
406 413
407 void clear() { 414 void clear() {
408 _clear(); 415 _clear();
409 } 416 }
410 417
411 bool containsKey(Object key) { 418 bool containsKey(Object key) {
412 return _validKey(key) && _splay(key) == 0; 419 return _validKey(key) && _splay(key as K) == 0;
413 } 420 }
414 421
415 bool containsValue(Object value) { 422 bool containsValue(Object value) {
416 bool found = false; 423 bool found = false;
417 int initialSplayCount = _splayCount; 424 int initialSplayCount = _splayCount;
418 bool visit(_SplayTreeMapNode node) { 425 bool visit(_SplayTreeMapNode node) {
419 while (node != null) { 426 while (node != null) {
420 if (node.value == value) return true; 427 if (node.value == value) return true;
421 if (initialSplayCount != _splayCount) { 428 if (initialSplayCount != _splayCount) {
422 throw new ConcurrentModificationError(this); 429 throw new ConcurrentModificationError(this);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 if (comp > 0) return _root.key; 488 if (comp > 0) return _root.key;
482 _SplayTreeNode<K> node = _root.right; 489 _SplayTreeNode<K> node = _root.right;
483 if (node == null) return null; 490 if (node == null) return null;
484 while (node.left != null) { 491 while (node.left != null) {
485 node = node.left; 492 node = node.left;
486 } 493 }
487 return node.key; 494 return node.key;
488 } 495 }
489 } 496 }
490 497
491 abstract class _SplayTreeIterator<T> implements Iterator<T> { 498 abstract class _SplayTreeIterator<K, T> implements Iterator<T> {
492 final _SplayTree _tree; 499 final _SplayTree<K, _SplayTreeNode<K>> _tree;
493 /** 500 /**
494 * Worklist of nodes to visit. 501 * Worklist of nodes to visit.
495 * 502 *
496 * 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
497 * depth-first left-to-right traversal. Visiting each node, 504 * depth-first left-to-right traversal. Visiting each node,
498 * and their right subtrees will visit the remainder of 505 * and their right subtrees will visit the remainder of
499 * the nodes of a full traversal. 506 * the nodes of a full traversal.
500 * 507 *
501 * Only valid as long as the original tree isn't reordered. 508 * Only valid as long as the original tree isn't reordered.
502 */ 509 */
503 final List<_SplayTreeNode> _workList = <_SplayTreeNode>[]; 510 final List<_SplayTreeNode<K>> _workList = <_SplayTreeNode<K>>[];
504 511
505 /** 512 /**
506 * Original modification counter of [_tree]. 513 * Original modification counter of [_tree].
507 * 514 *
508 * Incremented on [_tree] when a key is added or removed. 515 * Incremented on [_tree] when a key is added or removed.
509 * If it changes, iteration is aborted. 516 * If it changes, iteration is aborted.
510 * 517 *
511 * Not final because some iterators may modify the tree knowingly, 518 * Not final because some iterators may modify the tree knowingly,
512 * and they update the modification count in that case. 519 * and they update the modification count in that case.
513 */ 520 */
514 int _modificationCount; 521 int _modificationCount;
515 522
516 /** 523 /**
517 * Count of splay operations on [_tree] when [_workList] was built. 524 * Count of splay operations on [_tree] when [_workList] was built.
518 * 525 *
519 * If the splay count on [_tree] increases, [_workList] becomes invalid. 526 * If the splay count on [_tree] increases, [_workList] becomes invalid.
520 */ 527 */
521 int _splayCount; 528 int _splayCount;
522 529
523 /** Current node. */ 530 /** Current node. */
524 _SplayTreeNode _currentNode; 531 _SplayTreeNode<K> _currentNode;
525 532
526 _SplayTreeIterator(_SplayTree tree) 533 _SplayTreeIterator(_SplayTree<K, _SplayTreeNode<K>> tree)
527 : _tree = tree, 534 : _tree = tree,
528 _modificationCount = tree._modificationCount, 535 _modificationCount = tree._modificationCount,
529 _splayCount = tree._splayCount { 536 _splayCount = tree._splayCount {
530 _findLeftMostDescendent(tree._root); 537 _findLeftMostDescendent(tree._root);
531 } 538 }
532 539
533 _SplayTreeIterator.startAt(_SplayTree tree, var startKey) 540 _SplayTreeIterator.startAt(_SplayTree<K, _SplayTreeNode<K>> tree, K startKey)
534 : _tree = tree, 541 : _tree = tree,
535 _modificationCount = tree._modificationCount { 542 _modificationCount = tree._modificationCount {
536 if (tree._root == null) return; 543 if (tree._root == null) return;
537 int compare = tree._splay(startKey); 544 int compare = tree._splay(startKey);
538 _splayCount = tree._splayCount; 545 _splayCount = tree._splayCount;
539 if (compare < 0) { 546 if (compare < 0) {
540 // 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.
541 _findLeftMostDescendent(tree._root.right); 548 _findLeftMostDescendent(tree._root.right);
542 } else { 549 } else {
543 _workList.add(tree._root); 550 _workList.add(tree._root);
544 } 551 }
545 } 552 }
546 553
547 T get current { 554 T get current {
548 if (_currentNode == null) return null; 555 if (_currentNode == null) return null;
549 return _getValue(_currentNode); 556 return _getValue(_currentNode);
550 } 557 }
551 558
552 void _findLeftMostDescendent(_SplayTreeNode node) { 559 void _findLeftMostDescendent(_SplayTreeNode<K> node) {
553 while (node != null) { 560 while (node != null) {
554 _workList.add(node); 561 _workList.add(node);
555 node = node.left; 562 node = node.left;
556 } 563 }
557 } 564 }
558 565
559 /** 566 /**
560 * Called when the tree structure of the tree has changed. 567 * Called when the tree structure of the tree has changed.
561 * 568 *
562 * This can be caused by a splay operation. 569 * This can be caused by a splay operation.
563 * If the key-set changes, iteration is aborted before getting 570 * If the key-set changes, iteration is aborted before getting
564 * 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
565 * only the tree that has been reordered. 572 * only the tree that has been reordered.
566 */ 573 */
567 void _rebuildWorkList(_SplayTreeNode currentNode) { 574 void _rebuildWorkList(_SplayTreeNode<K> currentNode) {
568 assert(!_workList.isEmpty); 575 assert(!_workList.isEmpty);
569 _workList.clear(); 576 _workList.clear();
570 if (currentNode == null) { 577 if (currentNode == null) {
571 _findLeftMostDescendent(_tree._root); 578 _findLeftMostDescendent(_tree._root);
572 } else { 579 } else {
573 _tree._splay(currentNode.key); 580 _tree._splay(currentNode.key);
574 _findLeftMostDescendent(_tree._root.right); 581 _findLeftMostDescendent(_tree._root.right);
575 assert(!_workList.isEmpty); 582 assert(!_workList.isEmpty);
576 } 583 }
577 } 584 }
(...skipping 12 matching lines...) Expand all
590 return false; 597 return false;
591 } 598 }
592 if (_tree._splayCount != _splayCount && _currentNode != null) { 599 if (_tree._splayCount != _splayCount && _currentNode != null) {
593 _rebuildWorkList(_currentNode); 600 _rebuildWorkList(_currentNode);
594 } 601 }
595 _currentNode = _workList.removeLast(); 602 _currentNode = _workList.removeLast();
596 _findLeftMostDescendent(_currentNode.right); 603 _findLeftMostDescendent(_currentNode.right);
597 return true; 604 return true;
598 } 605 }
599 606
600 T _getValue(_SplayTreeMapNode node); 607 T _getValue(_SplayTreeNode<K> node);
601 } 608 }
602 609
603 class _SplayTreeKeyIterable<K> extends IterableBase<K> 610 class _SplayTreeKeyIterable<K> extends Iterable<K>
604 implements EfficientLength { 611 implements EfficientLength {
605 _SplayTree<K> _tree; 612 _SplayTree<K, _SplayTreeNode<K>> _tree;
606 _SplayTreeKeyIterable(this._tree); 613 _SplayTreeKeyIterable(this._tree);
607 int get length => _tree._count; 614 int get length => _tree._count;
608 bool get isEmpty => _tree._count == 0; 615 bool get isEmpty => _tree._count == 0;
609 Iterator<K> get iterator => new _SplayTreeKeyIterator<K>(_tree); 616 Iterator<K> get iterator => new _SplayTreeKeyIterator<K>(_tree);
610 617
611 Set<K> toSet() { 618 Set<K> toSet() {
612 var setOrMap = _tree; // Both have _comparator and _validKey.
613 SplayTreeSet<K> set = 619 SplayTreeSet<K> set =
614 new SplayTreeSet<K>(setOrMap._comparator, setOrMap._validKey); 620 new SplayTreeSet<K>(_tree._comparator, _tree._validKey);
615 set._count = _tree._count; 621 set._count = _tree._count;
616 set._root = set._copyNode(_tree._root); 622 set._root = set._copyNode(_tree._root);
617 return set; 623 return set;
618 } 624 }
619 } 625 }
620 626
621 class _SplayTreeValueIterable<K, V> extends IterableBase<V> 627 class _SplayTreeValueIterable<K, V> extends Iterable<V>
622 implements EfficientLength { 628 implements EfficientLength {
623 SplayTreeMap<K, V> _map; 629 SplayTreeMap<K, V> _map;
624 _SplayTreeValueIterable(this._map); 630 _SplayTreeValueIterable(this._map);
625 int get length => _map._count; 631 int get length => _map._count;
626 bool get isEmpty => _map._count == 0; 632 bool get isEmpty => _map._count == 0;
627 Iterator<V> get iterator => new _SplayTreeValueIterator<K, V>(_map); 633 Iterator<V> get iterator => new _SplayTreeValueIterator<K, V>(_map);
628 } 634 }
629 635
630 class _SplayTreeKeyIterator<K> extends _SplayTreeIterator<K> { 636 class _SplayTreeKeyIterator<K> extends _SplayTreeIterator<K, K> {
631 _SplayTreeKeyIterator(_SplayTree<K> map): super(map); 637 _SplayTreeKeyIterator(_SplayTree<K, _SplayTreeNode<K>> map): super(map);
632 K _getValue(_SplayTreeNode node) => node.key; 638 K _getValue(_SplayTreeNode<K> node) => node.key;
633 } 639 }
634 640
635 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<V> { 641 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<K, V> {
636 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map); 642 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map);
637 V _getValue(_SplayTreeMapNode node) => node.value; 643 V _getValue(_SplayTreeNode<K> node) {
644 _SplayTreeMapNode<K, V> mapNode = node as _SplayTreeMapNode<K, V>;
645 return mapNode.value;
646 }
638 } 647 }
639 648
640 class _SplayTreeNodeIterator<K> 649 class _SplayTreeNodeIterator<K>
641 extends _SplayTreeIterator<_SplayTreeNode<K>> { 650 extends _SplayTreeIterator<K, _SplayTreeNode<K>> {
642 _SplayTreeNodeIterator(_SplayTree<K> tree): super(tree); 651 _SplayTreeNodeIterator(_SplayTree<K, _SplayTreeNode<K>> tree): super(tree);
643 _SplayTreeNodeIterator.startAt(_SplayTree<K> tree, var startKey) 652 _SplayTreeNodeIterator.startAt(
653 _SplayTree<K, _SplayTreeNode<K>> tree, K startKey)
644 : super.startAt(tree, startKey); 654 : super.startAt(tree, startKey);
645 _SplayTreeNode<K> _getValue(_SplayTreeNode node) => node; 655 _SplayTreeNode<K> _getValue(_SplayTreeNode<K> node) => node;
646 } 656 }
647 657
648 658
649 /** 659 /**
650 * A [Set] of objects that can be ordered relative to each other. 660 * A [Set] of objects that can be ordered relative to each other.
651 * 661 *
652 * The set is based on a self-balancing binary tree. It allows most operations 662 * The set is based on a self-balancing binary tree. It allows most operations
653 * in amortized logarithmic time. 663 * in amortized logarithmic time.
654 * 664 *
655 * Elements of the set are compared using the `compare` function passed in 665 * Elements of the set are compared using the `compare` function passed in
656 * the constructor, both for ordering and for equality. 666 * the constructor, both for ordering and for equality.
657 * If the set contains only an object `a`, then `set.contains(b)` 667 * If the set contains only an object `a`, then `set.contains(b)`
658 * will return `true` if and only if `compare(a, b) == 0`, 668 * will return `true` if and only if `compare(a, b) == 0`,
659 * and the value of `a == b` is not even checked. 669 * and the value of `a == b` is not even checked.
660 * If the compare function is omitted, the objects are assumed to be 670 * If the compare function is omitted, the objects are assumed to be
661 * [Comparable], and are compared using their [Comparable.compareTo] method. 671 * [Comparable], and are compared using their [Comparable.compareTo] method.
662 * Non-comparable objects (including `null`) will not work as an element 672 * Non-comparable objects (including `null`) will not work as an element
663 * in that case. 673 * in that case.
664 */ 674 */
665 class SplayTreeSet<E> extends _SplayTree<E> with IterableMixin<E>, SetMixin<E> { 675 class SplayTreeSet<E> extends _SplayTree<E, _SplayTreeNode<E>>
676 with IterableMixin<E>, SetMixin<E> {
677 _SplayTreeNode<E> _root;
678 final _SplayTreeNode<E> _dummy = new _SplayTreeNode<E>(null);
679
666 Comparator<E> _comparator; 680 Comparator<E> _comparator;
667 _Predicate<Object> _validKey; 681 _Predicate _validKey;
668 682
669 /** 683 /**
670 * Create a new [SplayTreeSet] with the given compare function. 684 * Create a new [SplayTreeSet] with the given compare function.
671 * 685 *
672 * If the [compare] function is omitted, it defaults to [Comparable.compare], 686 * If the [compare] function is omitted, it defaults to [Comparable.compare],
673 * and the elements must be comparable. 687 * and the elements must be comparable.
674 * 688 *
675 * A provided `compare` function may not work on all objects. It may not even 689 * A provided `compare` function may not work on all objects. It may not even
676 * work on all `E` instances. 690 * work on all `E` instances.
677 * 691 *
678 * For operations that add elements to the set, the user is supposed to not 692 * For operations that add elements to the set, the user is supposed to not
679 * pass in objects that doesn't work with the compare function. 693 * pass in objects that doesn't work with the compare function.
680 * 694 *
681 * The methods [contains], [remove], [lookup], [removeAll] or [retainAll] 695 * The methods [contains], [remove], [lookup], [removeAll] or [retainAll]
682 * are typed to accept any object(s), and the [isValidKey] test can used to 696 * are typed to accept any object(s), and the [isValidKey] test can used to
683 * filter those objects before handing them to the `compare` function. 697 * filter those objects before handing them to the `compare` function.
684 * 698 *
685 * If [isValidKey] is provided, only values satisfying `isValidKey(other)` 699 * If [isValidKey] is provided, only values satisfying `isValidKey(other)`
686 * are compared using the `compare` method in the methods mentioned above. 700 * are compared using the `compare` method in the methods mentioned above.
687 * If the `isValidKey` function returns false for an object, it is assumed to 701 * If the `isValidKey` function returns false for an object, it is assumed to
688 * not be in the set. 702 * not be in the set.
689 * 703 *
690 * If omitted, the `isValidKey` function defaults to checking against the 704 * If omitted, the `isValidKey` function defaults to checking against the
691 * type parameter: `other is E`. 705 * type parameter: `other is E`.
692 */ 706 */
693 SplayTreeSet([int compare(E key1, E key2), 707 SplayTreeSet([int compare(E key1, E key2), bool isValidKey(potentialKey)])
694 bool isValidKey(Object potentialKey)]) 708 : _comparator = compare ?? Comparable.compare as Comparator<E>,
695 : _comparator = (compare == null) ? Comparable.compare : compare, 709 _validKey = isValidKey ?? ((v) => v is E);
696 _validKey = (isValidKey != null) ? isValidKey : ((v) => v is E);
697 710
698 /** 711 /**
699 * Creates a [SplayTreeSet] that contains all [elements]. 712 * Creates a [SplayTreeSet] that contains all [elements].
700 * 713 *
701 * The set works as if created by `new SplayTreeSet<E>(compare, isValidKey)`. 714 * The set works as if created by `new SplayTreeSet<E>(compare, isValidKey)`.
702 * 715 *
703 * All the [elements] should be valid as arguments to the [compare] function. 716 * All the [elements] should be valid as arguments to the [compare] function.
704 */ 717 */
705 factory SplayTreeSet.from(Iterable elements, 718 factory SplayTreeSet.from(Iterable elements,
706 [int compare(E key1, E key2), 719 [int compare(E key1, E key2),
707 bool isValidKey(Object potentialKey)]) { 720 bool isValidKey(potentialKey)]) {
708 SplayTreeSet<E> result = new SplayTreeSet<E>(compare, isValidKey); 721 SplayTreeSet<E> result = new SplayTreeSet<E>(compare, isValidKey);
709 for (final E element in elements) { 722 for (final element in elements) {
710 result.add(element); 723 result.add(element as E);
711 } 724 }
712 return result; 725 return result;
713 } 726 }
714 727
715 int _compare(E e1, E e2) => _comparator(e1, e2); 728 int _compare(E e1, E e2) => _comparator(e1, e2);
716 729
717 // From Iterable. 730 // From Iterable.
718 731
719 Iterator<E> get iterator => new _SplayTreeKeyIterator<E>(this); 732 Iterator<E> get iterator => new _SplayTreeKeyIterator<E>(this);
720 733
(...skipping 12 matching lines...) Expand all
733 } 746 }
734 747
735 E get single { 748 E get single {
736 if (_count == 0) throw IterableElementError.noElement(); 749 if (_count == 0) throw IterableElementError.noElement();
737 if (_count > 1) throw IterableElementError.tooMany(); 750 if (_count > 1) throw IterableElementError.tooMany();
738 return _root.key; 751 return _root.key;
739 } 752 }
740 753
741 // From Set. 754 // From Set.
742 bool contains(Object object) { 755 bool contains(Object object) {
743 return _validKey(object) && _splay(object) == 0; 756 return _validKey(object) && _splay(object as E) == 0;
744 } 757 }
745 758
746 bool add(E element) { 759 bool add(E element) {
747 int compare = _splay(element); 760 int compare = _splay(element);
748 if (compare == 0) return false; 761 if (compare == 0) return false;
749 _addNewRoot(new _SplayTreeNode(element), compare); 762 _addNewRoot(new _SplayTreeNode(element), compare);
750 return true; 763 return true;
751 } 764 }
752 765
753 bool remove(Object object) { 766 bool remove(Object object) {
754 if (!_validKey(object)) return false; 767 if (!_validKey(object)) return false;
755 return _remove(object) != null; 768 return _remove(object as E) != null;
756 } 769 }
757 770
758 void addAll(Iterable<E> elements) { 771 void addAll(Iterable<E> elements) {
759 for (E element in elements) { 772 for (E element in elements) {
760 int compare = _splay(element); 773 int compare = _splay(element);
761 if (compare != 0) { 774 if (compare != 0) {
762 _addNewRoot(new _SplayTreeNode(element), compare); 775 _addNewRoot(new _SplayTreeNode(element), compare);
763 } 776 }
764 } 777 }
765 } 778 }
766 779
767 void removeAll(Iterable<Object> elements) { 780 void removeAll(Iterable<Object> elements) {
768 for (Object element in elements) { 781 for (Object element in elements) {
769 if (_validKey(element)) _remove(element); 782 if (_validKey(element)) _remove(element as E);
770 } 783 }
771 } 784 }
772 785
773 void retainAll(Iterable<Object> elements) { 786 void retainAll(Iterable<Object> elements) {
774 // Build a set with the same sense of equality as this set. 787 // Build a set with the same sense of equality as this set.
775 SplayTreeSet<E> retainSet = new SplayTreeSet<E>(_comparator, _validKey); 788 SplayTreeSet<E> retainSet = new SplayTreeSet<E>(_comparator, _validKey);
776 int modificationCount = _modificationCount; 789 int modificationCount = _modificationCount;
777 for (Object object in elements) { 790 for (Object object in elements) {
778 if (modificationCount != _modificationCount) { 791 if (modificationCount != _modificationCount) {
779 // The iterator should not have side effects. 792 // The iterator should not have side effects.
780 throw new ConcurrentModificationError(this); 793 throw new ConcurrentModificationError(this);
781 } 794 }
782 // Equivalent to this.contains(object). 795 // Equivalent to this.contains(object).
783 if (_validKey(object) && _splay(object) == 0) retainSet.add(_root.key); 796 if (_validKey(object) && _splay(object as E) == 0) {
797 retainSet.add(_root.key);
798 }
784 } 799 }
785 // Take over the elements from the retained set, if it differs. 800 // Take over the elements from the retained set, if it differs.
786 if (retainSet._count != _count) { 801 if (retainSet._count != _count) {
787 _root = retainSet._root; 802 _root = retainSet._root;
788 _count = retainSet._count; 803 _count = retainSet._count;
789 _modificationCount++; 804 _modificationCount++;
790 } 805 }
791 } 806 }
792 807
793 E lookup(Object object) { 808 E lookup(Object object) {
794 if (!_validKey(object)) return null; 809 if (!_validKey(object)) return null;
795 int comp = _splay(object); 810 int comp = _splay(object as E);
796 if (comp != 0) return null; 811 if (comp != 0) return null;
797 return _root.key; 812 return _root.key;
798 } 813 }
799 814
800 Set<E> intersection(Set<Object> other) { 815 Set<E> intersection(Set<Object> other) {
801 Set<E> result = new SplayTreeSet<E>(_comparator, _validKey); 816 Set<E> result = new SplayTreeSet<E>(_comparator, _validKey);
802 for (E element in this) { 817 for (E element in this) {
803 if (other.contains(element)) result.add(element); 818 if (other.contains(element)) result.add(element);
804 } 819 }
805 return result; 820 return result;
(...skipping 25 matching lines...) Expand all
831 return new _SplayTreeNode<E>(node.key)..left = _copyNode(node.left) 846 return new _SplayTreeNode<E>(node.key)..left = _copyNode(node.left)
832 ..right = _copyNode(node.right); 847 ..right = _copyNode(node.right);
833 } 848 }
834 849
835 void clear() { _clear(); } 850 void clear() { _clear(); }
836 851
837 Set<E> toSet() => _clone(); 852 Set<E> toSet() => _clone();
838 853
839 String toString() => IterableBase.iterableToFullString(this, '{', '}'); 854 String toString() => IterableBase.iterableToFullString(this, '{', '}');
840 } 855 }
OLDNEW
« no previous file with comments | « tool/input_sdk/lib/collection/queue.dart ('k') | tool/sdk_expected_errors.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698