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

Side by Side Diff: sdk/lib/core/map.dart

Issue 11783009: Big merge from experimental to bleeding edge. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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/core/list.dart ('k') | sdk/lib/core/num.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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.core; 5 part of dart.core;
6 6
7 /** 7 /**
8 * A [Map] is an associative container, mapping a key to a value. 8 * A [Map] is an associative container, mapping a key to a value.
9 * Null values are supported, but null keys are not. 9 * Null values are supported, but null keys are not.
10 */ 10 */
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 * Removes all pairs from the map. 62 * Removes all pairs from the map.
63 */ 63 */
64 void clear(); 64 void clear();
65 65
66 /** 66 /**
67 * Applies [f] to each {key, value} pair of the map. 67 * Applies [f] to each {key, value} pair of the map.
68 */ 68 */
69 void forEach(void f(K key, V value)); 69 void forEach(void f(K key, V value));
70 70
71 /** 71 /**
72 * Returns a collection containing all the keys in the map. 72 * The keys of [this].
73 */ 73 */
74 Collection<K> get keys; 74 // TODO(floitsch): this should return a [Set].
75 Iterable<K> get keys;
75 76
76 /** 77 /**
77 * Returns a collection containing all the values in the map. 78 * The values of [this].
78 */ 79 */
79 Collection<V> get values; 80 Iterable<V> get values;
80 81
81 /** 82 /**
82 * The number of {key, value} pairs in the map. 83 * The number of {key, value} pairs in the map.
83 */ 84 */
84 int get length; 85 int get length;
85 86
86 /** 87 /**
87 * Returns true if there is no {key, value} pair in the map. 88 * Returns true if there is no {key, value} pair in the map.
88 */ 89 */
89 bool get isEmpty; 90 bool get isEmpty;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 // The sentinel when a key is deleted from the map. 162 // The sentinel when a key is deleted from the map.
162 static const _DeletedKeySentinel _DELETED_KEY = const _DeletedKeySentinel(); 163 static const _DeletedKeySentinel _DELETED_KEY = const _DeletedKeySentinel();
163 164
164 // The initial capacity of a hash map. 165 // The initial capacity of a hash map.
165 static const int _INITIAL_CAPACITY = 8; // must be power of 2 166 static const int _INITIAL_CAPACITY = 8; // must be power of 2
166 167
167 _HashMapImpl() { 168 _HashMapImpl() {
168 _numberOfEntries = 0; 169 _numberOfEntries = 0;
169 _numberOfDeleted = 0; 170 _numberOfDeleted = 0;
170 _loadLimit = _computeLoadLimit(_INITIAL_CAPACITY); 171 _loadLimit = _computeLoadLimit(_INITIAL_CAPACITY);
171 _keys = new List(_INITIAL_CAPACITY); 172 _keys = new List.fixedLength(_INITIAL_CAPACITY);
172 _values = new List<V>(_INITIAL_CAPACITY); 173 _values = new List<V>.fixedLength(_INITIAL_CAPACITY);
173 } 174 }
174 175
175 factory _HashMapImpl.from(Map<K, V> other) { 176 factory _HashMapImpl.from(Map<K, V> other) {
176 Map<K, V> result = new _HashMapImpl<K, V>(); 177 Map<K, V> result = new _HashMapImpl<K, V>();
177 other.forEach((K key, V value) { result[key] = value; }); 178 other.forEach((K key, V value) { result[key] = value; });
178 return result; 179 return result;
179 } 180 }
180 181
181 static int _computeLoadLimit(int capacity) { 182 static int _computeLoadLimit(int capacity) {
182 return (capacity * 3) ~/ 4; 183 return (capacity * 3) ~/ 4;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 static bool _isPowerOfTwo(int x) { 269 static bool _isPowerOfTwo(int x) {
269 return ((x & (x - 1)) == 0); 270 return ((x & (x - 1)) == 0);
270 } 271 }
271 272
272 void _grow(int newCapacity) { 273 void _grow(int newCapacity) {
273 assert(_isPowerOfTwo(newCapacity)); 274 assert(_isPowerOfTwo(newCapacity));
274 int capacity = _keys.length; 275 int capacity = _keys.length;
275 _loadLimit = _computeLoadLimit(newCapacity); 276 _loadLimit = _computeLoadLimit(newCapacity);
276 List oldKeys = _keys; 277 List oldKeys = _keys;
277 List<V> oldValues = _values; 278 List<V> oldValues = _values;
278 _keys = new List(newCapacity); 279 _keys = new List.fixedLength(newCapacity);
279 _values = new List<V>(newCapacity); 280 _values = new List<V>.fixedLength(newCapacity);
280 for (int i = 0; i < capacity; i++) { 281 for (int i = 0; i < capacity; i++) {
281 // [key] can be either of type [K] or [_DeletedKeySentinel]. 282 // [key] can be either of type [K] or [_DeletedKeySentinel].
282 Object key = oldKeys[i]; 283 Object key = oldKeys[i];
283 // If there is no key, we don't need to deal with the current slot. 284 // If there is no key, we don't need to deal with the current slot.
284 if (key == null || identical(key, _DELETED_KEY)) { 285 if (key == null || identical(key, _DELETED_KEY)) {
285 continue; 286 continue;
286 } 287 }
287 V value = oldValues[i]; 288 V value = oldValues[i];
288 // Insert the {key, value} pair in their new slot. 289 // Insert the {key, value} pair in their new slot.
289 int newIndex = _probeForAdding(key); 290 int newIndex = _probeForAdding(key);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 345
345 bool get isEmpty { 346 bool get isEmpty {
346 return _numberOfEntries == 0; 347 return _numberOfEntries == 0;
347 } 348 }
348 349
349 int get length { 350 int get length {
350 return _numberOfEntries; 351 return _numberOfEntries;
351 } 352 }
352 353
353 void forEach(void f(K key, V value)) { 354 void forEach(void f(K key, V value)) {
354 int length = _keys.length; 355 Iterator<int> it = new _HashMapImplIndexIterator(this);
355 for (int i = 0; i < length; i++) { 356 while (it.moveNext()) {
356 var key = _keys[i]; 357 f(_keys[it.current], _values[it.current]);
357 if ((key != null) && (!identical(key, _DELETED_KEY))) {
358 f(key, _values[i]);
359 }
360 } 358 }
361 } 359 }
362 360
361 Iterable<K> get keys => new _HashMapImplKeyIterable<K>(this);
363 362
364 Collection<K> get keys { 363 Iterable<V> get values => new _HashMapImplValueIterable<V>(this);
365 List<K> list = new List<K>(length);
366 int i = 0;
367 forEach((K key, V value) {
368 list[i++] = key;
369 });
370 return list;
371 }
372
373 Collection<V> get values {
374 List<V> list = new List<V>(length);
375 int i = 0;
376 forEach((K key, V value) {
377 list[i++] = value;
378 });
379 return list;
380 }
381 364
382 bool containsKey(K key) { 365 bool containsKey(K key) {
383 return (_probeForLookup(key) != -1); 366 return (_probeForLookup(key) != -1);
384 } 367 }
385 368
386 bool containsValue(V value) { 369 bool containsValue(V value) => values.contains(value);
387 int length = _values.length;
388 for (int i = 0; i < length; i++) {
389 var key = _keys[i];
390 if ((key != null) && (!identical(key, _DELETED_KEY))) {
391 if (_values[i] == value) return true;
392 }
393 }
394 return false;
395 }
396 370
397 String toString() { 371 String toString() {
398 return Maps.mapToString(this); 372 return Maps.mapToString(this);
399 } 373 }
400 } 374 }
401 375
376 class _HashMapImplKeyIterable<E> extends Iterable<E> {
377 final _HashMapImpl _map;
378 _HashMapImplKeyIterable(this._map);
379
380 Iterator<E> get iterator => new _HashMapImplKeyIterator<E>(_map);
381 }
382
383 class _HashMapImplValueIterable<E> extends Iterable<E> {
384 final _HashMapImpl _map;
385 _HashMapImplValueIterable(this._map);
386
387 Iterator<E> get iterator => new _HashMapImplValueIterator<E>(_map);
388 }
389
390 abstract class _HashMapImplIterator<E> implements Iterator<E> {
391 final _HashMapImpl _map;
392 int _index = -1;
393 E _current;
394
395 _HashMapImplIterator(this._map);
396
397 E _computeCurrentFromIndex(int index, List keys, List values);
398
399 bool moveNext() {
400 int length = _map._keys.length;
401 int newIndex = _index + 1;
402 while (newIndex < length) {
403 var key = _map._keys[newIndex];
404 if ((key != null) && (!identical(key, _HashMapImpl._DELETED_KEY))) {
405 _current = _computeCurrentFromIndex(newIndex, _map._keys, _map._values);
406 _index = newIndex;
407 return true;
408 }
409 newIndex++;
410 }
411 _index = length;
412 _current = null;
413 return false;
414 }
415
416 E get current => _current;
417 }
418
419 class _HashMapImplKeyIterator<E> extends _HashMapImplIterator<E> {
420 _HashMapImplKeyIterator(_HashMapImpl map) : super(map);
421
422 E _computeCurrentFromIndex(int index, List keys, List values) {
423 return keys[index];
424 }
425 }
426
427 class _HashMapImplValueIterator<E> extends _HashMapImplIterator<E> {
428 _HashMapImplValueIterator(_HashMapImpl map) : super(map);
429
430 E _computeCurrentFromIndex(int index, List keys, List values) {
431 return values[index];
432 }
433 }
434
435 class _HashMapImplIndexIterator extends _HashMapImplIterator<int> {
436 _HashMapImplIndexIterator(_HashMapImpl map) : super(map);
437
438 int _computeCurrentFromIndex(int index, List keys, List values) {
439 return index;
440 }
441 }
402 442
403 /** 443 /**
404 * A singleton sentinel used to represent when a key is deleted from the map. 444 * A singleton sentinel used to represent when a key is deleted from the map.
405 * We can't use [: const Object() :] as a sentinel because it would end up 445 * We can't use [: const Object() :] as a sentinel because it would end up
406 * canonicalized and then we cannot distinguish the deleted key from the 446 * canonicalized and then we cannot distinguish the deleted key from the
407 * canonicalized [: Object() :]. 447 * canonicalized [: Object() :].
408 */ 448 */
409 class _DeletedKeySentinel { 449 class _DeletedKeySentinel {
410 const _DeletedKeySentinel(); 450 const _DeletedKeySentinel();
411 } 451 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 506
467 V putIfAbsent(K key, V ifAbsent()) { 507 V putIfAbsent(K key, V ifAbsent()) {
468 V value = this[key]; 508 V value = this[key];
469 if ((this[key] == null) && !(containsKey(key))) { 509 if ((this[key] == null) && !(containsKey(key))) {
470 value = ifAbsent(); 510 value = ifAbsent();
471 this[key] = value; 511 this[key] = value;
472 } 512 }
473 return value; 513 return value;
474 } 514 }
475 515
476 Collection<K> get keys { 516 Iterable<K> get keys {
477 List<K> list = new List<K>(length); 517 return new MappedIterable<_KeyValuePair<K, V>, K>(
478 int index = 0; 518 _list, (_KeyValuePair<K, V> entry) => entry.key);
479 _list.forEach((_KeyValuePair<K, V> entry) {
480 list[index++] = entry.key;
481 });
482 assert(index == length);
483 return list;
484 } 519 }
485 520
486 521
487 Collection<V> get values { 522 Iterable<V> get values {
488 List<V> list = new List<V>(length); 523 return new MappedIterable<_KeyValuePair<K, V>, V>(
489 int index = 0; 524 _list, (_KeyValuePair<K, V> entry) => entry.value);
490 _list.forEach((_KeyValuePair<K, V> entry) {
491 list[index++] = entry.value;
492 });
493 assert(index == length);
494 return list;
495 } 525 }
496 526
497 void forEach(void f(K key, V value)) { 527 void forEach(void f(K key, V value)) {
498 _list.forEach((_KeyValuePair<K, V> entry) { 528 _list.forEach((_KeyValuePair<K, V> entry) {
499 f(entry.key, entry.value); 529 f(entry.key, entry.value);
500 }); 530 });
501 } 531 }
502 532
503 bool containsKey(K key) { 533 bool containsKey(K key) {
504 return _map.containsKey(key); 534 return _map.containsKey(key);
505 } 535 }
506 536
507 bool containsValue(V value) { 537 bool containsValue(V value) {
508 return _list.some((_KeyValuePair<K, V> entry) { 538 return _list.any((_KeyValuePair<K, V> entry) {
509 return (entry.value == value); 539 return (entry.value == value);
510 }); 540 });
511 } 541 }
512 542
513 int get length { 543 int get length {
514 return _map.length; 544 return _map.length;
515 } 545 }
516 546
517 bool get isEmpty { 547 bool get isEmpty {
518 return length == 0; 548 return length == 0;
519 } 549 }
520 550
521 void clear() { 551 void clear() {
522 _map.clear(); 552 _map.clear();
523 _list.clear(); 553 _list.clear();
524 } 554 }
525 555
526 String toString() { 556 String toString() {
527 return Maps.mapToString(this); 557 return Maps.mapToString(this);
528 } 558 }
529 } 559 }
560
OLDNEW
« no previous file with comments | « sdk/lib/core/list.dart ('k') | sdk/lib/core/num.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698