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); | |
8 | |
9 /** | 7 /** |
10 * A node in a splay tree. It holds the sorting key and the left | 8 * A node in a splay tree. It holds the sorting key and the left |
11 * and right children in the tree. | 9 * and right children in the tree. |
12 */ | 10 */ |
13 class _SplayTreeNode<K> { | 11 class _SplayTreeNode<K> { |
14 final K key; | 12 final K key; |
15 _SplayTreeNode<K> left; | 13 _SplayTreeNode<K> left; |
16 _SplayTreeNode<K> right; | 14 _SplayTreeNode<K> right; |
17 | 15 |
18 _SplayTreeNode(K this.key); | 16 _SplayTreeNode(K this.key); |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 return _root; | 222 return _root; |
225 } | 223 } |
226 | 224 |
227 void _clear() { | 225 void _clear() { |
228 _root = null; | 226 _root = null; |
229 _count = 0; | 227 _count = 0; |
230 _modificationCount++; | 228 _modificationCount++; |
231 } | 229 } |
232 } | 230 } |
233 | 231 |
234 class _TypeTest<T> { | |
235 bool test(v) => v is T; | |
236 } | |
237 | |
238 /* | 232 /* |
239 * A [Map] of objects that can be ordered relative to each other. | 233 * A [Map] of objects that can be ordered relative to each other. |
240 * | 234 * |
241 * The map is based on a self-balancing binary tree. It allows most operations | 235 * The map is based on a self-balancing binary tree. It allows most operations |
242 * in amortized logarithmic time. | 236 * in amortized logarithmic time. |
243 * | 237 * |
244 * Keys of the map are compared using the `compare` function passed in | 238 * Keys of the map are compared using the `compare` function passed in |
245 * the constructor. If that is omitted, the objects are assumed to be | 239 * the constructor. If that is omitted, the objects are assumed to be |
246 * [Comparable], and are compared using their [Comparable.compareTo] | 240 * [Comparable], and are compared using their [Comparable.compareTo] |
247 * method. Non-comparable objects (including `null`) will not work as keys | 241 * method. This also means that `null` is *not* allowed as a key. |
248 * in that case. | |
249 * | |
250 * To allow calling [operator[]], [remove] or [containsKey] with objects | |
251 * that are not supported by the `compare` function, an extra `isValidKey` | |
252 * predicate function can be supplied. This function is tested before | |
253 * using the `compare` function on an argument value that may not be a [K] | |
254 * value. If omitted, the `isValidKey` function defaults to testing if the | |
255 * value is a [K]. | |
256 */ | 242 */ |
257 class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> { | 243 class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> { |
258 Comparator<K> _comparator; | 244 Comparator<K> _comparator; |
259 _Predicate _validKey; | |
260 | 245 |
261 SplayTreeMap([int compare(K key1, K key2), bool isValidKey(potentialKey)]) | 246 SplayTreeMap([int compare(K key1, K key2)]) |
262 : _comparator = (compare == null) ? Comparable.compare : compare, | 247 : _comparator = (compare == null) ? Comparable.compare : compare; |
263 _validKey = (isValidKey != null) ? isValidKey : ((v) => v is K); | |
264 | 248 |
265 /** | 249 /** |
266 * Creates a [SplayTreeMap] that contains all key value pairs of [other]. | 250 * Creates a [SplayTreeMap] that contains all key value pairs of [other]. |
267 */ | 251 */ |
268 factory SplayTreeMap.from(Map<K, V> other, | 252 factory SplayTreeMap.from(Map<K, V> other, [int compare(K key1, K key2)]) => |
269 [ int compare(K key1, K key2), | 253 new SplayTreeMap(compare)..addAll(other); |
270 bool isValidKey(potentialKey)]) => | |
271 new SplayTreeMap(compare, isValidKey)..addAll(other); | |
272 | 254 |
273 /** | 255 /** |
274 * Creates a [SplayTreeMap] where the keys and values are computed from the | 256 * Creates a [SplayTreeMap] where the keys and values are computed from the |
275 * [iterable]. | 257 * [iterable]. |
276 * | 258 * |
277 * For each element of the [iterable] this constructor computes a key/value | 259 * For each element of the [iterable] this constructor computes a key/value |
278 * pair, by applying [key] and [value] respectively. | 260 * pair, by applying [key] and [value] respectively. |
279 * | 261 * |
280 * The keys of the key/value pairs do not need to be unique. The last | 262 * The keys of the key/value pairs do not need to be unique. The last |
281 * occurrence of a key will simply overwrite any previous value. | 263 * occurrence of a key will simply overwrite any previous value. |
282 * | 264 * |
283 * If no values are specified for [key] and [value] the default is the | 265 * If no values are specified for [key] and [value] the default is the |
284 * identity function. | 266 * identity function. |
285 */ | 267 */ |
286 factory SplayTreeMap.fromIterable(Iterable<K> iterable, | 268 factory SplayTreeMap.fromIterable(Iterable<K> iterable, |
287 {K key(element), V value(element), int compare(K key1, K key2), | 269 {K key(element), V value(element), int compare(K key1, K key2)}) { |
288 bool isValidKey(potentialKey) }) { | 270 SplayTreeMap<K, V> map = new SplayTreeMap<K, V>(compare); |
289 SplayTreeMap<K, V> map = new SplayTreeMap<K, V>(compare, isValidKey); | |
290 Maps._fillMapWithMappedIterable(map, iterable, key, value); | 271 Maps._fillMapWithMappedIterable(map, iterable, key, value); |
291 return map; | 272 return map; |
292 } | 273 } |
293 | 274 |
294 /** | 275 /** |
295 * Creates a [SplayTreeMap] associating the given [keys] to [values]. | 276 * Creates a [SplayTreeMap] associating the given [keys] to [values]. |
296 * | 277 * |
297 * This constructor iterates over [keys] and [values] and maps each element of | 278 * This constructor iterates over [keys] and [values] and maps each element of |
298 * [keys] to the corresponding element of [values]. | 279 * [keys] to the corresponding element of [values]. |
299 * | 280 * |
300 * If [keys] contains the same object multiple times, the last occurrence | 281 * If [keys] contains the same object multiple times, the last occurrence |
301 * overwrites the previous value. | 282 * overwrites the previous value. |
302 * | 283 * |
303 * It is an error if the two [Iterable]s don't have the same length. | 284 * It is an error if the two [Iterable]s don't have the same length. |
304 */ | 285 */ |
305 factory SplayTreeMap.fromIterables(Iterable<K> keys, Iterable<V> values, | 286 factory SplayTreeMap.fromIterables(Iterable<K> keys, Iterable<V> values, |
306 [int compare(K key1, K key2), bool isValidKey(potentialKey)]) { | 287 [int compare(K key1, K key2)]) { |
307 SplayTreeMap<K, V> map = new SplayTreeMap<K, V>(compare, isValidKey); | 288 SplayTreeMap<K, V> map = new SplayTreeMap<K, V>(compare); |
308 Maps._fillMapWithIterables(map, keys, values); | 289 Maps._fillMapWithIterables(map, keys, values); |
309 return map; | 290 return map; |
310 } | 291 } |
311 | 292 |
312 int _compare(K key1, K key2) => _comparator(key1, key2); | 293 int _compare(K key1, K key2) => _comparator(key1, key2); |
313 | 294 |
314 SplayTreeMap._internal(); | 295 SplayTreeMap._internal(); |
315 | 296 |
316 V operator [](Object key) { | 297 V operator [](Object key) { |
317 if (key == null) throw new ArgumentError(key); | 298 if (key == null) throw new ArgumentError(key); |
318 if (!_validKey(key)) return null; | 299 if (key is! K) return null; |
319 if (_root != null) { | 300 if (_root != null) { |
320 int comp = _splay(key); | 301 int comp = _splay(key); |
321 if (comp == 0) { | 302 if (comp == 0) { |
322 _SplayTreeMapNode mapRoot = _root; | 303 _SplayTreeMapNode mapRoot = _root; |
323 return mapRoot.value; | 304 return mapRoot.value; |
324 } | 305 } |
325 } | 306 } |
326 return null; | 307 return null; |
327 } | 308 } |
328 | 309 |
329 V remove(Object key) { | 310 V remove(Object key) { |
330 if (!_validKey(key)) return null; | 311 if (key is! K) return null; |
331 _SplayTreeMapNode mapRoot = _remove(key); | 312 _SplayTreeMapNode mapRoot = _remove(key); |
332 if (mapRoot != null) return mapRoot.value; | 313 if (mapRoot != null) return mapRoot.value; |
333 return null; | 314 return null; |
334 } | 315 } |
335 | 316 |
336 void operator []=(K key, V value) { | 317 void operator []=(K key, V value) { |
337 if (key == null) throw new ArgumentError(key); | 318 if (key == null) throw new ArgumentError(key); |
338 // Splay on the key to move the last node on the search path for | 319 // Splay on the key to move the last node on the search path for |
339 // the key to the root of the tree. | 320 // the key to the root of the tree. |
340 int comp = _splay(key); | 321 int comp = _splay(key); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 | 371 |
391 int get length { | 372 int get length { |
392 return _count; | 373 return _count; |
393 } | 374 } |
394 | 375 |
395 void clear() { | 376 void clear() { |
396 _clear(); | 377 _clear(); |
397 } | 378 } |
398 | 379 |
399 bool containsKey(Object key) { | 380 bool containsKey(Object key) { |
400 return _validKey(key) && _splay(key) == 0; | 381 return key is K && _splay(key) == 0; |
401 } | 382 } |
402 | 383 |
403 bool containsValue(Object value) { | 384 bool containsValue(Object value) { |
404 bool found = false; | 385 bool found = false; |
405 int initialSplayCount = _splayCount; | 386 int initialSplayCount = _splayCount; |
406 bool visit(_SplayTreeMapNode node) { | 387 bool visit(_SplayTreeMapNode node) { |
407 while (node != null) { | 388 while (node != null) { |
408 if (node.value == value) return true; | 389 if (node.value == value) return true; |
409 if (initialSplayCount != _splayCount) { | 390 if (initialSplayCount != _splayCount) { |
410 throw new ConcurrentModificationError(this); | 391 throw new ConcurrentModificationError(this); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<V> { | 576 class _SplayTreeValueIterator<K, V> extends _SplayTreeIterator<V> { |
596 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map); | 577 _SplayTreeValueIterator(SplayTreeMap<K, V> map): super(map); |
597 V _getValue(_SplayTreeMapNode node) => node.value; | 578 V _getValue(_SplayTreeMapNode node) => node.value; |
598 } | 579 } |
599 | 580 |
600 class _SplayTreeNodeIterator<K> | 581 class _SplayTreeNodeIterator<K> |
601 extends _SplayTreeIterator<_SplayTreeNode<K>> { | 582 extends _SplayTreeIterator<_SplayTreeNode<K>> { |
602 _SplayTreeNodeIterator(_SplayTree<K> map): super(map); | 583 _SplayTreeNodeIterator(_SplayTree<K> map): super(map); |
603 _SplayTreeNode<K> _getValue(_SplayTreeNode node) => node; | 584 _SplayTreeNode<K> _getValue(_SplayTreeNode node) => node; |
604 } | 585 } |
OLD | NEW |