Chromium Code Reviews| 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]. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 | 72 |
| 73 | 73 |
| 74 /** | 74 /** |
| 75 * An entry in a doubly linked list. It contains a pointer to the next | 75 * An entry in a doubly linked list. It contains a pointer to the next |
| 76 * entry, the previous entry, and the boxed element. | 76 * entry, the previous entry, and the boxed element. |
| 77 * | 77 * |
| 78 * WARNING: This class is temporary located in dart:core. It'll be removed | 78 * WARNING: This class is temporary located in dart:core. It'll be removed |
| 79 * at some point in the near future. | 79 * at some point in the near future. |
| 80 */ | 80 */ |
| 81 class DoubleLinkedQueueEntry<E> { | 81 class DoubleLinkedQueueEntry<E> { |
| 82 | |
| 82 DoubleLinkedQueueEntry<E> _previous; | 83 DoubleLinkedQueueEntry<E> _previous; |
| 83 DoubleLinkedQueueEntry<E> _next; | 84 DoubleLinkedQueueEntry<E> _next; |
| 84 E _element; | 85 E _element; |
| 85 | 86 |
| 86 DoubleLinkedQueueEntry(E e) { | 87 DoubleLinkedQueueEntry(E e) { |
| 87 _element = e; | 88 _element = e; |
| 88 } | 89 } |
| 89 | 90 |
| 90 void _link(DoubleLinkedQueueEntry<E> p, | 91 void _link(DoubleLinkedQueueEntry<E> p, |
| 91 DoubleLinkedQueueEntry<E> n) { | 92 DoubleLinkedQueueEntry<E> n) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 } | 164 } |
| 164 | 165 |
| 165 /** | 166 /** |
| 166 * A [Queue] implementation based on a double-linked list. | 167 * A [Queue] implementation based on a double-linked list. |
| 167 * | 168 * |
| 168 * Allows constant time add, remove-at-ends and peek operations. | 169 * Allows constant time add, remove-at-ends and peek operations. |
| 169 * | 170 * |
| 170 * Can do [removeAll] and [retainAll] in linear time. | 171 * Can do [removeAll] and [retainAll] in linear time. |
| 171 */ | 172 */ |
| 172 class DoubleLinkedQueue<E> extends IterableBase<E> implements Queue<E> { | 173 class DoubleLinkedQueue<E> extends IterableBase<E> implements Queue<E> { |
| 174 static List _toStringList = new List(); | |
| 173 _DoubleLinkedQueueEntrySentinel<E> _sentinel; | 175 _DoubleLinkedQueueEntrySentinel<E> _sentinel; |
| 174 int _elementCount = 0; | 176 int _elementCount = 0; |
| 175 | 177 |
| 176 DoubleLinkedQueue() { | 178 DoubleLinkedQueue() { |
| 177 _sentinel = new _DoubleLinkedQueueEntrySentinel<E>(); | 179 _sentinel = new _DoubleLinkedQueueEntrySentinel<E>(); |
| 178 } | 180 } |
| 179 | 181 |
| 180 factory DoubleLinkedQueue.from(Iterable<E> other) { | 182 factory DoubleLinkedQueue.from(Iterable<E> other) { |
| 181 Queue<E> list = new DoubleLinkedQueue(); | 183 Queue<E> list = new DoubleLinkedQueue(); |
| 182 for (final e in other) { | 184 for (final e in other) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 293 while (!identical(entry, _sentinel)) { | 295 while (!identical(entry, _sentinel)) { |
| 294 DoubleLinkedQueueEntry<E> nextEntry = entry._next; | 296 DoubleLinkedQueueEntry<E> nextEntry = entry._next; |
| 295 f(entry); | 297 f(entry); |
| 296 entry = nextEntry; | 298 entry = nextEntry; |
| 297 } | 299 } |
| 298 } | 300 } |
| 299 | 301 |
| 300 _DoubleLinkedQueueIterator<E> get iterator { | 302 _DoubleLinkedQueueIterator<E> get iterator { |
| 301 return new _DoubleLinkedQueueIterator<E>(_sentinel); | 303 return new _DoubleLinkedQueueIterator<E>(_sentinel); |
| 302 } | 304 } |
| 303 | 305 |
| 304 String toString() { | 306 String toString() { |
| 305 return ToString.iterableToString(this); | 307 for(int i = 0; i < _toStringList.length; i++) { |
|
floitsch
2013/07/08 12:00:50
Redirect to IterableMixinWorkaround for now. Add T
zarah
2013/07/08 14:35:15
Done.
| |
| 308 if(identical(_toStringList[i], this)) | |
| 309 return '{...}'; | |
| 310 } | |
| 311 _toStringList.add(this); | |
| 312 String result = IterableMixinWorkaround.toStringIterable(this); | |
| 313 _toStringList.remove(this); | |
| 314 return result; | |
| 306 } | 315 } |
| 307 } | 316 } |
| 308 | 317 |
| 309 class _DoubleLinkedQueueIterator<E> implements Iterator<E> { | 318 class _DoubleLinkedQueueIterator<E> implements Iterator<E> { |
| 310 _DoubleLinkedQueueEntrySentinel<E> _sentinel; | 319 _DoubleLinkedQueueEntrySentinel<E> _sentinel; |
| 311 DoubleLinkedQueueEntry<E> _currentEntry = null; | 320 DoubleLinkedQueueEntry<E> _currentEntry = null; |
| 312 E _current; | 321 E _current; |
| 313 | 322 |
| 314 _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel<E> sentinel) | 323 _DoubleLinkedQueueIterator(_DoubleLinkedQueueEntrySentinel<E> sentinel) |
| 315 : _sentinel = sentinel, _currentEntry = sentinel; | 324 : _sentinel = sentinel, _currentEntry = sentinel; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 341 * it fills up. This guarantees constant time peek and remove operations, and | 350 * it fills up. This guarantees constant time peek and remove operations, and |
| 342 * amortized constant time add operations. | 351 * amortized constant time add operations. |
| 343 * | 352 * |
| 344 * The structure is efficient for any queue or stack usage. | 353 * The structure is efficient for any queue or stack usage. |
| 345 * | 354 * |
| 346 * Operations like [removeAll] and [removeWhere] are very | 355 * Operations like [removeAll] and [removeWhere] are very |
| 347 * inefficient. If those are needed, use a [DoubleLinkedQueue] instead. | 356 * inefficient. If those are needed, use a [DoubleLinkedQueue] instead. |
| 348 */ | 357 */ |
| 349 class ListQueue<E> extends IterableBase<E> implements Queue<E> { | 358 class ListQueue<E> extends IterableBase<E> implements Queue<E> { |
| 350 static const int _INITIAL_CAPACITY = 8; | 359 static const int _INITIAL_CAPACITY = 8; |
| 360 static List _toStringList = new List(); | |
| 351 List<E> _table; | 361 List<E> _table; |
| 352 int _head; | 362 int _head; |
| 353 int _tail; | 363 int _tail; |
| 354 int _modificationCount = 0; | 364 int _modificationCount = 0; |
| 355 | 365 |
| 356 /** | 366 /** |
| 357 * Create an empty queue. | 367 * Create an empty queue. |
| 358 * | 368 * |
| 359 * If [initialCapacity] is given, prepare the queue for at least that many | 369 * If [initialCapacity] is given, prepare the queue for at least that many |
| 360 * elements. | 370 * elements. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 void clear() { | 533 void clear() { |
| 524 if (_head != _tail) { | 534 if (_head != _tail) { |
| 525 for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { | 535 for (int i = _head; i != _tail; i = (i + 1) & (_table.length - 1)) { |
| 526 _table[i] = null; | 536 _table[i] = null; |
| 527 } | 537 } |
| 528 _head = _tail = 0; | 538 _head = _tail = 0; |
| 529 _modificationCount++; | 539 _modificationCount++; |
| 530 } | 540 } |
| 531 } | 541 } |
| 532 | 542 |
| 533 String toString() { | 543 String toString() { |
|
floitsch
2013/07/08 12:00:50
ditto.
zarah
2013/07/08 14:35:15
Done.
| |
| 534 return ToString.iterableToString(this); | 544 for(int i = 0; i < _toStringList.length; i++) { |
| 545 if(identical(_toStringList[i], this)) | |
| 546 return '{...}'; | |
| 547 } | |
| 548 _toStringList.add(this); | |
| 549 String result = IterableMixinWorkaround.toStringIterable(this); | |
| 550 _toStringList.remove(this); | |
| 551 return result; | |
| 535 } | 552 } |
| 536 | 553 |
| 537 // Queue interface. | 554 // Queue interface. |
| 538 | 555 |
| 539 void addLast(E element) { _add(element); } | 556 void addLast(E element) { _add(element); } |
| 540 | 557 |
| 541 void addFirst(E element) { | 558 void addFirst(E element) { |
| 542 _head = (_head - 1) & (_table.length - 1); | 559 _head = (_head - 1) & (_table.length - 1); |
| 543 _table[_head] = element; | 560 _table[_head] = element; |
| 544 if (_head == _tail) _grow(); | 561 if (_head == _tail) _grow(); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 _head = 0; | 693 _head = 0; |
| 677 } | 694 } |
| 678 } | 695 } |
| 679 | 696 |
| 680 /** | 697 /** |
| 681 * Iterator for a [ListQueue]. | 698 * Iterator for a [ListQueue]. |
| 682 * | 699 * |
| 683 * Considers any add or remove operation a concurrent modification. | 700 * Considers any add or remove operation a concurrent modification. |
| 684 */ | 701 */ |
| 685 class _ListQueueIterator<E> implements Iterator<E> { | 702 class _ListQueueIterator<E> implements Iterator<E> { |
| 703 | |
| 686 final ListQueue _queue; | 704 final ListQueue _queue; |
| 687 final int _end; | 705 final int _end; |
| 688 final int _modificationCount; | 706 final int _modificationCount; |
| 689 int _position; | 707 int _position; |
| 690 E _current; | 708 E _current; |
| 691 | 709 |
| 692 _ListQueueIterator(ListQueue queue) | 710 _ListQueueIterator(ListQueue queue) |
| 693 : _queue = queue, | 711 : _queue = queue, |
| 694 _end = queue._tail, | 712 _end = queue._tail, |
| 695 _modificationCount = queue._modificationCount, | 713 _modificationCount = queue._modificationCount, |
| 696 _position = queue._head; | 714 _position = queue._head; |
| 697 | 715 |
| 698 E get current => _current; | 716 E get current => _current; |
| 699 | 717 |
| 700 bool moveNext() { | 718 bool moveNext() { |
| 701 _queue._checkModification(_modificationCount); | 719 _queue._checkModification(_modificationCount); |
| 702 if (_position == _end) { | 720 if (_position == _end) { |
| 703 _current = null; | 721 _current = null; |
| 704 return false; | 722 return false; |
| 705 } | 723 } |
| 706 _current = _queue._table[_position]; | 724 _current = _queue._table[_position]; |
| 707 _position = (_position + 1) & (_queue._table.length - 1); | 725 _position = (_position + 1) & (_queue._table.length - 1); |
| 708 return true; | 726 return true; |
| 709 } | 727 } |
| 710 } | 728 } |
| OLD | NEW |