Browse Source

Started to implement a BufferedIterator

Jose Lorenzo Rodriguez 11 years ago
parent
commit
f9793773ae
1 changed files with 129 additions and 0 deletions
  1. 129 0
      src/Collection/Iterator/BufferedIterator.php

+ 129 - 0
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();
+	}
+
+}