Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 part of dart.collection; | |
| 2 | |
| 3 /** Unique marker object for the head of a linked list of entries. */ | |
| 4 class _LinkedHashTableHeadMarker { | |
| 5 const _LinkedHashTableHeadMarker(); | |
| 6 } | |
| 7 | |
| 8 const _LinkedHashTableHeadMarker _HEAD_MARKER = | |
| 9 const _LinkedHashTableHeadMarker(); | |
| 10 | |
| 11 class _LinkedHashTable<K> extends _HashTable<K> { | |
| 12 static const _NEXT_INDEX = 1; | |
| 13 static const _PREV_INDEX = 2; | |
| 14 static const _HEAD_OFFSET = 0; | |
| 15 | |
| 16 _LinkedHashTable(int initialCapacity) : super(initialCapacity); | |
| 17 | |
| 18 int get _entrySize => 3; | |
| 19 | |
| 20 List _createTable(int capacity) { | |
| 21 List result = new List.fixedLength(capacity * _entrySize); | |
| 22 result[_HEAD_OFFSET] = _HEAD_MARKER; | |
| 23 result[_HEAD_OFFSET + _NEXT_INDEX] = _HEAD_OFFSET; | |
| 24 result[_HEAD_OFFSET + _PREV_INDEX] = _HEAD_OFFSET; | |
| 25 return result; | |
| 26 } | |
| 27 | |
| 28 int _next(int offset) => _table[offset + _NEXT_INDEX]; | |
| 29 void _setNext(int offset, int to) { _table[offset + _NEXT_INDEX] = to; } | |
| 30 | |
| 31 int _prev(int offset) => _table[offset + _PREV_INDEX]; | |
| 32 void _setPrev(int offset, int to) { _table[offset + _PREV_INDEX] = to; } | |
| 33 | |
| 34 void _linkLast(int offset) { | |
| 35 // Add entry at offset at end of double-linked list. | |
| 36 int last = _prev(_HEAD_OFFSET); | |
| 37 _setNext(offset, _HEAD_OFFSET); | |
| 38 _setPrev(offset, last); | |
| 39 _setNext(last, offset); | |
| 40 _setPrev(_HEAD_OFFSET, offset); | |
| 41 } | |
| 42 | |
| 43 void _unlink(int offset) { | |
| 44 assert(offset != _HEAD_OFFSET); | |
| 45 int next = _next(offset); | |
| 46 int prev = _prev(offset); | |
| 47 _setNext(offset, null); | |
| 48 _setPrev(offset, null); | |
| 49 _setNext(prev, next); | |
| 50 _setPrev(next, prev); | |
| 51 } | |
| 52 | |
| 53 /** | |
| 54 * Copies all non-free entries from the old table to the new empty table. | |
| 55 */ | |
| 56 void _addAllEntries(List oldTable) { | |
| 57 int offset = oldTable[_HEAD_OFFSET + _NEXT_INDEX]; | |
| 58 while (offset != _HEAD_OFFSET) { | |
| 59 Object object = oldTable[offset]; | |
| 60 int nextOffset = oldTable[offset + _NEXT_INDEX]; | |
| 61 int toOffset = _put(object); | |
| 62 _copyEntry(oldTable, offset, toOffset); | |
| 63 offset = nextOffset; | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 void _clear() { | |
| 68 _setNext(_HEAD_OFFSET, _HEAD_OFFSET); | |
| 69 _setPrev(_HEAD_OFFSET, _HEAD_OFFSET); | |
| 70 for (int i = _entrySize; i < _table.length; i++) { | |
| 71 _table[i] = null; | |
| 72 } | |
| 73 _entryCount = _deletedCount = 0; | |
| 74 _modificationCount++; | |
|
floitsch
2013/02/06 10:43:58
This is the only place in the linked_hash_table wh
Lasse Reichstein Nielsen
2013/02/08 13:53:01
I have moved modification-count into the _put, _re
| |
| 75 } | |
| 76 | |
| 77 int _put(K key) { | |
| 78 Object keyOrNull = (key == null) ? _NULL : key; | |
| 79 int offset = _probeForAdd(_hashCodeOf(key), keyOrNull); | |
| 80 Object entry = _key(offset); | |
| 81 if (!_isFree(entry)) return offset; | |
| 82 if (identical(entry, _TOMBSTONE)) { | |
| 83 _deletedCount--; | |
| 84 } else { | |
| 85 _entryCount++; | |
| 86 } | |
| 87 _setKey(offset, keyOrNull); | |
| 88 _linkLast(offset); | |
| 89 return offset; | |
| 90 } | |
| 91 | |
| 92 void _deleteEntry(int offset) { | |
| 93 _unlink(offset); | |
| 94 _setKey(offset, _TOMBSTONE); | |
| 95 _deletedCount++; | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 class _LinkedHashTableKeyIterable<K> extends Iterable<K> { | |
| 100 final _LinkedHashTable<K> _table; | |
| 101 _LinkedHashTableKeyIterable(this._table); | |
| 102 Iterator<K> get iterator => new _LinkedHashTableKeyIterator<K>(_table); | |
| 103 | |
| 104 bool contains(Object value) => _table._get(value) >= 0; | |
| 105 | |
| 106 int get length => _table._elementCount; | |
| 107 } | |
| 108 | |
| 109 class _LinkedHashTableKeyIterator<K> implements Iterator<K> { | |
| 110 final _LinkedHashTable<K> _table; | |
| 111 final int _modificationCount; | |
| 112 int _offset; | |
| 113 K _current; | |
| 114 | |
| 115 _LinkedHashTableKeyIterator(_LinkedHashTable<K> table) | |
| 116 : _table = table, | |
| 117 _modificationCount = table._modificationCount, | |
| 118 _offset = _LinkedHashTable._HEAD_OFFSET; | |
| 119 | |
| 120 bool moveNext() { | |
| 121 if (_offset == null) return false; | |
| 122 _table._checkModification(_modificationCount); | |
| 123 _offset = _table._next(_offset); | |
| 124 if (_offset == _LinkedHashTable._HEAD_OFFSET) { | |
| 125 _current = null; | |
| 126 _offset = null; | |
| 127 return false; | |
| 128 } | |
| 129 _current = _table._key(_offset); | |
| 130 return true; | |
| 131 } | |
| 132 | |
| 133 K get current => _current; | |
| 134 } | |
| 135 | |
| 136 class _LinkedHashTableValueIterable<V> extends Iterable<V> { | |
| 137 final _LinkedHashTable _table; | |
| 138 final int _valueIndex; | |
| 139 _LinkedHashTableValueIterable(this._table, this._valueIndex); | |
| 140 Iterator<V> get iterator => | |
| 141 new _LinkedHashTableValueIterator<V>(_table, _valueIndex); | |
| 142 int get length => _table._elementCount; | |
| 143 } | |
| 144 | |
| 145 class _LinkedHashTableValueIterator<V> implements Iterator<V> { | |
|
floitsch
2013/02/06 10:43:58
The Key and Value iterator could share a common su
Lasse Reichstein Nielsen
2013/02/08 13:53:01
Done.
| |
| 146 final _LinkedHashTable _table; | |
| 147 final int _valueIndex; | |
| 148 final int _modificationCount; | |
| 149 int _offset; | |
| 150 V _current; | |
| 151 | |
| 152 _LinkedHashTableValueIterator(_LinkedHashTable table, this._valueIndex) | |
| 153 : _table = table, | |
| 154 _modificationCount = table._modificationCount, | |
| 155 _offset = _LinkedHashTable._HEAD_OFFSET; | |
| 156 | |
| 157 bool moveNext() { | |
| 158 if (_offset == null) return false; | |
| 159 _table._checkModification(_modificationCount); | |
| 160 _offset = _table._next(_offset); | |
| 161 if (_offset == _LinkedHashTable._HEAD_OFFSET) { | |
| 162 _current = null; | |
| 163 _offset = null; | |
| 164 return false; | |
| 165 } | |
| 166 _current = _table._table[_offset + _valueIndex]; | |
| 167 return true; | |
| 168 } | |
| 169 | |
| 170 V get current => _current; | |
| 171 } | |
| OLD | NEW |