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

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

Issue 12213010: New implementation of {,Linked}Hash{Set,Map}. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments, fix bugs. Created 7 years, 10 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
OLDNEW
(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 if (_elementCount == 0) return;
69 _setNext(_HEAD_OFFSET, _HEAD_OFFSET);
70 _setPrev(_HEAD_OFFSET, _HEAD_OFFSET);
71 for (int i = _entrySize; i < _table.length; i++) {
72 _table[i] = null;
73 }
74 _entryCount = _deletedCount = 0;
75 _recordModification();
76 }
77
78 int _put(K key) {
79 int offset = _probeForAdd(_hashCodeOf(key), key);
80 Object oldEntry = _table[offset];
81 if (identical(oldEntry, _TOMBSTONE)) {
82 _deletedCount--;
83 } else if (oldEntry == null) {
84 _entryCount++;
85 } else {
86 return offset;
87 }
88 _recordModification();
89 _setKey(offset, key);
90 _linkLast(offset);
91 return offset;
92 }
93
94 void _deleteEntry(int offset) {
95 _unlink(offset);
96 _setKey(offset, _TOMBSTONE);
97 _deletedCount++;
98 _recordModification();
99 }
100 }
101
102 class _LinkedHashTableKeyIterable<K> extends Iterable<K> {
103 final _LinkedHashTable<K> _table;
104 _LinkedHashTableKeyIterable(this._table);
105 Iterator<K> get iterator => new _LinkedHashTableKeyIterator<K>(_table);
106
107 bool contains(Object value) => _table._get(value) >= 0;
108
109 int get length => _table._elementCount;
110 }
111
112 class _LinkedHashTableKeyIterator<K> extends _LinkedHashTableIterator<K> {
113 _LinkedHashTableKeyIterator(_LinkedHashTable<K> hashTable): super(hashTable);
114
115 K _getCurrent(int offset) => _hashTable._key(offset);
116 }
117
118 class _LinkedHashTableValueIterable<V> extends Iterable<V> {
119 final _LinkedHashTable _hashTable;
120 final int _valueIndex;
121 _LinkedHashTableValueIterable(this._hashTable, this._valueIndex);
122 Iterator<V> get iterator =>
123 new _LinkedHashTableValueIterator<V>(_hashTable, _valueIndex);
124 int get length => _hashTable._elementCount;
125 }
126
127 class _LinkedHashTableValueIterator<V> extends _LinkedHashTableIterator<V> {
128 final int _valueIndex;
129
130 _LinkedHashTableValueIterator(_LinkedHashTable hashTable, this._valueIndex)
131 : super(hashTable);
132
133 V _getCurrent(int offset) => _hashTable._table[offset + _valueIndex];
134 }
135
136 abstract class _LinkedHashTableIterator<T> implements Iterator<T> {
137 final _LinkedHashTable _hashTable;
138 final int _modificationCount;
139 int _offset;
140 T _current;
141
142 _LinkedHashTableIterator(_LinkedHashTable table)
143 : _hashTable = table,
144 _modificationCount = table._modificationCount,
145 _offset = table._next(_LinkedHashTable._HEAD_OFFSET);
146
147 bool moveNext() {
148 _hashTable._checkModification(_modificationCount);
149 if (_offset == _LinkedHashTable._HEAD_OFFSET) {
150 _current = null;
151 return false;
152 }
153 _current = _getCurrent(_offset);
154 _offset = _hashTable._next(_offset);
155 return true;
156 }
157
158 T _getCurrent(int offset);
159
160 T get current => _current;
161 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698