| 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 |