JScanIterator   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 188
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 19
c 2
b 1
f 0
lcom 1
cbo 1
dl 0
loc 188
ccs 54
cts 54
cp 1
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C scan() 0 40 7
A current() 0 4 1
A next() 0 4 1
A key() 0 4 1
A valid() 0 9 3
A rewind() 0 4 1
A setCount() 0 4 1
A setQueues() 0 4 1
A setStates() 0 4 1
A setFormat() 0 4 1
1
<?php
2
3
namespace Phloppy\Client\Node;
4
5
use Phloppy\Client\AbstractClient;
6
use Phloppy\Stream\StreamInterface;
7
use Psr\Log\LoggerInterface;
8
9
/**
10
 * JSCAN Iterator.
11
 *
12
 * @see https://github.com/antirez/disque#jscan-cursor-count-count-busyloop-queue-queue-state-state1-state-state2--state-staten-reply-allid
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 139 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
13
 */
14
class JScanIterator extends AbstractClient implements \Iterator {
15
16
    const FORMAT_ID  = 'id';
17
    const FORMAT_ALL = 'all';
18
19
    /**
20
     * @var int Current disque cursor.
21
     */
22
    private $cursor = -1;
23
24
    /**
25
     * @var array returned elements.
26
     */
27
    private $elements = [];
28
29
    /**
30
     * @var int current iterator index.
31
     */
32
    private $index = 0;
33
34
    /**
35
     * Pagination count per call.
36
     *
37
     * @var int
38
     */
39
    private $count = 100;
40
41
    /**
42
     * @var string[]
43
     */
44
    private $queues = [];
45
46
    /**
47
     * @var string[]
48
     */
49
    private $states = [];
50
51
    /**
52
     * @var string
53
     */
54
    private $format = self::FORMAT_ID;
55
56
57
    /**
58
     * @param StreamInterface $stream
59
     * @param LoggerInterface|null $log
60
     */
61 1
    public function __construct(StreamInterface $stream, LoggerInterface $log = null)
62
    {
63 1
        parent::__construct($stream, $log);
64 1
    }
65
66 1
    private function scan()
67
    {
68
        // initialize cursor
69 1
        if ($this->cursor < 0) {
70 1
            $this->cursor = 0;
71 1
        }
72
73
        // Iterating here because the response of the jscan
74
        // iteration might be empty due to filter restrictions
75
        // (disque internally limits the number of dictScan iterations).
76
        // Thus we rescan if we didn't get any elements and the cursor
77
        // is still valid.
78
        do {
79 1
            $command = ['JSCAN', $this->cursor];
80
81 1
            if ($this->count) {
82 1
                $command = array_merge($command, ['COUNT', $this->count]);
83 1
            } else {
84 1
                $command[] = 'BUSYLOOP';
85
            }
86
87 1
            if (!empty($this->queues)) {
88
                $command = array_reduce($this->queues, function($prev, $current) {
89 1
                    return array_merge($prev, ['QUEUE', $current]);
90 1
                }, $command);
91 1
            }
92
93
94 1
            if (!empty($this->states)) {
95 1
                $command = array_reduce($this->states, function($prev, $current) {
96 1
                    return array_merge($prev, ['STATE', $current]);
97 1
                }, $command);
98 1
            }
99
100 1
            $command        = array_merge($command, ['REPLY', $this->format]);
101 1
            $response       = $this->send($command);
102 1
            $this->cursor   = (int) $response[0];
103 1
            $this->elements = array_merge($this->elements, $response[1]);
104 1
        } while ($this->cursor && empty($response[1]));
105 1
    }
106
107
108
    /**
109
     * Return the current element
110
     *
111
     * @link http://php.net/manual/en/iterator.current.php
112
     * @return string the next queue name
113
     */
114 1
    public function current()
115
    {
116 1
        return $this->elements[$this->index];
117
    }
118
119
    /**
120
     * Move forward to next element
121
     *
122
     * @link http://php.net/manual/en/iterator.next.php
123
     */
124 1
    public function next()
125
    {
126 1
        $this->index++;
127 1
    }
128
129
    /**
130
     * Return the key of the current element
131
     *
132
     * @link http://php.net/manual/en/iterator.key.php
133
     * @return int scalar on success, or null on failure.
134
     */
135 1
    public function key()
136
    {
137 1
        return $this->index;
138
    }
139
140
    /**
141
     * Checks if current position is valid
142
     *
143
     * @link http://php.net/manual/en/iterator.valid.php
144
     * @return boolean true on success or false on failure.
145
     */
146 1
    public function valid()
147
    {
148
        // initialize/refresh cursor
149 1
        if ($this->cursor != 0 && !isset($this->elements[$this->index])) {
150 1
            $this->scan();
151 1
        }
152
153 1
        return isset($this->elements[$this->index]);
154
    }
155
156
    /**
157
     * Rewind the Iterator to the first element
158
     *
159
     * @link http://php.net/manual/en/iterator.rewind.php
160
     */
161 1
    public function rewind()
162
    {
163 1
        $this->index = 0;
164 1
    }
165
166
167
    /**
168
     * @param int $count
169
     */
170 1
    public function setCount($count)
171
    {
172 1
        $this->count = (int) $count;
173 1
    }
174
175
176
    /**
177
     * @param string[] $queues
178
     */
179 1
    public function setQueues($queues)
180
    {
181 1
        $this->queues = $queues;
182 1
    }
183
184
185
    /**
186
     * @param string[] $states
187
     */
188 1
    public function setStates($states)
189
    {
190 1
        $this->states = $states;
191 1
    }
192
193
194
    /**
195
     * @param string $format
196
     */
197 1
    public function setFormat($format)
198
    {
199 1
        $this->format = $format;
200 1
    }
201
}
202