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

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

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

Powered by Google App Engine
This is Rietveld 408576698