Completed
Push — master ( 01762c...256c3c )
by Karsten
02:12
created

solveIntermediateOperationChain()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 39
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 17
cts 17
cp 1
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 17
nc 7
nop 2
crap 7
1
<?php
2
/**
3
 * File was created 06.05.2015 22:56
4
 *
5
 * @author Karsten J. Gerber <[email protected]>
6
 */
7
8
namespace PeekAndPoke\Component\Psi;
9
10
/**
11
 * @api
12
 *
13
 * @author Karsten J. Gerber <[email protected]>
14
 */
15
class DefaultOperationChainSolver implements OperationChainSolver
16
{
17
    /**
18
     * {@inheritdoc}
19
     */
20 93
    public function solve(\Iterator $operations, \Iterator $items)
21
    {
22
        // search for all UnaryOperations
23 93
        $tempResult = $items;
24 93
        $unaryChain = new \ArrayIterator();
25
26 93
        foreach ($operations as $operation) {
27
28
            // collect all unary operators
29 93
            if ($operation instanceof IntermediateOperation) {
30 75
                $unaryChain->append($operation);
31
            } else {
32
                // execute all the collected unary operations
33
34 22
                if ($unaryChain->count() > 0) {
35 2
                    $tempResult = $this->solveIntermediateOperationChain($unaryChain, $tempResult);
36 2
                    $unaryChain = new \ArrayIterator();
37
                }
38
39
                // execute full set operations (like sort)
40 22
                if ($operation instanceof FullSetOperation) {
41 93
                    $tempResult = $operation->apply($tempResult);
42
                }
43
            }
44
        }
45
46
        // resolve the rest of the unary operation
47 93
        if ($unaryChain->count() > 0) {
48 73
            $tempResult = $this->solveIntermediateOperationChain($unaryChain, $tempResult);
49
        }
50
51 93
        return $tempResult;
52
    }
53
54
    /**
55
     * @param \Iterator $operatorChain
56
     * @param \Iterator $input
57
     *
58
     * @return \ArrayIterator
59
     */
60 75
    private function solveIntermediateOperationChain(\Iterator $operatorChain, \Iterator $input)
61
    {
62 75
        $results = new \ArrayIterator();
63
64 75
        $input->rewind();
65
66 75
        $continueWithNextItem = true;
67
68 75
        while ($continueWithNextItem && $input->valid()) {
69
70 63
            $result    = $input->current();
71 63
            $useResult = true;
72
73
            // do the whole intermediate operation chain for the current input
74 63
            $operatorChain->rewind();
75
76 63
            while ($useResult && $operatorChain->valid()) {
77
78
                /** @var IntermediateOperation $current */
79 63
                $current = $operatorChain->current();
80
                // apply intermediate operations
81 63
                $result = $current->apply($result, $input->key(), $useResult, $returnedCanContinue);
82
                // track the continuation flags
83 63
                $continueWithNextItem = $continueWithNextItem && $returnedCanContinue;
84
85
                // iterate
86 63
                $operatorChain->next();
87
            }
88
89 63
            if ($useResult) {
90 63
                $results->offsetSet($input->key(), $result);
91
            }
92
93
            // goto next item
94 63
            $input->next();
95
        }
96
97 75
        return $results;
98
    }
99
}
100