Passed
Push — master ( 9d6212...8601c7 )
by Martins
02:21
created

Node::yieldInterSelectNode()   C

Complexity

Conditions 13
Paths 512

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 5.5209
c 0
b 0
f 0
cc 13
eloc 11
nc 512
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace MartanLV\Koki;
6
7
/**
8
 * Class Node.
9
 *
10
 * @author yourname
11
 */
12
class Node
13
{
14
	public $root;
15
    /**
16
     * @var Interval
17
     */
18
    public $interval;
19
    /**
20
     * @var int
21
     */
22
    public $max;
23
    /**
24
     * @var Node
25
     */
26
    public $left;
27
    /**
28
     * @var Node
29
     */
30
    public $right;
31
32
    /**
33
     * undocumented function.
34
     *
35
     * @return void
36
     */
37
    public function __construct(IntervalInterface $interval, $left = null, $right = null, $max = 0)
38
    {
39
        $this->interval = $interval;
0 ignored issues
show
Documentation Bug introduced by
$interval is of type MartanLV\Koki\IntervalInterface, but the property $interval was declared to be of type MartanLV\Koki\Interval. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
40
        $this->left = $left;
41
        $this->right = $right;
42
        $this->max = $max ? $max : $interval->getEnd();
43
    }
44
45
    /**
46
     * returns intervals that fall within interval range.
47
     *
48
     * @return void
49
     */
50
    public function all(): array
51
    {
52
        return iterator_to_array($this->yieldAll(), false);
0 ignored issues
show
Bug introduced by
$this->yieldAll() of type void is incompatible with the type Traversable expected by parameter $iterator of iterator_to_array(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

52
        return iterator_to_array(/** @scrutinizer ignore-type */ $this->yieldAll(), false);
Loading history...
Bug Best Practice introduced by
The expression return iterator_to_array...his->yieldAll(), false) returns the type array which is incompatible with the documented return type void.
Loading history...
Bug introduced by
Are you sure the usage of $this->yieldAll() targeting MartanLV\Koki\Node::yieldAll() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
53
    }
54
55
    /**
56
     * undocumented function.
57
     *
58
     * @return void
59
     */
60
    public function yieldAll()
61
    {
62
        return $this->yieldSelect(-1, $this->max + 1);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->yieldSelect(-1, $this->max + 1) returns the type Generator which is incompatible with the documented return type void.
Loading history...
63
    }
64
65
    /**
66
     * returns intervals that touches a given range.
67
     *
68
     * @return void
69
     */
70
    public function interSelectNode(int $low, int $high): array
71
    {
72
        return iterator_to_array($this->yieldInterSelectNode($low, $high), false);
0 ignored issues
show
Bug Best Practice introduced by
The expression return iterator_to_array...de($low, $high), false) returns the type array which is incompatible with the documented return type void.
Loading history...
73
    }
74
    /**
75
     * returns intervals that touches a given range.
76
     *
77
     * @return void
78
     */
79
    public function interSelect(int $low, int $high): array
80
    {
81
        return iterator_to_array($this->yieldInterSelect($low, $high), false);
0 ignored issues
show
Bug Best Practice introduced by
The expression return iterator_to_array...ct($low, $high), false) returns the type array which is incompatible with the documented return type void.
Loading history...
82
    }
83
84
    /**
85
     * returns intervals that fall within interval range.
86
     *
87
     * @return void
88
     */
89
    public function select(int $low, int $high): array
90
    {
91
        return iterator_to_array($this->yieldSelect($low, $high), false);
0 ignored issues
show
Bug Best Practice introduced by
The expression return iterator_to_array...ct($low, $high), false) returns the type array which is incompatible with the documented return type void.
Loading history...
92
    }
93
94
    public function selectNode(int $low, int $high): array
95
    {
96
        return iterator_to_array($this->yieldSelectNode($low, $high), false);
97
    }
98
    /**
99
     * returns intervals that touches a given range.
100
     *
101
     * @return generator
0 ignored issues
show
Bug introduced by
The type MartanLV\Koki\generator was not found. Did you mean generator? If so, make sure to prefix the type with \.
Loading history...
102
     */
103
    public function yieldInterSelectNode(int $low, int $high)
104
    {
105
        $edgeR = $high >= $this->interval->getStart() && $high <= $this->interval->getEnd();
106
        $edgeL = $low >= $this->interval->getStart() && $low <= $this->interval->getEnd();
107
        $part = $this->interval->getStart() >= $low && $this->interval->getEnd() <= $high;
108
        $whole = $this->interval->getStart() <= $low && $this->interval->getEnd() >= $high;
109
110
        $currentNodeMatches = $edgeR || $edgeL || $part || $whole;
111
        if ($currentNodeMatches) {
112
            yield $this;
113
        }
114
115
        if ($this->right && $this->interval->getStart() <= $high) {
116
            yield from $this->right->yieldInterSelectNode($low, $high);
117
        }
118
119
        if ($this->left && $this->left->max >= $low) {
120
            yield from $this->left->yieldInterSelectNode($low, $high);
121
        }
122
    }
123
    /**
124
     * returns intervals that touches a given range.
125
     *
126
     * @return generator
127
     */
128
    public function yieldInterSelect(int $low, int $high)
129
    {
130
        $edgeR = $high >= $this->interval->getStart() && $high <= $this->interval->getEnd();
131
        $edgeL = $low >= $this->interval->getStart() && $low <= $this->interval->getEnd();
132
        $part = $this->interval->getStart() >= $low && $this->interval->getEnd() <= $high;
133
        $whole = $this->interval->getStart() <= $low && $this->interval->getEnd() >= $high;
134
135
        $currentNodeMatches = $edgeR || $edgeL || $part || $whole;
136
        if ($currentNodeMatches) {
137
            yield $this->interval;
138
        }
139
140
        if ($this->right && $this->interval->getStart() <= $high) {
141
            yield from $this->right->yieldInterSelect($low, $high);
142
        }
143
144
        if ($this->left && $this->left->max >= $low) {
145
            yield from $this->left->yieldInterSelect($low, $high);
146
        }
147
    }
148
149
    /**
150
     * returns intervals that fall within interval range.
151
     *
152
     * @return generator
153
     */
154
    public function yieldSelectNode(int $low, int $high)
155
    {
156
        /*
157
         * does current node matches?
158
         */
159
        if ($this->interval->getEnd() < $high && $this->interval->getStart() > $low) {
160
            yield $this;
161
        }
162
163
        /*
164
         * since the node's low value is less than the "select end" value,
165
         * we must search in the right subtree. If it exists.
166
         */
167
        if ($this->right && $this->interval->getStart() < $high) {
168
            yield from $this->right->yieldSelectNode($low, $high);
169
        }
170
        /*
171
         * If the left subtree's max exceeds the quiery's low value,
172
         * so we must search the left subtree as well.
173
         */
174
        if ($this->left && $this->left->max > $low) {
175
            yield from $this->left->yieldSelectNode($low, $high);
176
        }
177
    }
178
179
    /**
180
     * returns intervals that fall within interval range.
181
     *
182
     * @return generator
183
     */
184
    public function yieldSelect(int $low, int $high)
185
    {
186
        /*
187
         * does current node matches?
188
         */
189
        if ($this->interval->getEnd() < $high && $this->interval->getStart() > $low) {
190
            yield $this->interval;
191
        }
192
193
        /*
194
         * since the node's low value is less than the "select end" value,
195
         * we must search in the right subtree. If it exists.
196
         */
197
        if ($this->right && $this->interval->getStart() < $high) {
198
            yield from $this->right->yieldSelect($low, $high);
199
        }
200
        /*
201
         * If the left subtree's max exceeds the quiery's low value,
202
         * so we must search the left subtree as well.
203
         */
204
        if ($this->left && $this->left->max > $low) {
205
            yield from $this->left->yieldSelect($low, $high);
206
        }
207
    }
208
209
    public function remove()
210
    {
211
	if ($this->max > $i->getEnd()) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $i seems to be never defined.
Loading history...
212
		if ($this->left) {
213
			$this->left->add($i);
214
		} else {
215
			$this->left = new Node($i);
216
		}
217
	} else {
218
		$this->max = $i->getEnd();
219
		if ($this->right) {
220
			$this->right->add($i);
221
		} else {
222
			$this->right = new Node($i);
223
		}
224
	}
225
    }
226
   
227
    public function add(IntervalInterface $i)
228
    {
229
	if ($this->max > $i->getEnd()) {
230
		if ($this->left) {
231
			$this->left->add($i);
232
		} else {
233
			$this->left = new Node($i);
234
			$this->left->root = &$this;
235
		}
236
	} else {
237
		$this->max = $i->getEnd();
238
		if ($this->right) {
239
			$this->right->add($i);
240
		} else {
241
			$this->right = new Node($i);
242
			$this->right->root = &$this;
243
		}
244
	}
245
    }
246
}
247