FSNode   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 14
eloc 46
c 1
b 0
f 1
dl 0
loc 146
ccs 46
cts 46
cp 1
rs 10

7 Methods

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