CachingIterator   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 1
dl 0
loc 91
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A uncachedKey() 0 4 1
A uncachedCurrent() 0 4 1
A uncachedValid() 0 4 1
A uncachedRewind() 0 4 1
A uncachedNext() 0 4 1
A cacheUpTo() 0 11 4
A rewind() 0 10 2
A key() 0 5 1
A current() 0 5 1
A next() 0 4 1
A hasNext() 0 5 1
A valid() 0 5 1
1
<?php
2
3
namespace itertools;
4
5
use IteratorIterator;
6
7
/**
8
 * This iterator is able to prefetch its values and cache them.
9
 * This you to look ahead of the current iteration position.
10
 */
11
class CachingIterator extends IteratorIterator
12
{
13
	const NO_REWIND = 'NO_REWIND';
14
	const CACHE_ISSUED_REWIND = 'CACHE_ISSUED_REWIND';
15
	const OUTER_ISSUED_REWIND = 'OUTER_ISSUED_REWIND';
16
17
	protected $cache = array();
18
	protected $rewindStatus = self::NO_REWIND;
19
20
	public function __construct($innerIterator)
21
	{
22
		parent::__construct(IterUtil::asIterator($innerIterator));
23
	}
24
25
	protected function uncachedKey()
26
	{
27
		return $this->getInnerIterator()->key();
28
	}
29
30
	protected function uncachedCurrent()
31
	{
32
		return $this->getInnerIterator()->current();
33
	}
34
35
	protected function uncachedValid()
36
	{
37
		return $this->getInnerIterator()->valid();
38
	}
39
40
	protected function uncachedRewind()
41
	{
42
		return $this->getInnerIterator()->rewind();
43
	}
44
45
	protected function uncachedNext()
46
	{
47
		return $this->getInnerIterator()->next();
48
	}
49
50
	public function cacheUpTo($count)
51
	{
52
		if(self::NO_REWIND == $this->rewindStatus) {
53
			$this->uncachedRewind();
54
			$this->rewindStatus = self::CACHE_ISSUED_REWIND;
55
		}
56
		while(count($this->cache) < $count && $this->uncachedValid()) {
57
			$this->cache[] = (object) array('key' => $this->uncachedKey(), 'current' => $this->uncachedCurrent());
58
			$this->uncachedNext();
59
		}
60
	}
61
62
    public function rewind()
63
	{
64
		if(self::CACHE_ISSUED_REWIND == $this->rewindStatus) {
65
			$this->rewindStatus = self::OUTER_ISSUED_REWIND;
66
			return;
67
		}
68
		$this->cache = array();
69
		$this->uncachedRewind();
70
		$this->rewindStatus = self::OUTER_ISSUED_REWIND;
71
    }
72
73
    public function key()
74
	{
75
		$this->cacheUpTo(1);
76
        return reset($this->cache)->key;
77
    }
78
79
    public function current()
80
	{
81
		$this->cacheUpTo(1);
82
        return reset($this->cache)->current;
83
    }
84
85
    public function next()
86
	{
87
		array_shift($this->cache);
88
    }
89
90
	public function hasNext($offset = 1)
91
	{
92
		$this->cacheUpTo($offset);
93
		return count($this->cache) >= $offset;
94
	}
95
96
    public function valid()
97
	{
98
		$this->cacheUpTo(1);
99
		return count($this->cache) > 0;
100
    }
101
}
102
103