Index: pkg/compiler/lib/src/util/maplet.dart |
diff --git a/pkg/compiler/lib/src/util/maplet.dart b/pkg/compiler/lib/src/util/maplet.dart |
deleted file mode 100644 |
index 455435bd91000def9828eccfc3c7a51591b3fd60..0000000000000000000000000000000000000000 |
--- a/pkg/compiler/lib/src/util/maplet.dart |
+++ /dev/null |
@@ -1,280 +0,0 @@ |
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-library dart2js.util.maplet; |
- |
-import 'dart:collection' show MapBase, IterableBase; |
- |
-class Maplet<K, V> extends MapBase<K, V> { |
- static const _MARKER = const _MapletMarker(); |
- static const CAPACITY = 8; |
- |
-// The maplet can be in one of four states: |
- // |
- // * Empty (extra: null, key: marker, value: null) |
- // * Single element (extra: null, key: key, value: value) |
- // * List-backed (extra: length, key: list, value: null) |
- // * Map-backed (extra: marker, key: map, value: null) |
- // |
- // When the maplet is list-backed, the list has two sections: One |
- // for keys and one for values. The first [CAPACITY] entries are |
- // the keys and they may contain markers for deleted elements. After |
- // the keys there are [CAPACITY] entries for the values. |
- |
- var _key = _MARKER; |
- var _value; |
- var _extra; |
- |
- Maplet(); |
- |
- Maplet.from(Maplet<K, V> other) { |
- other.forEach((K key, V value) { |
- this[key] = value; |
- }); |
- } |
- |
- bool get isEmpty { |
- if (_extra == null) { |
- return _MARKER == _key; |
- } else if (_MARKER == _extra) { |
- return _key.isEmpty; |
- } else { |
- return _extra == 0; |
- } |
- } |
- |
- int get length { |
- if (_extra == null) { |
- return (_MARKER == _key) ? 0 : 1; |
- } else if (_MARKER == _extra) { |
- return _key.length; |
- } else { |
- return _extra; |
- } |
- } |
- |
- bool containsKey(K key) { |
- if (_extra == null) { |
- return _key == key; |
- } else if (_MARKER == _extra) { |
- return _key.containsKey(key); |
- } else { |
- for (int remaining = _extra, i = 0; remaining > 0 && i < CAPACITY; i++) { |
- var candidate = _key[i]; |
- if (_MARKER == candidate) continue; |
- if (candidate == key) return true; |
- remaining--; |
- } |
- return false; |
- } |
- } |
- |
- V operator [](K key) { |
- if (_extra == null) { |
- return (_key == key) ? _value : null; |
- } else if (_MARKER == _extra) { |
- return _key[key]; |
- } else { |
- for (int remaining = _extra, i = 0; remaining > 0 && i < CAPACITY; i++) { |
- var candidate = _key[i]; |
- if (_MARKER == candidate) continue; |
- if (candidate == key) return _key[i + CAPACITY]; |
- remaining--; |
- } |
- return null; |
- } |
- } |
- |
- void operator []=(K key, V value) { |
- if (_extra == null) { |
- if (_MARKER == _key) { |
- _key = key; |
- _value = value; |
- } else if (_key == key) { |
- _value = value; |
- } else { |
- List list = new List(CAPACITY * 2); |
- list[0] = _key; |
- list[1] = key; |
- list[CAPACITY] = _value; |
- list[CAPACITY + 1] = value; |
- _key = list; |
- _value = null; |
- _extra = 2; // Two elements. |
- } |
- } else if (_MARKER == _extra) { |
- _key[key] = value; |
- } else { |
- int remaining = _extra; |
- int index = 0; |
- int copyTo, copyFrom; |
- while (remaining > 0 && index < CAPACITY) { |
- var candidate = _key[index]; |
- if (_MARKER == candidate) { |
- // Keep track of the last range of empty slots in the |
- // list. When we're done we'll move all the elements |
- // after those empty slots down, so that adding an element |
- // after that will preserve the insertion order. |
- if (copyFrom == index) { |
- copyFrom++; |
- } else { |
- copyTo = index; |
- copyFrom = index + 1; |
- } |
- } else if (candidate == key) { |
- _key[CAPACITY + index] = value; |
- return; |
- } else { |
- // Skipped an element that didn't match. |
- remaining--; |
- } |
- index++; |
- } |
- if (index < CAPACITY) { |
- _key[index] = key; |
- _key[CAPACITY + index] = value; |
- _extra++; |
- } else if (_extra < CAPACITY) { |
- // Move the last elements down into the last empty slots |
- // so that we have empty slots after the last element. |
- while (copyFrom < CAPACITY) { |
- _key[copyTo] = _key[copyFrom]; |
- _key[CAPACITY + copyTo] = _key[CAPACITY + copyFrom]; |
- copyTo++; |
- copyFrom++; |
- } |
- // Insert the new element as the last element. |
- _key[copyTo] = key; |
- _key[CAPACITY + copyTo] = value; |
- copyTo++; |
- // Add one to the length encoded in the extra field. |
- _extra++; |
- // Clear all elements after the new last elements to |
- // make sure we don't keep extra stuff alive. |
- while (copyTo < CAPACITY) { |
- _key[copyTo] = _key[CAPACITY + copyTo] = null; |
- copyTo++; |
- } |
- } else { |
- Map map = new Map(); |
- forEach((eachKey, eachValue) => map[eachKey] = eachValue); |
- map[key] = value; |
- _key = map; |
- _extra = _MARKER; |
- } |
- } |
- } |
- |
- V remove(K key) { |
- if (_extra == null) { |
- if (_key != key) return null; |
- _key = _MARKER; |
- V result = _value; |
- _value = null; |
- return result; |
- } else if (_MARKER == _extra) { |
- return _key.remove(key); |
- } else { |
- for (int remaining = _extra, i = 0; remaining > 0 && i < CAPACITY; i++) { |
- var candidate = _key[i]; |
- if (_MARKER == candidate) continue; |
- if (candidate == key) { |
- int valueIndex = CAPACITY + i; |
- var result = _key[valueIndex]; |
- _key[i] = _MARKER; |
- _key[valueIndex] = null; |
- _extra--; |
- return result; |
- } |
- remaining--; |
- } |
- return null; |
- } |
- } |
- |
- void forEach(void action(K key, V value)) { |
- if (_extra == null) { |
- if (_MARKER != _key) action(_key, _value); |
- } else if (_MARKER == _extra) { |
- _key.forEach(action); |
- } else { |
- for (int remaining = _extra, i = 0; remaining > 0 && i < CAPACITY; i++) { |
- var candidate = _key[i]; |
- if (_MARKER == candidate) continue; |
- action(candidate, _key[CAPACITY + i]); |
- remaining--; |
- } |
- } |
- } |
- |
- void clear() { |
- _key = _MARKER; |
- _value = _extra = null; |
- } |
- |
- Iterable<K> get keys => new _MapletKeyIterable<K>(this); |
-} |
- |
-class _MapletMarker { |
- const _MapletMarker(); |
-} |
- |
-class _MapletKeyIterable<K> extends IterableBase<K> { |
- final Maplet<K, dynamic> maplet; |
- |
- _MapletKeyIterable(this.maplet); |
- |
- Iterator<K> get iterator { |
- if (maplet._extra == null) { |
- return new _MapletSingleIterator<K>(maplet._key); |
- } else if (Maplet._MARKER == maplet._extra) { |
- return maplet._key.keys.iterator; |
- } else { |
- return new _MapletListIterator<K>(maplet._key, maplet._extra); |
- } |
- } |
-} |
- |
-class _MapletSingleIterator<K> implements Iterator<K> { |
- var _element; |
- K _current; |
- |
- _MapletSingleIterator(this._element); |
- |
- K get current => _current; |
- |
- bool moveNext() { |
- if (Maplet._MARKER == _element) { |
- _current = null; |
- return false; |
- } |
- _current = _element; |
- _element = Maplet._MARKER; |
- return true; |
- } |
-} |
- |
-class _MapletListIterator<K> implements Iterator<K> { |
- final List _list; |
- int _remaining; |
- int _index = 0; |
- K _current; |
- |
- _MapletListIterator(this._list, this._remaining); |
- |
- K get current => _current; |
- |
- bool moveNext() { |
- while (_remaining > 0) { |
- var candidate = _list[_index++]; |
- if (Maplet._MARKER != candidate) { |
- _current = candidate; |
- _remaining--; |
- return true; |
- } |
- } |
- _current = null; |
- return false; |
- } |
-} |