Test Failed
Push — master ( 3e22f3...90cc1b )
by Kirill
03:50
created

Pipeline::pop()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 10
ccs 0
cts 8
cp 0
crap 6
rs 9.9332
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\SDL\Compiler;
11
12
/**
13
 * Class Pipeline
14
 */
15
class Pipeline implements \IteratorAggregate, \Countable
16
{
17
    /**
18
     * Example struct:
19
     *
20
     * <code>
21
     *  [
22
     *      PRIORITY_1 => \SplQueue([1, 2, 3]),
23
     *      PRIORITY_2 => \SplQueue([1, 2, 3]),
24
     *      PRIORITY_3 => \SplQueue([1, 2, 3]),
25
     *  ]
26
     * </code>
27
     *
28
     * @var \SplQueue[]
29
     */
30
    private $queue = [];
31
32
    /**
33
     * @return \Traversable|callable[]
34
     */
35
    public function getIterator(): \Traversable
36
    {
37
        while ($next = $this->next()) {
38
            yield $next;
39
        }
40
    }
41
42
    /**
43
     * @return null|callable
44
     */
45
    private function next(): ?callable
46
    {
47
        foreach ($this->queue as $queue) {
48
            if ($queue->count() > 0) {
49
                return $queue->shift();
50
            }
51
        }
52
53
        return null;
54
    }
55
56
    /**
57
     * @param int $priority
58
     * @param callable $then
59
     */
60
    public function push(int $priority, callable $then): void
61
    {
62
        if (! \array_key_exists($priority, $this->queue)) {
63
            $this->queue[$priority] = $this->createList();
64
        }
65
66
        $this->queue[$priority]->push($then);
67
    }
68
69
    /**
70
     * @return \SplDoublyLinkedList
71
     */
72
    protected function createList(): \SplDoublyLinkedList
73
    {
74
        return new \SplQueue();
75
    }
76
77
    /**
78
     * @return int
79
     */
80
    public function count(): int
81
    {
82
        return (int)\array_reduce($this->queue, function (int $result, \SplQueue $queue): int {
83
            return $result + $queue->count();
84
        }, 0);
85
    }
86
87
    /**
88
     * @return callable
89
     * @throws \UnderflowException
90
     */
91
    public function pop(): callable
92
    {
93
        $result = $this->next();
94
95
        if ($result === null) {
96
            throw new \UnderflowException('Can not fetch data from empty heap');
97
        }
98
99
        return $result;
100
    }
101
102
    /**
103
     * @param \Closure $each
104
     */
105
    public function reduce(\Closure $each): void
106
    {
107
        foreach ($this->getIterator() as $callback) {
108
            $each($callback);
109
        }
110
    }
111
}
112