Completed
Push — master ( f9fb84...12a14e )
by Basarab
05:55
created

FSNode::getRight()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 7
cts 7
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 7
nc 4
nop 0
crap 4
1
<?php
2
3
4
namespace Hexogen\KDTree;
5
6
class FSNode implements NodeInterface
7
{
8
    /**
9
     * @var ItemInterface item that belongs to the node
10
     */
11
    private $item;
12
13
    /**
14
     * @var NodeInterface|null link to the left node
15
     */
16
    private $left;
17
18
    /**
19
     * @var int left node offset in file
20
     */
21
    private $leftPosition;
22
23
    /**
24
     * @var NodeInterface|null right node link
25
     */
26
    private $right;
27
28
    /**
29
     * @var int right node offset in the file
30
     */
31
    private $rightPosition;
32
33
    /**
34
     * @var resource file handler
35
     */
36
    private $handler;
37
38
    /**
39
     * @var int node start position in the file
40
     */
41
    private $position;
42
43
    /**
44
     * @var ItemFactoryInterface item factory
45
     */
46
    private $factory;
47
48
    /**
49
     * @var int num of dimensions it item
50
     */
51
    private $dimensions;
52
53
    /**
54
     * FSNode constructor.
55
     * @param ItemFactoryInterface $factory
56
     * @param resource $handler file handler
57
     * @param int $position node start position in the file
58
     * @param int $dimensions number of dimensions in item
59
     */
60 48
    public function __construct(ItemFactoryInterface $factory, $handler, int $position, int $dimensions)
61
    {
62 48
        $this->item = null;
63 48
        $this->left = null;
64 48
        $this->right = null;
65 48
        $this->handler = $handler;
66 48
        $this->position = $position;
67 48
        $this->factory = $factory;
68 48
        $this->dimensions = $dimensions;
69 48
    }
70
71
    /**
72
     * @return ItemInterface get item from the node
73
     */
74 12
    public function getItem() : ItemInterface
75
    {
76 12
        if ($this->item == null) {
77 12
            $this->readNode();
78
        }
79 12
        return $this->item;
80
    }
81
82
    /**
83
     * @param NodeInterface $node set right node
84
     */
85 12
    public function setRight(NodeInterface $node)
86
    {
87 12
        $this->right = $node;
88 12
    }
89
90
    /**
91
     * @param NodeInterface $node set left node
92
     */
93 12
    public function setLeft(NodeInterface $node)
94
    {
95 12
        $this->left = $node;
96 12
    }
97
98
    /**
99
     * Returns right node if it exists, null otherwise
100
     * @return NodeInterface|null get right node
101
     */
102 12
    public function getRight()
103
    {
104 12
        if ($this->rightPosition === null) {
105 3
            $this->readNode();
106
        }
107 12
        if ($this->right === null && $this->rightPosition !== 0) {
108 12
            $rightNode = new FSNode($this->factory, $this->handler, $this->rightPosition, $this->dimensions);
109 12
            $this->setRight($rightNode);
110
        }
111 12
        return $this->right;
112
    }
113
114
    /**
115
     * Returns left node if it exists, null otherwise
116
     * @return NodeInterface|null left node
117
     */
118 12
    public function getLeft()
119
    {
120 12
        if ($this->leftPosition === null) {
121 3
            $this->readNode();
122
        }
123 12
        if ($this->left === null && $this->leftPosition !== 0) {
124 12
            $leftNode = new FSNode($this->factory, $this->handler, $this->leftPosition, $this->dimensions);
125 12
            $this->setLeft($leftNode);
126
        }
127 12
        return $this->left;
128
    }
129
130
    /**
131
     * Read node data from the file
132
     */
133 18
    private function readNode()
134
    {
135 18
        fseek($this->handler, $this->position);
136 18
        $dataLength = 8 * $this->dimensions;
137
138 18
        $binData = fread($this->handler, 4);
139 18
        $itemId = unpack('V', $binData)[1];
140
141 18
        $binData = fread($this->handler, 4);
142 18
        $this->leftPosition = unpack('V', $binData)[1];
143
144 18
        $binData = fread($this->handler, 4);
145 18
        $this->rightPosition = unpack('V', $binData)[1];
146
147 18
        $binData = fread($this->handler, $dataLength);
148 18
        $dValues = unpack('d'.$this->dimensions, $binData);
149 18
        $dValues = array_values($dValues);
150
151 18
        $this->item = $this->factory->make($itemId, $dValues);
152 18
    }
153
}
154