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

DefaultOperationChainSolver   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 13
lcom 0
cbo 2
dl 0
loc 85
ccs 31
cts 31
cp 1
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B solve() 0 33 6
C solveIntermediateOperationChain() 0 39 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