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

Tree::selectNode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 2
eloc 1
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MartanLV\Koki;
6
7
/**
8
 * Augmented tree
9
 * Class StaticTree.
10
 *
11
 * @author yourname
12
 */
13
class Tree extends Node
14
{
15
	public $root;
16
    /**
17
     * undocumented function.
18
     *
19
     * @param $intervals array of Interval
20
     *
21
     * @return void
22
     */
23
    public function __construct(array $intervals = [], bool $preSorted = false)
24
    {
25
        !$preSorted && usort($intervals, function (IntervalInterface $i0, IntervalInterface $i) {
26
            return $i0->getStart() <=> $i->getStart();
27
        });
28
        $this->root = $this->toTree($intervals);
29
    }
30
31
    /**
32
     * An augmented tree can be built from a simple ordered tree,
33
     * for example a binary search tree or self-balancing binary search tree,
34
     * ordered by the 'low' values of the intervals.
35
     */
36
    public function toTree(array $intervals)
37
    {
38
        $max = 0;
39
        $len = count($intervals);
40
        $mid = (int) floor($len / 2);
41
42
        if (!$len) {
43
            return;
44
        }
45
46
        array_walk($intervals, function (IntervalInterface $el) use (&$max) {
47
            if ($max < $el->getEnd()) {
48
                $max = $el->getEnd();
49
            }
50
        });
51
        $l_intervals = array_splice($intervals, 0, $mid);
52
        $r_intervals = array_splice($intervals, -$mid);
53
        $interval = $intervals ? reset($intervals) : array_pop($l_intervals);
54
        $interval = $interval ?? array_pop($r_intervals);
55
56
        $node = new Node(
57
            $interval,
58
            $this->toTree($l_intervals),
59
            $this->toTree($r_intervals),
60
            $max
61
        );
62
63
	$node->root = &$this;
64
	return $node;
65
    }
66
67
    /**
68
     * returns intervals that exclusively fall within range given
69
     * to retrieve eather bound inclusevely, just modify parameters.
70
     *
71
     * @return void
72
     */
73
    public function select(int $low, int $high): array
74
    {
75
        return $this->root ? $this->root->select($low, $high) : [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->root ? $th...($low, $high) : array() returns the type array which is incompatible with the documented return type void.
Loading history...
76
    }
77
78
    public function selectNode(int $low, int $high): array
79
    {
80
        return $this->root ? $this->root->selectNode($low, $high) : [];
81
    }
82
83
    /**
84
     * rebalance messed up tree overall
85
     */
86
    public function balance()
87
    {
88
	    // todo
89
    }
90
91
    /**
92
     * understandable var dump.
93
     */
94
    public function __debugInfo()
95
    {
96
        $arr = $this->all();
97
98
        usort($arr, function (IntervalInterface $i0, IntervalInterface $i) {
99
            return $i0->getStart() <=> $i->getStart();
100
        });
101
102
        return $arr;
103
    }
104
105
    public function yieldInterSelect(int $low, int $high)
106
    {
107
        return $this->root ? $this->root->yieldInterSelect($low, $high) : [];
108
    }
109
110
    public function interSelectNode(int $low, int $high): array
111
    {
112
        return $this->root ? $this->root->interSelectNode($low, $high) : [];
113
    }
114
115
    public function interSelect(int $low, int $high): array
116
    {
117
        return $this->root ? $this->root->interSelect($low, $high) : [];
118
    }
119
120
    public function yieldSelect(int $low, int $high)
121
    {
122
        return $this->root ? $this->root->yieldSelect($low, $high) : [];
123
    }
124
125
    /**
126
     * @return void
127
     */
128
    public function all(): array
129
    {
130
        return $this->root ? $this->root->all() : [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->root ? $this->root->all() : array() returns the type array which is incompatible with the documented return type void.
Loading history...
131
    }
132
133
    /**
134
     * undocumented function.
135
     *
136
     * @return void
137
     */
138
    public function yieldAll()
139
    {
140
        return $this->root ? $this->root->yieldAll() : [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->root ? $th...t->yieldAll() : array() 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->root->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...
141
    }
142
143
    public function removeRegion(int $low, int $high)
144
    {
145
    	if (!$this->root) {
146
	    return [];
147
    	}
148
	foreach($this->interSelectNode($low, $high) as $node) {
149
		$this->remove($node);
150
	}
151
    }
152
153
    public function remove(IntervalInterface $i)
154
    {
155
	    if (!$i->left && !$i->right) {
0 ignored issues
show
Bug introduced by
Accessing right on the interface MartanLV\Koki\IntervalInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
Bug introduced by
Accessing left on the interface MartanLV\Koki\IntervalInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
156
		    if ($i->root) {
0 ignored issues
show
Bug introduced by
Accessing root on the interface MartanLV\Koki\IntervalInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
157
			    $i->root = null;
158
		    }
159
		    return;
160
	    }
161
162
	    if ($i->left && $i->right) {
163
	    		// todo
164
		    return;
165
	    }
166
	    if ($i->left) {
167
	    	$i->interval = &$i->left->interval;
0 ignored issues
show
Bug introduced by
Accessing interval on the interface MartanLV\Koki\IntervalInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
168
	    	$i->left = null;
169
	    }
170
171
	    if ($i->right) {
172
173
	    }
174
175
	if ($this->max > $i->getEnd()) {
176
		if ($this->left) {
177
			$this->left->add($i);
178
		} else {
179
			$this->left = new Node($i);
180
		}
181
	} else {
182
		$this->max = $i->getEnd();
183
		if ($this->right) {
184
			$this->right->add($i);
185
		} else {
186
			$this->right = new Node($i);
187
		}
188
	}
189
	return;
190
    	if (!$this->root) {
0 ignored issues
show
Unused Code introduced by
IfNode is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
191
	    return [];
192
    	}
193
	$this->root->remove($i);
194
    }
195
196
    public function add(IntervalInterface $i)
197
    {
198
    	if (!$this->root) {
199
	    $this->root = new Node($i);
200
	    return;
201
    	}
202
	$this->root->add($i);
203
    }
204
}
205