-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathnode.go
169 lines (156 loc) · 3.09 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package radix
import (
"bytes"
"sort"
)
// Node is a node of a radix tree.
type Node struct {
Value interface{}
edges []*edge
priority int
depth int
}
// Depth returns the node's depth.
func (n *Node) Depth() int {
return n.depth
}
// IsLeaf returns whether the node is a leaf.
func (n *Node) IsLeaf() bool {
length := len(n.edges)
if length == 2 { // check for binary tree
return n.edges[0] == nil && n.edges[1] == nil
}
return length == 0
}
// Priority returns the node's priority.
func (n *Node) Priority() int {
return n.priority
}
func (n *Node) addBinary(label string, v interface{}) (nn int) {
for i := range label {
for j := uint8(8); j > 0; j-- {
bbit := bit(j, label[i])
done := i == len(label)-1 && j == 1
if e := n.edges[bbit]; e != nil {
if done {
e.n.Value = v
return
}
goto next
}
n.edges[bbit] = &edge{
n: &Node{
depth: n.depth + 1,
edges: make([]*edge, 2),
},
}
if done {
n.edges[bbit].n.Value = v
}
nn++
next:
n = n.edges[bbit].n
}
}
return nn
}
func (n *Node) clone() *Node {
c := *n
c.incrDepth()
return &c
}
func (n *Node) delBinary(label string) int {
var (
ref *edge
del int
)
for i := range label {
for j := uint8(8); j > 0; j-- {
bbit := bit(j, label[i])
done := i == len(label)-1 && j == 1
if e := n.edges[bbit]; e != nil {
del++
if done && e.n.IsLeaf() { // only delete if node is leaf, otherwise it would break the tree
ref.n.edges = make([]*edge, 2) // reset edges from the last node that has value
return del
}
ref = e
n = e.n
continue
}
return 0
}
}
return 0
}
func (n *Node) getBinary(label string) *Node {
for i := range label {
for j := uint8(8); j > 0; j-- {
bbit := bit(j, label[i])
done := i == len(label)-1 && j == 1
if e := n.edges[bbit]; e != nil {
if done {
return e.n
}
n = e.n
continue
}
return nil
}
}
return nil
}
func (n *Node) incrDepth() {
n.depth++
for _, e := range n.edges {
e.n.incrDepth()
}
}
// sort sorts the node and its children recursively.
func (n *Node) sort(st SortingTechnique) {
s := &sorter{
n: n,
st: st,
}
sort.Sort(s)
for _, e := range n.edges {
e.n.sort(st)
}
}
func (n *Node) writeTo(bd *builder) {
for i, e := range n.edges {
e.writeTo(bd, []bool{i == len(n.edges)-1})
}
}
func (n *Node) writeToBinary(bd *builder, buf, aux *bytes.Buffer) {
prefix := aux.Bytes()
length := len(prefix)
aux1, aux2 := make([]byte, length), make([]byte, length)
copy(aux1, prefix)
copy(aux2, prefix)
auxs := []*bytes.Buffer{
bytes.NewBuffer(aux1),
bytes.NewBuffer(aux2),
}
for i, e := range n.edges {
if e != nil {
bit := byte('0')
if i == 1 {
bit = '1'
}
auxs[i].WriteByte(bit)
if e.n != nil {
if e.n.Value != nil {
bd.Write(prefix)
bd.WriteByte(bit) // holds only one value
isLeaf := e.n.IsLeaf()
if isLeaf {
bd.WriteString(bd.colors[colorGreen].Wrap(" 🍂"))
}
bd.WriteString(bd.colors[colorMagenta].Wrapf(" → %#v\n", e.n.Value))
}
e.n.writeToBinary(bd, buf, auxs[i])
}
}
}
}