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

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: Now with new files too 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 _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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698