OLD | NEW |
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]. |
11 */ | 11 */ |
12 abstract class Queue<E> implements Collection<E> { | 12 abstract class Queue<E> implements Iterable<E> { |
13 | 13 |
14 /** | 14 /** |
15 * Creates a queue. | 15 * Creates a queue. |
16 */ | 16 */ |
17 factory Queue() => new ListQueue<E>(); | 17 factory Queue() => new ListQueue<E>(); |
18 | 18 |
19 /** | 19 /** |
20 * Creates a queue with the elements of [other]. The order in | 20 * Creates a queue with the elements of [other]. The order in |
21 * the queue will be the order provided by the iterator of [other]. | 21 * the queue will be the order provided by the iterator of [other]. |
22 */ | 22 */ |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 153 } |
154 } | 154 } |
155 | 155 |
156 /** | 156 /** |
157 * A [Queue] implementation based on a double-linked list. | 157 * A [Queue] implementation based on a double-linked list. |
158 * | 158 * |
159 * Allows constant time add, remove-at-ends and peek operations. | 159 * Allows constant time add, remove-at-ends and peek operations. |
160 * | 160 * |
161 * Can do [removeAll] and [retainAll] in linear time. | 161 * Can do [removeAll] and [retainAll] in linear time. |
162 */ | 162 */ |
163 class DoubleLinkedQueue<E> extends Collection<E> implements Queue<E> { | 163 class DoubleLinkedQueue<E> extends Iterable<E> implements Queue<E> { |
164 _DoubleLinkedQueueEntrySentinel<E> _sentinel; | 164 _DoubleLinkedQueueEntrySentinel<E> _sentinel; |
165 int _elementCount = 0; | 165 int _elementCount = 0; |
166 | 166 |
167 DoubleLinkedQueue() { | 167 DoubleLinkedQueue() { |
168 _sentinel = new _DoubleLinkedQueueEntrySentinel<E>(); | 168 _sentinel = new _DoubleLinkedQueueEntrySentinel<E>(); |
169 } | 169 } |
170 | 170 |
171 factory DoubleLinkedQueue.from(Iterable<E> other) { | 171 factory DoubleLinkedQueue.from(Iterable<E> other) { |
172 Queue<E> list = new DoubleLinkedQueue(); | 172 Queue<E> list = new DoubleLinkedQueue(); |
173 for (final e in other) { | 173 for (final e in other) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 f(entry); | 303 f(entry); |
304 entry = nextEntry; | 304 entry = nextEntry; |
305 } | 305 } |
306 } | 306 } |
307 | 307 |
308 _DoubleLinkedQueueIterator<E> get iterator { | 308 _DoubleLinkedQueueIterator<E> get iterator { |
309 return new _DoubleLinkedQueueIterator<E>(_sentinel); | 309 return new _DoubleLinkedQueueIterator<E>(_sentinel); |
310 } | 310 } |
311 | 311 |
312 String toString() { | 312 String toString() { |
313 return Collections.collectionToString(this); | 313 return ToString.iterableToString(this); |
314 } | 314 } |
315 } | 315 } |
316 | 316 |
317 class _DoubleLinkedQueueIterator<E> implements Iterator<E> { | 317 class _DoubleLinkedQueueIterator<E> implements Iterator<E> { |
318 _DoubleLinkedQueueEntrySentinel<E> _sentinel; | 318 _DoubleLinkedQueueEntrySentinel<E> _sentinel; |
319 DoubleLinkedQueueEntry<E> _currentEntry = null; | 319 DoubleLinkedQueueEntry<E> _currentEntry = null; |
320 E _current; | 320 E _current; |
321 | 321 |
322 _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel<E> sentinel) | 322 _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel<E> sentinel) |
323 : _sentinel = sentinel, _currentEntry = sentinel; | 323 : _sentinel = sentinel, _currentEntry = sentinel; |
(...skipping 20 matching lines...) Expand all Loading... |
344 | 344 |
345 /** | 345 /** |
346 * List based [Queue]. | 346 * List based [Queue]. |
347 * | 347 * |
348 * Keeps a cyclic buffer of elements, and grows to a larger buffer when | 348 * Keeps a cyclic buffer of elements, and grows to a larger buffer when |
349 * it fills up. This guarantees constant time peek and remove operations, and | 349 * it fills up. This guarantees constant time peek and remove operations, and |
350 * amortized constant time add operations. | 350 * amortized constant time add operations. |
351 * | 351 * |
352 * The structure is efficient for any queue or stack usage. | 352 * The structure is efficient for any queue or stack usage. |
353 * | 353 * |
354 * Collection operations like [removeAll] and [removeWhere] are very | 354 * Operations like [removeAll] and [removeWhere] are very |
355 * inefficient. If those are needed, use a [DoubleLinkedQueue] instead. | 355 * inefficient. If those are needed, use a [DoubleLinkedQueue] instead. |
356 */ | 356 */ |
357 class ListQueue<E> extends Collection<E> implements Queue<E>{ | 357 class ListQueue<E> extends Iterable<E> implements Queue<E>{ |
358 static const int _INITIAL_CAPACITY = 8; | 358 static const int _INITIAL_CAPACITY = 8; |
359 List<E> _table; | 359 List<E> _table; |
360 int _head; | 360 int _head; |
361 int _tail; | 361 int _tail; |
362 int _modificationCount = 0; | 362 int _modificationCount = 0; |
363 | 363 |
364 /** | 364 /** |
365 * Create an empty queue. | 365 * Create an empty queue. |
366 * | 366 * |
367 * If [initialCapacity] is given, prepare the queue for at least that many | 367 * If [initialCapacity] is given, prepare the queue for at least that many |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { | 483 for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { |
484 E element = _table[i]; | 484 E element = _table[i]; |
485 if (element == object) { | 485 if (element == object) { |
486 _remove(i); | 486 _remove(i); |
487 return; | 487 return; |
488 } | 488 } |
489 } | 489 } |
490 _modificationCount++; | 490 _modificationCount++; |
491 } | 491 } |
492 | 492 |
493 void removeAll(Iterable objectsToRemove) { | |
494 IterableMixinWorkaround.removeAllList(this, objectsToRemove); | |
495 } | |
496 | |
497 void retainAll(Iterable objectsToRetain) { | |
498 IterableMixinWorkaround.retainAll(this, objectsToRetain); | |
499 } | |
500 | |
501 void _filterWhere(bool test(E element), bool removeMatching) { | 493 void _filterWhere(bool test(E element), bool removeMatching) { |
502 int index = _head; | 494 int index = _head; |
503 int modificationCount = _modificationCount; | 495 int modificationCount = _modificationCount; |
504 int i = _head; | 496 int i = _head; |
505 while (i != _tail) { | 497 while (i != _tail) { |
506 E element = _table[i]; | 498 E element = _table[i]; |
507 bool remove = (test(element) == removeMatching); | 499 bool remove = (test(element) == removeMatching); |
508 _checkModification(modificationCount); | 500 _checkModification(modificationCount); |
509 if (remove) { | 501 if (remove) { |
510 i = _remove(i); | 502 i = _remove(i); |
(...skipping 28 matching lines...) Expand all Loading... |
539 if (_head != _tail) { | 531 if (_head != _tail) { |
540 for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { | 532 for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { |
541 _table[i] = null; | 533 _table[i] = null; |
542 } | 534 } |
543 _head = _tail = 0; | 535 _head = _tail = 0; |
544 _modificationCount++; | 536 _modificationCount++; |
545 } | 537 } |
546 } | 538 } |
547 | 539 |
548 String toString() { | 540 String toString() { |
549 return Collections.collectionToString(this); | 541 return ToString.iterableToString(this); |
550 } | 542 } |
551 | 543 |
552 // Queue interface. | 544 // Queue interface. |
553 | 545 |
554 void addLast(E element) { _add(element); } | 546 void addLast(E element) { _add(element); } |
555 | 547 |
556 void addFirst(E element) { | 548 void addFirst(E element) { |
557 _head = (_head - 1) & (_table.length - 1); | 549 _head = (_head - 1) & (_table.length - 1); |
558 _table[_head] = element; | 550 _table[_head] = element; |
559 if (_head == _tail) _grow(); | 551 if (_head == _tail) _grow(); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 _queue._checkModification(_modificationCount); | 708 _queue._checkModification(_modificationCount); |
717 if (_position == _end) { | 709 if (_position == _end) { |
718 _current = null; | 710 _current = null; |
719 return false; | 711 return false; |
720 } | 712 } |
721 _current = _queue._table[_position]; | 713 _current = _queue._table[_position]; |
722 _position = (_position + 1) & (_queue._table.length - 1); | 714 _position = (_position + 1) & (_queue._table.length - 1); |
723 return true; | 715 return true; |
724 } | 716 } |
725 } | 717 } |
OLD | NEW |