Issues (18)

src/Tree.php (1 issue)

Labels
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
    /**
18
     * undocumented function.
19
     *
20
     * @param $intervals array of Interval
21
     *
22
     * @return void
23
     */
24
    public function __construct(array $intervals = [], bool $preSorted = false)
25
    {
26
        !$preSorted && usort($intervals, function (IntervalInterface $i0, IntervalInterface $i) {
27
            return $i0->getStart() <=> $i->getStart();
28
        });
29
        $this->root = $this->toTree($intervals);
30
    }
31
32
    /**
33
     * An augmented tree can be built from a simple ordered tree,
34
     * for example a binary search tree or self-balancing binary search tree,
35
     * ordered by the 'low' values of the intervals.
36
     */
37
    public function toTree(array $intervals)
38
    {
39
        $max = 0;
40
        $len = count($intervals);
41
        $mid = (int) floor($len / 2);
42
43
        if (!$len) {
44
            return;
45
        }
46
47
        array_walk($intervals, function (IntervalInterface $el) use (&$max) {
48
            if ($max < $el->getEnd()) {
49
                $max = $el->getEnd();
50
            }
51
        });
52
        $l_intervals = array_splice($intervals, 0, $mid);
53
        $r_intervals = array_splice($intervals, -$mid);
54
        $interval = $intervals ? reset($intervals) : array_pop($l_intervals);
55
        $interval = $interval ?? array_pop($r_intervals);
56
57
        $node = new Node(
58
            $interval,
59
            $this->toTree($l_intervals),
60
            $this->toTree($r_intervals),
61
            $max
62
        );
63
64
        $node->root = &$this;
65
66
        return $node;
67
    }
68
69
    /**
70
     * returns intervals that exclusively fall within range given
71
     * to retrieve eather bound inclusevely, just modify parameters.
72
     *
73
     * @return void
74
     */
75
    public function select(int $low, int $high): array
76
    {
77
        return $this->root ? $this->root->select($low, $high) : [];
78
    }
79
80
    public function selectNode(int $low, int $high): array
81
    {
82
        return $this->root ? $this->root->selectNode($low, $high) : [];
83
    }
84
85
    /**
86
     * rebalance messed up tree overall.
87
     */
88
    public function balance()
89
    {
90
        // todo
91
    }
92
93
    /**
94
     * understandable var dump.
95
     */
96
    public function __debugInfo()
97
    {
98
        $arr = $this->all();
99
100
        usort($arr, function (IntervalInterface $i0, IntervalInterface $i) {
101
            return $i0->getStart() <=> $i->getStart();
102
        });
103
104
        return $arr;
105
    }
106
107
    public function yieldInterSelect(int $low, int $high)
108
    {
109
        return $this->root ? $this->root->yieldInterSelect($low, $high) : [];
110
    }
111
112
    public function interSelectNode(int $low, int $high): array
113
    {
114
        return $this->root ? $this->root->interSelectNode($low, $high) : [];
115
    }
116
117
    public function interSelect(int $low, int $high): array
118
    {
119
        return $this->root ? $this->root->interSelect($low, $high) : [];
120
    }
121
122
    public function yieldSelect(int $low, int $high)
123
    {
124
        return $this->root ? $this->root->yieldSelect($low, $high) : [];
125
    }
126
127
    /**
128
     * @return void
129
     */
130
    public function all(): array
131
    {
132
        return $this->root ? $this->root->all() : [];
133
    }
134
135
    /**
136
     * undocumented function.
137
     *
138
     * @return void
139
     */
140
    public function yieldAll()
141
    {
142
        return $this->root ? $this->root->yieldAll() : [];
0 ignored issues
show
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...
143
    }
144
145
    public function removeRegion(int $low, int $high)
146
    {
147
        if (!$this->root) {
148
            return [];
149
        }
150
        foreach ($this->interSelectNode($low, $high) as $node) {
151
            $this->remove($node);
152
        }
153
    }
154
155
    public function remove(IntervalInterface $i)
156
    {
157
        if (!$i->left && !$i->right) {
158
            if ($i->root) {
159
                $i->root = null;
160
            }
161
162
            return;
163
        }
164
165
        if ($i->left && $i->right) {
166
            // todo
167
            return;
168
        }
169
        if ($i->left) {
170
            $i->interval = &$i->left->interval;
171
            $i->left = null;
172
        }
173
174
        if ($i->right) {
175
        }
176
177
        if ($this->max > $i->getEnd()) {
178
            if ($this->left) {
179
                $this->left->add($i);
180
            } else {
181
                $this->left = new Node($i);
182
            }
183
        } else {
184
            $this->max = $i->getEnd();
185
            if ($this->right) {
186
                $this->right->add($i);
187
            } else {
188
                $this->right = new Node($i);
189
            }
190
        }
191
192
        return;
193
        if (!$this->root) {
194
            return [];
195
        }
196
        $this->root->remove($i);
197
    }
198
199
    public function add(IntervalInterface $i)
200
    {
201
        if (!$this->root) {
202
            $this->root = new Node($i);
203
204
            return;
205
        }
206
        $this->root->add($i);
207
    }
208
}
209