123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- <?php
- /**
- * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- * @link https://cakephp.org CakePHP(tm) Project
- * @since 3.0.0
- * @license https://opensource.org/licenses/mit-license.php MIT License
- */
- namespace Cake\Collection\Iterator;
- use Cake\Collection\Collection;
- use Countable;
- use Serializable;
- use SplDoublyLinkedList;
- /**
- * Creates an iterator from another iterator that will keep the results of the inner
- * iterator in memory, so that results don't have to be re-calculated.
- */
- class BufferedIterator extends Collection implements Countable, Serializable
- {
- /**
- * The in-memory cache containing results from previous iterators
- *
- * @var \SplDoublyLinkedList
- */
- protected $_buffer;
- /**
- * Points to the next record number that should be fetched
- *
- * @var int
- */
- protected $_index = 0;
- /**
- * Last record fetched from the inner iterator
- *
- * @var mixed
- */
- protected $_current;
- /**
- * Last key obtained from the inner iterator
- *
- * @var mixed
- */
- protected $_key;
- /**
- * Whether or not the internal iterator's rewind method was already
- * called
- *
- * @var bool
- */
- protected $_started = false;
- /**
- * Whether or not the internal iterator has reached its end.
- *
- * @var bool
- */
- protected $_finished = false;
- /**
- * Maintains an in-memory cache of the results yielded by the internal
- * iterator.
- *
- * @param array|\Traversable $items The items to be filtered.
- */
- public function __construct($items)
- {
- $this->_buffer = new SplDoublyLinkedList();
- parent::__construct($items);
- }
- /**
- * Returns the current key in the iterator
- *
- * @return mixed
- */
- public function key()
- {
- return $this->_key;
- }
- /**
- * Returns the current record in the iterator
- *
- * @return mixed
- */
- public function current()
- {
- return $this->_current;
- }
- /**
- * Rewinds the collection
- *
- * @return void
- */
- public function rewind()
- {
- if ($this->_index === 0 && !$this->_started) {
- $this->_started = true;
- parent::rewind();
- return;
- }
- $this->_index = 0;
- }
- /**
- * Returns whether or not the iterator has more elements
- *
- * @return bool
- */
- public function valid()
- {
- if ($this->_buffer->offsetExists($this->_index)) {
- $current = $this->_buffer->offsetGet($this->_index);
- $this->_current = $current['value'];
- $this->_key = $current['key'];
- return true;
- }
- $valid = parent::valid();
- if ($valid) {
- $this->_current = parent::current();
- $this->_key = parent::key();
- $this->_buffer->push([
- 'key' => $this->_key,
- 'value' => $this->_current
- ]);
- }
- $this->_finished = !$valid;
- return $valid;
- }
- /**
- * Advances the iterator pointer to the next element
- *
- * @return void
- */
- public function next()
- {
- $this->_index++;
- if (!$this->_finished) {
- parent::next();
- }
- }
- /**
- * Returns the number or items in this collection
- *
- * @return int
- */
- public function count()
- {
- if (!$this->_started) {
- $this->rewind();
- }
- while ($this->valid()) {
- $this->next();
- }
- return $this->_buffer->count();
- }
- /**
- * Returns a string representation of this object that can be used
- * to reconstruct it
- *
- * @return string
- */
- public function serialize()
- {
- if (!$this->_finished) {
- $this->count();
- }
- return serialize($this->_buffer);
- }
- /**
- * Unserializes the passed string and rebuilds the BufferedIterator instance
- *
- * @param string $buffer The serialized buffer iterator
- * @return void
- */
- public function unserialize($buffer)
- {
- $this->__construct([]);
- $this->_buffer = unserialize($buffer);
- $this->_started = true;
- $this->_finished = true;
- }
- }
|