Skip to content

Commit

Permalink
Started to implement a BufferedIterator
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Sep 21, 2014
1 parent a183391 commit f979377
Showing 1 changed file with 129 additions and 0 deletions.
129 changes: 129 additions & 0 deletions src/Collection/Iterator/BufferedIterator.php
@@ -0,0 +1,129 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://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. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Collection\Iterator;

use Cake\Collection\Collection;
use SplDoublyLinkedList;

/**
* Creates an iterator from another iterator that will keep in memory the results
* from the inner iterator so they don't have to be calculated again.
*/
class BufferedIterator extends Collection {

/**
* The in-memory cache containing results from previous iterators
*
* @var callable
*/
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 array
*/
protected $_current;

/**
* Last key obtained from the inner iterator
*
* @var array
*/
protected $_key;

protected $_started = 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);
}

public function key() {
return $this->_key;
}

/**
* Returns the current record in the result iterator
*
* Part of Iterator interface.
*
* @return array|object
*/
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;
}

/**
*
* @return mixed
*/
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->add($this->_index, [
'key' => $this->_index,
'value' => $this->_current
]);
}

return $valid;
}

public function next() {
$this->_index++;
parent::next();
}

}

0 comments on commit f979377

Please sign in to comment.