-
Notifications
You must be signed in to change notification settings - Fork 1
/
node48.go
145 lines (123 loc) · 2.94 KB
/
node48.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
package art
// key value for keys that have no child node.
const n48NoChildForKey byte = 255
// index into the children arrays for the node value leaf.
const n48ValueIdx = 47
type node48[V any] struct {
nodeHeader
key [256]byte // index into children, 255 for no child
children [48]node[V]
}
func newNode48[V any](src node[V]) *node48[V] {
n := &node48[V]{nodeHeader: src.header()}
for i := range n.key {
n.key[i] = n48NoChildForKey
}
if n.hasValue {
n.children[n48ValueIdx] = src.valueNode()
}
slot := byte(0)
src.iterateChildren(func(k byte, cn node[V]) WalkState {
n.key[k] = slot
n.children[slot] = cn
slot++
return Continue
})
return n
}
func (n *node48[V]) header() nodeHeader {
return n.nodeHeader
}
func (n *node48[V]) keyPath() *keyPath {
return &n.path
}
func (n *node48[V]) grow() node[V] {
return newNode256(n)
}
func (n *node48[V]) canAddChild() bool {
max := int16(len(n.children))
if n.hasValue {
max--
}
return n.childCount < max
}
func (n *node48[V]) addChildNode(key byte, child node[V]) {
n.key[key] = byte(n.childCount)
n.children[n.childCount] = child
n.childCount++
}
func (n *node48[V]) canSetNodeValue() bool {
return n.childCount < int16(len(n.children))
}
func (n *node48[V]) setNodeValue(v *leaf[V]) {
n.children[n48ValueIdx] = v
n.hasValue = true
}
func (n *node48[V]) valueNode() *leaf[V] {
if n.hasValue {
return n.children[n48ValueIdx].(*leaf[V])
}
return nil
}
func (n *node48[V]) iterateChildren(cb func(k byte, n node[V]) WalkState) WalkState {
return n.iterateChildrenRange(0, 256, cb)
}
func (n *node48[V]) iterateChildrenRange(start, end int, cb func(k byte, n node[V]) WalkState) WalkState {
for k := start; k < end; k++ {
slot := n.key[k]
if slot != n48NoChildForKey {
if cb(byte(k), n.children[slot]) == Stop {
return Stop
}
}
}
return Continue
}
func (n *node48[V]) removeValue() node[V] {
n.children[n48ValueIdx] = nil
n.hasValue = false
return n
}
// keyForSlot returns the key value for the supplied child slot number.
func (n *node48[V]) keyForSlot(slot byte) int {
for k, s := range n.key {
if s == slot {
return k
}
}
panic("n48.keyForSlot called with unused slot number")
}
func (n *node48[V]) removeChild(key byte) {
lastSlot := byte(n.childCount - 1)
keyOfLastSlot := n.keyForSlot(lastSlot)
slot := n.key[key]
n.children[slot] = n.children[lastSlot]
n.key[keyOfLastSlot] = slot
n.key[key] = n48NoChildForKey
n.childCount--
}
func (n *node48[V]) shrink() node[V] {
if n.childCount < 16*3/4 {
return newNode16[V](n)
}
return n
}
func (n *node48[V]) getChildNode(key []byte) *node[V] {
idx := n.key[key[0]]
if idx == n48NoChildForKey {
return nil
}
return &n.children[idx]
}
func (n *node48[V]) pretty(indent int, w writer) {
writeNode[V](n, "n48", indent, w)
}
func (n *node48[V]) stats(s *Stats) {
s.Node48s++
if n.hasValue {
n.children[n48ValueIdx].stats(s)
}
for i := int16(0); i < n.childCount; i++ {
n.children[i].stats(s)
}
}