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

Side by Side Diff: tool/input_sdk/lib/collection/queue.dart

Issue 1966473002: Update linked_list, queue, splay_tree (Closed) Base URL: https://github.com/dart-lang/dev_compiler@master
Patch Set: Created 4 years, 7 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
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart.collection; 5 part of dart.collection;
6 6
7 /** 7 /**
8 * A [Queue] is a collection that can be manipulated at both ends. One 8 * A [Queue] is a collection that can be manipulated at both ends. One
9 * can iterate over the elements of a queue through [forEach] or with 9 * can iterate over the elements of a queue through [forEach] or with
10 * an [Iterator]. 10 * an [Iterator].
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 * Adds [value] at the end of the queue. 60 * Adds [value] at the end of the queue.
61 */ 61 */
62 void add(E value); 62 void add(E value);
63 63
64 /** 64 /**
65 * Remove a single instance of [value] from the queue. 65 * Remove a single instance of [value] from the queue.
66 * 66 *
67 * Returns `true` if a value was removed, or `false` if the queue 67 * Returns `true` if a value was removed, or `false` if the queue
68 * contained no element equal to [value]. 68 * contained no element equal to [value].
69 */ 69 */
70 bool remove(Object object); 70 bool remove(Object value);
71 71
72 /** 72 /**
73 * Adds all elements of [iterable] at the end of the queue. The 73 * Adds all elements of [iterable] at the end of the queue. The
74 * length of the queue is extended by the length of [iterable]. 74 * length of the queue is extended by the length of [iterable].
75 */ 75 */
76 void addAll(Iterable<E> iterable); 76 void addAll(Iterable<E> iterable);
77 77
78 /** 78 /**
79 * Removes all elements matched by [test] from the queue. 79 * Removes all elements matched by [test] from the queue.
80 * 80 *
81 * The `test` function must not throw or modify the queue. 81 * The `test` function must not throw or modify the queue.
82 */ 82 */
83 void removeWhere(bool test(E element)); 83 void removeWhere(bool test(E element));
84 84
85 /** 85 /**
86 * Removes all elements not matched by [test] from the queue. 86 * Removes all elements not matched by [test] from the queue.
87 * 87 *
88 * The `test` function must not throw or modify the queue. 88 * The `test` function must not throw or modify the queue.
89 */ 89 */
90 void retainWhere(bool test(E element)); 90 void retainWhere(bool test(E element));
91 91
92 /** 92 /**
93 * Removes all elements in the queue. The size of the queue becomes zero. 93 * Removes all elements in the queue. The size of the queue becomes zero.
94 */ 94 */
95 void clear(); 95 void clear();
96 } 96 }
97 97
98 98
99 class _DoubleLink<E extends _DoubleLink> {
100 E _previousLink;
101 E _nextLink;
102
103 void _link(E previous, E next) {
104 _nextLink = next;
105 _previousLink = previous;
106 if (previous != null) previous._nextLink = this;
107 if (next != null) next._previousLink = this;
108 }
109
110 void _unlink() {
111 if (_previousLink != null) _previousLink._nextLink = _nextLink;
112 if (_nextLink != null) _nextLink._previousLink = _previousLink;
113 _nextLink = null;
114 _previousLink = null;
115 }
116 }
117
99 /** 118 /**
100 * An entry in a doubly linked list. It contains a pointer to the next 119 * An entry in a doubly linked list. It contains a pointer to the next
101 * entry, the previous entry, and the boxed element. 120 * entry, the previous entry, and the boxed element.
102 */ 121 */
103 class DoubleLinkedQueueEntry<E> { 122 abstract class DoubleLinkedQueueEntry<E> {
104 DoubleLinkedQueueEntry<E> _previous; 123 factory DoubleLinkedQueueEntry(E element) = _UserDoubleLinkedQueueEntry<E>;
105 DoubleLinkedQueueEntry<E> _next;
106 E _element;
107 124
108 DoubleLinkedQueueEntry(E e) : _element = e; 125 /// The element in the queue.
126 E get element;
109 127
110 void _link(DoubleLinkedQueueEntry<E> previous, 128 /// Appends the given [e] as entry just after this entry.
111 DoubleLinkedQueueEntry<E> next) { 129 void append(E e);
112 _next = next; 130
113 _previous = previous; 131 /// Prepends the given [e] as entry just before this entry.
114 previous._next = this; 132 void prepend(E e);
115 next._previous = this; 133
116 } 134 /// Returns the previous entry or `null` if there is none.
135 DoubleLinkedQueueEntry<E> previousEntry();
136
137 /// Returns the next entry or `null` if there is none.
138 DoubleLinkedQueueEntry<E> nextEntry();
139 }
140
141 /// Default implementation of a doubly linked queue entry.
142 ///
143 /// This implementation is only used if a user instantiates a
144 /// [DoubleLinkedQueueEntry] directly. The internal implementations don't use
145 /// this class.
146 class _UserDoubleLinkedQueueEntry<E>
147 extends _DoubleLink<_UserDoubleLinkedQueueEntry<E>>
148 implements DoubleLinkedQueueEntry<E> {
149 E element;
150
151 _UserDoubleLinkedQueueEntry(this.element);
117 152
118 void append(E e) { 153 void append(E e) {
119 new DoubleLinkedQueueEntry<E>(e)._link(this, _next); 154 new _UserDoubleLinkedQueueEntry<E>(e)._link(this, _nextLink);
120 } 155 }
121 156
122 void prepend(E e) { 157 void prepend(E e) {
123 new DoubleLinkedQueueEntry<E>(e)._link(_previous, this); 158 new _UserDoubleLinkedQueueEntry<E>(e)._link(_previousLink, this);
124 } 159 }
125 160
126 E remove() { 161 E remove() {
127 _previous._next = _next; 162 _unlink();
128 _next._previous = _previous; 163 return element;
129 _next = null;
130 _previous = null;
131 return _element;
132 } 164 }
133 165
134 DoubleLinkedQueueEntry<E> _asNonSentinelEntry() { 166 DoubleLinkedQueueEntry<E> previousEntry() => _previousLink;
135 return this; 167
168 DoubleLinkedQueueEntry<E> nextEntry() => _nextLink;
169 }
170
171 /**
172 * Interface for the link classes used by [DoubleLinkedQueue].
173 *
174 * Both the [_DoubleLinkedQueueElement] and [_DoubleLinkedQueueSentinel]
175 * implement this interface.
176 * The entry contains a link back to the queue, so calling `append`
177 * or `prepend` can correctly update the element count.
178 */
179 abstract class _DoubleLinkedQueueEntry<E>
180 extends _DoubleLink<_DoubleLinkedQueueEntry<E>> {
181 DoubleLinkedQueue<E> _queue;
182 _DoubleLinkedQueueEntry(this._queue);
183
184 DoubleLinkedQueueEntry<E> _asNonSentinelEntry();
185
186 void _append(E e) {
187 new _DoubleLinkedQueueElement<E>(e, _queue)._link(this, _nextLink);
188 }
189
190 void _prepend(E e) {
191 new _DoubleLinkedQueueElement<E>(e, _queue)._link(_previousLink, this);
192 }
193
194 E _remove();
195
196 E get element;
197
198 DoubleLinkedQueueEntry<E> nextEntry() {
199 return _nextLink._asNonSentinelEntry();
136 } 200 }
137 201
138 DoubleLinkedQueueEntry<E> previousEntry() { 202 DoubleLinkedQueueEntry<E> previousEntry() {
139 return _previous._asNonSentinelEntry(); 203 return _previousLink._asNonSentinelEntry();
140 }
141
142 DoubleLinkedQueueEntry<E> nextEntry() {
143 return _next._asNonSentinelEntry();
144 }
145
146 E get element {
147 return _element;
148 }
149
150 void set element(E e) {
151 _element = e;
152 } 204 }
153 } 205 }
154 206
207 /**
208 * The actual entry type used by the [DoubleLinkedQueue].
209 *
210 * The entry contains a reference to the queue, allowing
211 * [append]/[prepend] to update the list length.
212 */
213 class _DoubleLinkedQueueElement<E> extends _DoubleLinkedQueueEntry<E>
214 implements DoubleLinkedQueueEntry<E> {
215 E element;
216 _DoubleLinkedQueueElement(this.element, DoubleLinkedQueue<E> queue)
217 : super(queue);
218
219 void append(E e) {
220 _append(e);
221 if (_queue != null) _queue._elementCount++;
222 }
223
224 void prepend(E e) {
225 _prepend(e);
226 if (_queue != null) _queue._elementCount++;
227 }
228
229 E _remove() {
230 _queue = null;
231 _unlink();
232 return element;
233 }
234
235 E remove() {
236 if (_queue != null) _queue._elementCount--;
237 return _remove();
238 }
239
240 _DoubleLinkedQueueElement<E> _asNonSentinelEntry() {
241 return this;
242 }
243 }
244
155 /** 245 /**
156 * A sentinel in a double linked list is used to manipulate the list 246 * A sentinel in a double linked list is used to manipulate the list
157 * at both ends. 247 * at both ends.
158 * A double linked list has exactly one sentinel, 248 * A double linked list has exactly one sentinel,
159 * which is the only entry when the list is constructed. 249 * which is the only entry when the list is constructed.
160 * Initially, a sentinel has its next and previous entry point to itself. 250 * Initially, a sentinel has its next and previous entry point to itself.
161 * A sentinel does not box any user element. 251 * A sentinel does not box any user element.
162 */ 252 */
163 class _DoubleLinkedQueueEntrySentinel<E> extends DoubleLinkedQueueEntry<E> { 253 class _DoubleLinkedQueueSentinel<E> extends _DoubleLinkedQueueEntry<E> {
164 _DoubleLinkedQueueEntrySentinel() : super(null) { 254 _DoubleLinkedQueueSentinel(DoubleLinkedQueue<E> queue) : super(queue) {
165 _link(this, this); 255 _previousLink = this;
166 } 256 _nextLink = this;
167
168 E remove() {
169 throw IterableElementError.noElement();
170 } 257 }
171 258
172 DoubleLinkedQueueEntry<E> _asNonSentinelEntry() { 259 DoubleLinkedQueueEntry<E> _asNonSentinelEntry() {
173 return null; 260 return null;
174 } 261 }
175 262
176 void set element(E e) { 263 /** Hit by, e.g., [DoubleLinkedQueue.removeFirst] if the queue is empty. */
177 // This setter is unreachable. 264 E _remove() {
178 // TODO(lrn): Don't inherit the field if we don't use it. 265 throw IterableElementError.noElement();
179 assert(false);
180 } 266 }
181 267
268 /** Hit by, e.g., [DoubleLinkedQueue.first] if the queue is empty. */
182 E get element { 269 E get element {
183 throw IterableElementError.noElement(); 270 throw IterableElementError.noElement();
184 } 271 }
185 } 272 }
186 273
187 /** 274 /**
188 * A [Queue] implementation based on a double-linked list. 275 * A [Queue] implementation based on a double-linked list.
189 * 276 *
190 * Allows constant time add, remove-at-ends and peek operations. 277 * Allows constant time add, remove-at-ends and peek operations.
191 */ 278 */
192 class DoubleLinkedQueue<E> extends IterableBase<E> implements Queue<E> { 279 class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> {
193 _DoubleLinkedQueueEntrySentinel<E> _sentinel; 280 _DoubleLinkedQueueSentinel<E> _sentinel;
194 int _elementCount = 0; 281 int _elementCount = 0;
195 282
196 DoubleLinkedQueue() { 283 DoubleLinkedQueue() {
197 _sentinel = new _DoubleLinkedQueueEntrySentinel<E>(); 284 _sentinel = new _DoubleLinkedQueueSentinel<E>(this);
198 } 285 }
199 286
200 /** 287 /**
201 * Creates a double-linked queue containing all [elements]. 288 * Creates a double-linked queue containing all [elements].
202 * 289 *
203 * The element order in the queue is as if the elements were added using 290 * The element order in the queue is as if the elements were added using
204 * [addLast] in the order provided by [elements.iterator]. 291 * [addLast] in the order provided by [elements.iterator].
205 */ 292 */
206 factory DoubleLinkedQueue.from(Iterable elements) { 293 factory DoubleLinkedQueue.from(Iterable elements) {
207 Queue<E> list = new DoubleLinkedQueue(); 294 Queue<E> list = new DoubleLinkedQueue<E>();
208 for (final E e in elements) { 295 for (final e in elements) {
209 list.addLast(e); 296 list.addLast(e as E);
210 } 297 }
211 return list; 298 return list;
212 } 299 }
213 300
214 int get length => _elementCount; 301 int get length => _elementCount;
215 302
216 void addLast(E value) { 303 void addLast(E value) {
217 _sentinel.prepend(value); 304 _sentinel._prepend(value);
218 _elementCount++; 305 _elementCount++;
219 } 306 }
220 307
221 void addFirst(E value) { 308 void addFirst(E value) {
222 _sentinel.append(value); 309 _sentinel._append(value);
223 _elementCount++; 310 _elementCount++;
224 } 311 }
225 312
226 void add(E value) { 313 void add(E value) {
227 _sentinel.prepend(value); 314 _sentinel._prepend(value);
228 _elementCount++; 315 _elementCount++;
229 } 316 }
230 317
231 void addAll(Iterable<E> iterable) { 318 void addAll(Iterable<E> iterable) {
232 for (final E value in iterable) { 319 for (final E value in iterable) {
233 _sentinel.prepend(value); 320 _sentinel._prepend(value);
234 _elementCount++; 321 _elementCount++;
235 } 322 }
236 } 323 }
237 324
238 E removeLast() { 325 E removeLast() {
239 E result = _sentinel._previous.remove(); 326 _DoubleLinkedQueueEntry<E> lastEntry = _sentinel._previousLink;
327 E result = lastEntry._remove();
240 _elementCount--; 328 _elementCount--;
241 return result; 329 return result;
242 } 330 }
243 331
244 E removeFirst() { 332 E removeFirst() {
245 E result = _sentinel._next.remove(); 333 _DoubleLinkedQueueEntry<E> firstEntry = _sentinel._nextLink;
334 E result = firstEntry._remove();
246 _elementCount--; 335 _elementCount--;
247 return result; 336 return result;
248 } 337 }
249 338
250 bool remove(Object o) { 339 bool remove(Object o) {
251 DoubleLinkedQueueEntry<E> entry = _sentinel._next; 340 _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
252 while (!identical(entry, _sentinel)) { 341 while (!identical(entry, _sentinel)) {
253 if (entry.element == o) { 342 if (entry.element == o) {
254 entry.remove(); 343 entry._remove();
255 _elementCount--; 344 _elementCount--;
256 return true; 345 return true;
257 } 346 }
258 entry = entry._next; 347 entry = entry._nextLink;
259 } 348 }
260 return false; 349 return false;
261 } 350 }
262 351
263 void _filter(bool test(E element), bool removeMatching) { 352 void _filter(bool test(E element), bool removeMatching) {
264 DoubleLinkedQueueEntry<E> entry = _sentinel._next; 353 _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
265 while (!identical(entry, _sentinel)) { 354 while (!identical(entry, _sentinel)) {
266 DoubleLinkedQueueEntry<E> next = entry._next; 355 _DoubleLinkedQueueEntry<E> next = entry._nextLink;
267 if (identical(removeMatching, test(entry.element))) { 356 if (identical(removeMatching, test(entry.element))) {
268 entry.remove(); 357 entry._remove();
269 _elementCount--; 358 _elementCount--;
270 } 359 }
271 entry = next; 360 entry = next;
272 } 361 }
273 } 362 }
274 363
275 void removeWhere(bool test(E element)) { 364 void removeWhere(bool test(E element)) {
276 _filter(test, true); 365 _filter(test, true);
277 } 366 }
278 367
279 void retainWhere(bool test(E element)) { 368 void retainWhere(bool test(E element)) {
280 _filter(test, false); 369 _filter(test, false);
281 } 370 }
282 371
283 E get first { 372 E get first {
284 return _sentinel._next.element; 373 _DoubleLinkedQueueEntry<E> firstEntry = _sentinel._nextLink;
374 return firstEntry.element;
285 } 375 }
286 376
287 E get last { 377 E get last {
288 return _sentinel._previous.element; 378 _DoubleLinkedQueueEntry<E> lastEntry = _sentinel._previousLink;
379 return lastEntry.element;
289 } 380 }
290 381
291 E get single { 382 E get single {
292 // Note that this throws correctly if the queue is empty. 383 // Note that this throws correctly if the queue is empty
293 if (identical(_sentinel._next, _sentinel._previous)) { 384 // because reading element on the sentinel throws.
294 return _sentinel._next.element; 385 if (identical(_sentinel._nextLink, _sentinel._previousLink)) {
386 _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
387 return entry.element;
295 } 388 }
296 throw IterableElementError.tooMany(); 389 throw IterableElementError.tooMany();
297 } 390 }
298 391
299 DoubleLinkedQueueEntry<E> lastEntry() { 392 DoubleLinkedQueueEntry<E> lastEntry() {
300 return _sentinel.previousEntry(); 393 return _sentinel.previousEntry();
301 } 394 }
302 395
303 DoubleLinkedQueueEntry<E> firstEntry() { 396 DoubleLinkedQueueEntry<E> firstEntry() {
304 return _sentinel.nextEntry(); 397 return _sentinel.nextEntry();
305 } 398 }
306 399
307 bool get isEmpty { 400 bool get isEmpty {
308 return (identical(_sentinel._next, _sentinel)); 401 return (identical(_sentinel._nextLink, _sentinel));
309 } 402 }
310 403
311 void clear() { 404 void clear() {
312 _sentinel._next = _sentinel; 405 _sentinel._nextLink = _sentinel;
313 _sentinel._previous = _sentinel; 406 _sentinel._previousLink = _sentinel;
314 _elementCount = 0; 407 _elementCount = 0;
315 } 408 }
316 409
317 void forEachEntry(void f(DoubleLinkedQueueEntry<E> element)) { 410 void forEachEntry(void f(DoubleLinkedQueueEntry<E> element)) {
318 DoubleLinkedQueueEntry<E> entry = _sentinel._next; 411 _DoubleLinkedQueueEntry<E> entry = _sentinel._nextLink;
319 while (!identical(entry, _sentinel)) { 412 while (!identical(entry, _sentinel)) {
320 DoubleLinkedQueueEntry<E> nextEntry = entry._next; 413 _DoubleLinkedQueueEntry<E> nextEntry = entry._nextLink;
321 f(entry); 414 _DoubleLinkedQueueElement<E> element = entry;
415 f(element);
322 entry = nextEntry; 416 entry = nextEntry;
323 } 417 }
324 } 418 }
325 419
326 _DoubleLinkedQueueIterator<E> get iterator { 420 _DoubleLinkedQueueIterator<E> get iterator {
327 return new _DoubleLinkedQueueIterator<E>(_sentinel); 421 return new _DoubleLinkedQueueIterator<E>(_sentinel);
328 } 422 }
329 423
330 String toString() => IterableBase.iterableToFullString(this, '{', '}'); 424 String toString() => IterableBase.iterableToFullString(this, '{', '}');
331 } 425 }
332 426
333 class _DoubleLinkedQueueIterator<E> implements Iterator<E> { 427 class _DoubleLinkedQueueIterator<E> implements Iterator<E> {
334 _DoubleLinkedQueueEntrySentinel<E> _sentinel; 428 _DoubleLinkedQueueSentinel<E> _sentinel;
335 DoubleLinkedQueueEntry<E> _nextEntry = null; 429 _DoubleLinkedQueueEntry<E> _nextEntry = null;
336 E _current; 430 E _current;
337 431
338 _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel<E> sentinel) 432 _DoubleLinkedQueueIterator(_DoubleLinkedQueueSentinel<E> sentinel)
339 : _sentinel = sentinel, _nextEntry = sentinel._next; 433 : _sentinel = sentinel,
434 _nextEntry = sentinel._nextLink;
340 435
341 bool moveNext() { 436 bool moveNext() {
342 // When [_currentEntry] it is set to [:null:] then it is at the end. 437 if (identical(_nextEntry, _sentinel)) {
343 if (!identical(_nextEntry, _sentinel)) { 438 _current = null;
344 _current = _nextEntry._element; 439 _nextEntry = null;
345 _nextEntry = _nextEntry._next; 440 _sentinel = null;
346 return true; 441 return false;
347 } 442 }
348 _current = null; 443 _DoubleLinkedQueueElement<E> elementEntry = _nextEntry;
349 _nextEntry = _sentinel = null; // Still identical. 444 if (elementEntry._queue == null) {
350 return false; 445 throw new ConcurrentModificationError(_sentinel._queue);
446 }
447 _current = elementEntry.element;
448 _nextEntry = elementEntry._nextLink;
449 return true;
351 } 450 }
352 451
353 E get current => _current; 452 E get current => _current;
354 } 453 }
355 454
356 /** 455 /**
357 * List based [Queue]. 456 * List based [Queue].
358 * 457 *
359 * Keeps a cyclic buffer of elements, and grows to a larger buffer when 458 * Keeps a cyclic buffer of elements, and grows to a larger buffer when
360 * it fills up. This guarantees constant time peek and remove operations, and 459 * it fills up. This guarantees constant time peek and remove operations, and
361 * amortized constant time add operations. 460 * amortized constant time add operations.
362 * 461 *
363 * The structure is efficient for any queue or stack usage. 462 * The structure is efficient for any queue or stack usage.
364 */ 463 */
365 class ListQueue<E> extends IterableBase<E> implements Queue<E> { 464 class ListQueue<E> extends Iterable<E> implements Queue<E> {
366 static const int _INITIAL_CAPACITY = 8; 465 static const int _INITIAL_CAPACITY = 8;
367 List<E> _table; 466 List<E> _table;
368 int _head; 467 int _head;
369 int _tail; 468 int _tail;
370 int _modificationCount = 0; 469 int _modificationCount = 0;
371 470
372 /** 471 /**
373 * Create an empty queue. 472 * Create an empty queue.
374 * 473 *
375 * If [initialCapacity] is given, prepare the queue for at least that many 474 * If [initialCapacity] is given, prepare the queue for at least that many
(...skipping 15 matching lines...) Expand all
391 * The elements are added to the queue, as by [addLast], in the order given by 490 * The elements are added to the queue, as by [addLast], in the order given by
392 * `elements.iterator`. 491 * `elements.iterator`.
393 * 492 *
394 * All `elements` should be assignable to [E]. 493 * All `elements` should be assignable to [E].
395 */ 494 */
396 factory ListQueue.from(Iterable elements) { 495 factory ListQueue.from(Iterable elements) {
397 if (elements is List) { 496 if (elements is List) {
398 int length = elements.length; 497 int length = elements.length;
399 ListQueue<E> queue = new ListQueue(length + 1); 498 ListQueue<E> queue = new ListQueue(length + 1);
400 assert(queue._table.length > length); 499 assert(queue._table.length > length);
401 List sourceList = elements; 500 for (int i = 0; i < length; i++) {
402 queue._table.setRange(0, length, sourceList, 0); 501 queue._table[i] = elements[i] as E;
502 }
403 queue._tail = length; 503 queue._tail = length;
404 return queue; 504 return queue;
405 } else { 505 } else {
406 int capacity = _INITIAL_CAPACITY; 506 int capacity = _INITIAL_CAPACITY;
407 if (elements is EfficientLength) { 507 if (elements is EfficientLength) {
408 capacity = elements.length; 508 capacity = elements.length;
409 } 509 }
410 ListQueue<E> result = new ListQueue<E>(capacity); 510 ListQueue<E> result = new ListQueue<E>(capacity);
411 for (final E element in elements) { 511 for (final element in elements) {
412 result.addLast(element); 512 result.addLast(element as E);
413 } 513 }
414 return result; 514 return result;
415 } 515 }
416 } 516 }
417 517
418 // Iterable interface. 518 // Iterable interface.
419 519
420 Iterator<E> get iterator => new _ListQueueIterator<E>(this); 520 Iterator<E> get iterator => new _ListQueueIterator<E>(this);
421 521
422 void forEach(void action (E element)) { 522 void forEach(void action (E element)) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 list = new List<E>()..length = length; 558 list = new List<E>()..length = length;
459 } else { 559 } else {
460 list = new List<E>(length); 560 list = new List<E>(length);
461 } 561 }
462 _writeToList(list); 562 _writeToList(list);
463 return list; 563 return list;
464 } 564 }
465 565
466 // Collection interface. 566 // Collection interface.
467 567
468 void add(E element) { 568 void add(E value) {
469 _add(element); 569 _add(value);
470 } 570 }
471 571
472 void addAll(Iterable<E> elements) { 572 void addAll(Iterable<E> elements) {
473 if (elements is List) { 573 if (elements is List/*<E>*/) {
474 List list = elements; 574 List<E> list = elements;
475 int addCount = list.length; 575 int addCount = list.length;
476 int length = this.length; 576 int length = this.length;
477 if (length + addCount >= _table.length) { 577 if (length + addCount >= _table.length) {
478 _preGrow(length + addCount); 578 _preGrow(length + addCount);
479 // After preGrow, all elements are at the start of the list. 579 // After preGrow, all elements are at the start of the list.
480 _table.setRange(length, length + addCount, list, 0); 580 _table.setRange(length, length + addCount, list, 0);
481 _tail += addCount; 581 _tail += addCount;
482 } else { 582 } else {
483 // Adding addCount elements won't reach _head. 583 // Adding addCount elements won't reach _head.
484 int endSpace = _table.length - _tail; 584 int endSpace = _table.length - _tail;
485 if (addCount < endSpace) { 585 if (addCount < endSpace) {
486 _table.setRange(_tail, _tail + addCount, list, 0); 586 _table.setRange(_tail, _tail + addCount, list, 0);
487 _tail += addCount; 587 _tail += addCount;
488 } else { 588 } else {
489 int preSpace = addCount - endSpace; 589 int preSpace = addCount - endSpace;
490 _table.setRange(_tail, _tail + endSpace, list, 0); 590 _table.setRange(_tail, _tail + endSpace, list, 0);
491 _table.setRange(0, preSpace, list, endSpace); 591 _table.setRange(0, preSpace, list, endSpace);
492 _tail = preSpace; 592 _tail = preSpace;
493 } 593 }
494 } 594 }
495 _modificationCount++; 595 _modificationCount++;
496 } else { 596 } else {
497 for (E element in elements) _add(element); 597 for (E element in elements) _add(element);
498 } 598 }
499 } 599 }
500 600
501 bool remove(Object object) { 601 bool remove(Object value) {
502 for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { 602 for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) {
503 E element = _table[i]; 603 E element = _table[i];
504 if (element == object) { 604 if (element == value) {
505 _remove(i); 605 _remove(i);
506 _modificationCount++; 606 _modificationCount++;
507 return true; 607 return true;
508 } 608 }
509 } 609 }
510 return false; 610 return false;
511 } 611 }
512 612
513 void _filterWhere(bool test(E element), bool removeMatching) { 613 void _filterWhere(bool test(E element), bool removeMatching) {
514 int index = _head;
515 int modificationCount = _modificationCount; 614 int modificationCount = _modificationCount;
516 int i = _head; 615 int i = _head;
517 while (i != _tail) { 616 while (i != _tail) {
518 E element = _table[i]; 617 E element = _table[i];
519 bool remove = identical(removeMatching, test(element)); 618 bool remove = identical(removeMatching, test(element));
520 _checkModification(modificationCount); 619 _checkModification(modificationCount);
521 if (remove) { 620 if (remove) {
522 i = _remove(i); 621 i = _remove(i);
523 modificationCount = ++_modificationCount; 622 modificationCount = ++_modificationCount;
524 } else { 623 } else {
(...skipping 29 matching lines...) Expand all
554 } 653 }
555 _head = _tail = 0; 654 _head = _tail = 0;
556 _modificationCount++; 655 _modificationCount++;
557 } 656 }
558 } 657 }
559 658
560 String toString() => IterableBase.iterableToFullString(this, "{", "}"); 659 String toString() => IterableBase.iterableToFullString(this, "{", "}");
561 660
562 // Queue interface. 661 // Queue interface.
563 662
564 void addLast(E element) { _add(element); } 663 void addLast(E value) { _add(value); }
565 664
566 void addFirst(E element) { 665 void addFirst(E value) {
567 _head = (_head - 1) & (_table.length - 1); 666 _head = (_head - 1) & (_table.length - 1);
568 _table[_head] = element; 667 _table[_head] = value;
569 if (_head == _tail) _grow(); 668 if (_head == _tail) _grow();
570 _modificationCount++; 669 _modificationCount++;
571 } 670 }
572 671
573 E removeFirst() { 672 E removeFirst() {
574 if (_head == _tail) throw IterableElementError.noElement(); 673 if (_head == _tail) throw IterableElementError.noElement();
575 _modificationCount++; 674 _modificationCount++;
576 E result = _table[_head]; 675 E result = _table[_head];
577 _table[_head] = null; 676 _table[_head] = null;
578 _head = (_head + 1) & (_table.length - 1); 677 _head = (_head + 1) & (_table.length - 1);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 _head = 0; 807 _head = 0;
709 } 808 }
710 } 809 }
711 810
712 /** 811 /**
713 * Iterator for a [ListQueue]. 812 * Iterator for a [ListQueue].
714 * 813 *
715 * Considers any add or remove operation a concurrent modification. 814 * Considers any add or remove operation a concurrent modification.
716 */ 815 */
717 class _ListQueueIterator<E> implements Iterator<E> { 816 class _ListQueueIterator<E> implements Iterator<E> {
718 final ListQueue _queue; 817 final ListQueue<E> _queue;
719 final int _end; 818 final int _end;
720 final int _modificationCount; 819 final int _modificationCount;
721 int _position; 820 int _position;
722 E _current; 821 E _current;
723 822
724 _ListQueueIterator(ListQueue queue) 823 _ListQueueIterator(ListQueue<E> queue)
725 : _queue = queue, 824 : _queue = queue,
726 _end = queue._tail, 825 _end = queue._tail,
727 _modificationCount = queue._modificationCount, 826 _modificationCount = queue._modificationCount,
728 _position = queue._head; 827 _position = queue._head;
729 828
730 E get current => _current; 829 E get current => _current;
731 830
732 bool moveNext() { 831 bool moveNext() {
733 _queue._checkModification(_modificationCount); 832 _queue._checkModification(_modificationCount);
734 if (_position == _end) { 833 if (_position == _end) {
735 _current = null; 834 _current = null;
736 return false; 835 return false;
737 } 836 }
738 _current = _queue._table[_position]; 837 _current = _queue._table[_position];
739 _position = (_position + 1) & (_queue._table.length - 1); 838 _position = (_position + 1) & (_queue._table.length - 1);
740 return true; 839 return true;
741 } 840 }
742 } 841 }
OLDNEW
« no previous file with comments | « tool/input_sdk/lib/collection/linked_list.dart ('k') | tool/input_sdk/lib/collection/splay_tree.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698