| Index: runtime/lib/collection_patch.dart
|
| ===================================================================
|
| --- runtime/lib/collection_patch.dart (revision 44194)
|
| +++ runtime/lib/collection_patch.dart (working copy)
|
| @@ -918,10 +918,8 @@
|
| if (equals == null) {
|
| if (_useInternalCached) {
|
| return new _InternalLinkedHashMap<K, V>();
|
| - } else if (_useCompactCached) {
|
| + } else {
|
| return new _CompactLinkedHashMap<K, V>();
|
| - } else {
|
| - return new _LinkedHashMap<K, V>();
|
| }
|
| }
|
| hashCode = _defaultHashCode;
|
| @@ -928,7 +926,7 @@
|
| } else {
|
| if (identical(identityHashCode, hashCode) &&
|
| identical(identical, equals)) {
|
| - return new _LinkedIdentityHashMap<K, V>();
|
| + return new _CompactLinkedIdentityHashMap<K, V>();
|
| }
|
| if (equals == null) {
|
| equals = _defaultEquals;
|
| @@ -942,124 +940,16 @@
|
| equals = _defaultEquals;
|
| }
|
| }
|
| - return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
|
| + return new _CompactLinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
|
| }
|
|
|
| - /* patch */ factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>;
|
| + /* patch */ factory LinkedHashMap.identity() =
|
| + _CompactLinkedIdentityHashMap<K, V>;
|
|
|
| static final bool _useInternalCached = _useInternal;
|
| static bool get _useInternal native "LinkedHashMap_useInternal";
|
| - static final bool _useCompactCached = _useCompact;
|
| - static bool get _useCompact native "LinkedHashMap_useCompact";
|
| }
|
|
|
| -// Methods that are exactly the same in all three linked hash map variants.
|
| -abstract class _LinkedHashMapMixin<K, V> implements LinkedHashMap<K, V> {
|
| - var _nextEntry;
|
| - var _previousEntry;
|
| -
|
| -
|
| - bool containsValue(Object value) {
|
| - int modificationCount = _modificationCount;
|
| - var cursor = _nextEntry;
|
| - while (!identical(cursor, this)) {
|
| - _HashMapEntry entry = cursor;
|
| - if (entry.value == value) return true;
|
| - if (modificationCount != _modificationCount) {
|
| - throw new ConcurrentModificationError(this);
|
| - }
|
| - cursor = cursor._nextEntry;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - void forEach(void action(K key, V value)) {
|
| - int modificationCount = _modificationCount;
|
| - var cursor = _nextEntry;
|
| - while (!identical(cursor, this)) {
|
| - _HashMapEntry entry = cursor;
|
| - action(entry.key, entry.value);
|
| - if (modificationCount != _modificationCount) {
|
| - throw new ConcurrentModificationError(this);
|
| - }
|
| - cursor = cursor._nextEntry;
|
| - }
|
| - }
|
| -
|
| - void clear() {
|
| - _nextEntry = _previousEntry = this;
|
| - _buckets = new List(_HashMap._INITIAL_CAPACITY);
|
| - if (_elementCount > 0) {
|
| - _elementCount = 0;
|
| - _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
|
| - }
|
| - }
|
| -
|
| - void _addEntry(List buckets, int index, int length,
|
| - K key, V value, int hashCode) {
|
| - _HashMapEntry entry =
|
| - new _LinkedHashMapEntry(key, value, hashCode, buckets[index],
|
| - _previousEntry, this);
|
| - buckets[index] = entry;
|
| - int newElements = _elementCount + 1;
|
| - _elementCount = newElements;
|
| -
|
| - // If we end up with more than 75% non-empty entries, we
|
| - // resize the backing store.
|
| - if ((newElements << 2) > ((length << 1) + length)) _resize();
|
| - _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
|
| - }
|
| -
|
| - void _removeEntry(_LinkedHashMapEntry entry,
|
| - _HashMapEntry previousInBucket,
|
| - int bucketIndex) {
|
| - var previousInChain = entry._previousEntry;
|
| - var nextInChain = entry._nextEntry;
|
| - previousInChain._nextEntry = nextInChain;
|
| - nextInChain._previousEntry = previousInChain;
|
| - if (previousInBucket == null) {
|
| - _buckets[bucketIndex] = entry.next;
|
| - } else {
|
| - previousInBucket.next = entry.next;
|
| - }
|
| - }
|
| -
|
| -
|
| - Iterable<K> get keys => new _LinkedHashMapKeyIterable<K>(this);
|
| - Iterable<V> get values => new _LinkedHashMapValueIterable<V>(this);
|
| -}
|
| -
|
| -class _LinkedHashMap<K, V> extends _HashMap<K, V>
|
| - with _LinkedHashMapMixin<K, V> {
|
| - _LinkedHashMap() {
|
| - _nextEntry = _previousEntry = this;
|
| - }
|
| -
|
| - Set<K> _newKeySet() => new _LinkedHashSet<K>();
|
| -}
|
| -
|
| -class _LinkedIdentityHashMap<K, V> extends _IdentityHashMap<K, V>
|
| - with _LinkedHashMapMixin<K, V> {
|
| - _LinkedIdentityHashMap() {
|
| - _nextEntry = _previousEntry = this;
|
| - }
|
| -
|
| - Set<K> _newKeySet() => new _LinkedIdentityHashSet<K>();
|
| -}
|
| -
|
| -class _LinkedCustomHashMap<K, V> extends _CustomHashMap<K, V>
|
| - with _LinkedHashMapMixin<K, V> {
|
| - _LinkedCustomHashMap(bool equals(K key1, K key2),
|
| - int hashCode(K key),
|
| - bool isValidKey(potentialKey))
|
| - : super(equals, hashCode, isValidKey) {
|
| - _nextEntry = _previousEntry = this;
|
| - }
|
| - Set<K> _newKeySet() =>
|
| - new _LinkedCustomHashSet<K>(_equals, _hashCode, _validKey);
|
| -}
|
| -
|
| -
|
| patch class LinkedHashSet<E> {
|
| /* patch */ factory LinkedHashSet({ bool equals(E e1, E e2),
|
| int hashCode(E e),
|
| @@ -1067,17 +957,13 @@
|
| if (isValidKey == null) {
|
| if (hashCode == null) {
|
| if (equals == null) {
|
| - if (LinkedHashMap._useCompactCached) {
|
| - return new _CompactLinkedHashSet<E>();
|
| - } else {
|
| - return new _LinkedHashSet<E>();
|
| - }
|
| + return new _CompactLinkedHashSet<E>();
|
| }
|
| hashCode = _defaultHashCode;
|
| } else {
|
| if (identical(identityHashCode, hashCode) &&
|
| identical(identical, equals)) {
|
| - return new _LinkedIdentityHashSet<E>();
|
| + return new _CompactLinkedIdentityHashSet<E>();
|
| }
|
| if (equals == null) {
|
| equals = _defaultEquals;
|
| @@ -1091,196 +977,9 @@
|
| equals = _defaultEquals;
|
| }
|
| }
|
| - return new _LinkedCustomHashSet<E>(equals, hashCode, isValidKey);
|
| + return new _CompactLinkedCustomHashSet<E>(equals, hashCode, isValidKey);
|
| }
|
|
|
| - /* patch */ factory LinkedHashSet.identity() = _LinkedIdentityHashSet<E>;
|
| + /* patch */ factory LinkedHashSet.identity() =
|
| + _CompactLinkedIdentityHashSet<E>;
|
| }
|
| -
|
| -class _LinkedHashSetEntry extends _HashSetEntry {
|
| - /// Links this element into a double-linked list of elements of a hash set.
|
| - /// The hash set object itself is used as the head entry of the list, so
|
| - /// the field is typed as "var".
|
| - /// Both links are initialized to `this` when the object is created.
|
| - var _nextEntry;
|
| - var _previousEntry;
|
| - _LinkedHashSetEntry(var key, int hashCode, _LinkedHashSetEntry next,
|
| - this._previousEntry, this._nextEntry)
|
| - : super(key, hashCode, next) {
|
| - _previousEntry._nextEntry = _nextEntry._previousEntry = this;
|
| - }
|
| -
|
| - _LinkedHashSetEntry remove() {
|
| - _previousEntry._nextEntry = _nextEntry;
|
| - _nextEntry._previousEntry = _previousEntry;
|
| - _nextEntry = _previousEntry = this;
|
| - return super.remove();
|
| - }
|
| -}
|
| -
|
| -class _LinkedHashSet<E> extends _HashSet<E>
|
| - implements LinkedHashSet<E> {
|
| - /// Holds a double linked list of the element entries of the set in
|
| - /// insertion order.
|
| - /// The fields have the same names as the ones in [_LinkedHashSetEntry],
|
| - /// allowing this object to be used as the head entry of the list.
|
| - /// The fields are initialized to `this` when created, representing the
|
| - /// empty list that only contains the head entry.
|
| - var _nextEntry;
|
| - var _previousEntry;
|
| -
|
| - _LinkedHashSet() {
|
| - _nextEntry = _previousEntry = this;
|
| - }
|
| -
|
| - // Iterable.
|
| -
|
| - Iterator<E> get iterator => new _LinkedHashSetIterator<E>(this);
|
| -
|
| - void forEach(void action(E element)) {
|
| - var cursor = _nextEntry;
|
| - int modificationCount = _modificationCount;
|
| - while (!identical(cursor, this)) {
|
| - _LinkedHashSetEntry entry = cursor;
|
| - action(entry.key);
|
| - if (_modificationCount != modificationCount) {
|
| - throw new ConcurrentModificationError(this);
|
| - }
|
| - cursor = entry._nextEntry;
|
| - }
|
| - }
|
| -
|
| - E get first {
|
| - if (identical(_nextEntry, this)) {
|
| - throw new StateError("No elements");
|
| - }
|
| - _LinkedHashSetEntry entry = _nextEntry;
|
| - return entry.key;
|
| - }
|
| -
|
| - E get last {
|
| - if (identical(_previousEntry, this)) {
|
| - throw new StateError("No elements");
|
| - }
|
| - _LinkedHashSetEntry entry = _previousEntry;
|
| - return entry.key;
|
| - }
|
| -
|
| - // Set.
|
| -
|
| - void _filterWhere(bool test(E element), bool removeMatching) {
|
| - var cursor = _nextEntry;
|
| - while (!identical(cursor, this)) {
|
| - _LinkedHashSetEntry entry = cursor;
|
| - int modificationCount = _modificationCount;
|
| - bool testResult = test(entry.key);
|
| - if (modificationCount != _modificationCount) {
|
| - throw new ConcurrentModificationError(this);
|
| - }
|
| - cursor = entry._nextEntry;
|
| - if (testResult == removeMatching) {
|
| - _remove(entry.key, entry.hashCode);
|
| - }
|
| - }
|
| - }
|
| -
|
| - void _addEntry(E key, int hashCode, int index) {
|
| - _buckets[index] =
|
| - new _LinkedHashSetEntry(key, hashCode, _buckets[index],
|
| - _previousEntry, this);
|
| - int newElements = _elementCount + 1;
|
| - _elementCount = newElements;
|
| - int length = _buckets.length;
|
| - // If we end up with more than 75% non-empty entries, we
|
| - // resize the backing store.
|
| - if ((newElements << 2) > ((length << 1) + length)) _resize();
|
| - _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
|
| - }
|
| -
|
| - void clear() {
|
| - _nextEntry = _previousEntry = this;
|
| - super.clear();
|
| - }
|
| -
|
| - HashSet<E> _newSet() => new _LinkedHashSet<E>();
|
| -}
|
| -
|
| -class _LinkedIdentityHashSet<E> extends _LinkedHashSet<E> {
|
| - int _hashCode(e) => identityHashCode(e);
|
| - bool _equals(e1, e2) => identical(e1, e2);
|
| - HashSet<E> _newSet() => new _LinkedIdentityHashSet<E>();
|
| -}
|
| -
|
| -class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> {
|
| - final _Equality<E> _equality;
|
| - final _Hasher<E> _hasher;
|
| - final _Predicate _validKey;
|
| -
|
| - _LinkedCustomHashSet(this._equality, this._hasher, bool validKey(Object o))
|
| - : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
|
| -
|
| - bool _equals(e1, e2) => _equality(e1, e2);
|
| -
|
| - int _hashCode(e) => _hasher(e);
|
| -
|
| - bool contains(Object o) {
|
| - if (!_validKey(o)) return false;
|
| - return super.contains(o);
|
| - }
|
| -
|
| - E lookup(Object o) {
|
| - if (!_validKey(o)) return null;
|
| - return super.lookup(o);
|
| - }
|
| -
|
| - bool remove(Object o) {
|
| - if (!_validKey(o)) return false;
|
| - return super.remove(o);
|
| - }
|
| -
|
| - bool containsAll(Iterable<Object> elements) {
|
| - for (Object element in elements) {
|
| - if (!_validKey(element) || !this.contains(element)) return false;
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - void removeAll(Iterable<Object> elements) {
|
| - for (Object element in elements) {
|
| - if (_validKey(element)) {
|
| - super._remove(element, _hasher(element));
|
| - }
|
| - }
|
| - }
|
| -
|
| - HashSet<E> _newSet() =>
|
| - new _LinkedCustomHashSet<E>(_equality, _hasher, _validKey);
|
| -}
|
| -
|
| -class _LinkedHashSetIterator<E> implements Iterator<E> {
|
| - final _LinkedHashSet _set;
|
| - final int _modificationCount;
|
| - var _next;
|
| - E _current;
|
| -
|
| - _LinkedHashSetIterator(_LinkedHashSet hashSet)
|
| - : _set = hashSet,
|
| - _modificationCount = hashSet._modificationCount,
|
| - _next = hashSet._nextEntry;
|
| -
|
| - bool moveNext() {
|
| - if (_modificationCount != _set._modificationCount) {
|
| - throw new ConcurrentModificationError(_set);
|
| - }
|
| - if (identical(_set, _next)) {
|
| - _current = null;
|
| - return false;
|
| - }
|
| - _LinkedHashSetEntry entry = _next;
|
| - _current = entry.key;
|
| - _next = entry._nextEntry;
|
| - return true;
|
| - }
|
| -
|
| - E get current => _current;
|
| -}
|
|
|