-
Notifications
You must be signed in to change notification settings - Fork 8
/
node.go
120 lines (102 loc) · 1.97 KB
/
node.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package gannoy
type Nodes struct {
Storage
free Free
maps Maps
}
func newNodes(filename string, tree, dim, K int) Nodes {
// TODO Switch storage by parameter
nodes := Nodes{
Storage: newFile(filename, tree, dim, K),
}
// initialize free and maps
nodes.initialize()
return nodes
}
func (n *Nodes) initialize() {
n.free = newFree()
n.maps = newMaps()
iterator := make(chan Node)
go n.Iterate(iterator)
for node := range iterator {
if node.free {
n.free.push(node.id)
} else {
if node.isLeaf() {
n.maps.add(node.id, node.key)
}
}
}
}
func (ns *Nodes) newNode() Node {
node := Node{
storage: ns.Storage,
nDescendants: 1,
id: -1,
key: -1,
parents: []int{},
children: []int{0, 0},
v: []float64{},
free: false,
isNewRecord: true,
}
if free, err := ns.free.pop(); err == nil {
node.id = free
node.isNewRecord = false
}
return node
}
func (ns Nodes) getNode(id int) (Node, error) {
return ns.Storage.Find(id)
}
func (ns *Nodes) getNodeByKey(key int) (Node, error) {
id, err := ns.maps.getId(key)
if err != nil {
return Node{}, err
}
return ns.getNode(id)
}
type Node struct {
storage Storage
nDescendants int
id int
key int
parents []int
children []int
v []float64
free bool
isNewRecord bool
}
func (n Node) isLeaf() bool {
return n.nDescendants == 1
}
func (n Node) isBucket() bool {
return len(n.v) == 0
}
func (n Node) isRoot(index int) bool {
return n.parents[index] == -1
}
func (n *Node) save() error {
if n.isNewRecord {
id, err := n.storage.Create(*n)
if err != nil {
return err
}
n.id = id
n.isNewRecord = false
return nil
} else {
return n.storage.Update(*n)
}
}
func (n *Node) updateParents(index, parent int) error {
return n.storage.UpdateParent(n.id, index, parent)
}
func (n *Node) destroy() error {
err := n.storage.Delete(*n)
if err != nil {
return err
}
n.free = true
return nil
}