-
Notifications
You must be signed in to change notification settings - Fork 0
/
tree.go
139 lines (128 loc) · 2.7 KB
/
tree.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
package art
import "sync/atomic"
type Tree[T any] struct {
lock olock
root node[T]
size int64
}
func (t *Tree[T]) Insert(key Key, value T) (updated bool) {
for {
version, restart := t.lock.RLock()
l := &leaf[T]{key: key, value: value}
root := t.root
if root == nil { // empty tree, then insert a leaf node
if t.lock.Upgrade(version, nil) {
continue // restart
}
t.root = l
t.lock.Unlock()
atomic.AddInt64(&t.size, 1)
return
}
if _, ok := root.(*leaf[T]); ok {
if t.lock.Upgrade(version, nil) {
continue // restart
}
t.root, _, updated = root.insert(l, 0, &t.lock, version)
t.lock.Unlock()
if !updated {
atomic.AddInt64(&t.size, 1)
}
return
}
_, restart, updated = root.insert(l, 0, &t.lock, version)
if restart {
continue
}
if !updated {
atomic.AddInt64(&t.size, 1)
}
return
}
}
func (t *Tree[T]) Search(key Key) (value T, found bool) {
restart := false
for {
version, _ := t.lock.RLock()
root := t.root
if root == nil {
if t.lock.RUnlock(version, nil) {
continue
}
return value, false
}
value, found, restart = root.get(key, 0, &t.lock, version)
if restart {
continue
}
return value, found
}
}
func (t *Tree[T]) Remove(key Key) (deleted bool, value T) {
restart := false
var deletedNode node[T]
for {
version, _ := t.lock.RLock()
root := t.root
if root == nil {
if t.lock.RUnlock(version, nil) {
continue
}
return false, value
}
l, isLeaf := root.(*leaf[T])
if isLeaf && l != nil && l.cmp(key) { // remove root leaf node
if t.lock.Upgrade(version, nil) {
continue
}
value = l.value
t.root = nil
t.lock.Unlock()
return true, value
} else if isLeaf { // mismatch
if t.lock.RUnlock(version, nil) {
continue
}
return false, value
}
if deleted, restart, deletedNode = root.del(key, 0, &t.lock, version, func(rn node[T]) {
t.root = rn
}); restart {
continue
}
if deleted {
value = deletedNode.(*leaf[T]).value
atomic.AddInt64(&t.size, -1)
}
return deleted, value
}
}
func (t *Tree[T]) Empty() (empty bool) {
for {
version, _ := t.lock.RLock()
empty = t.root == nil
if t.lock.RUnlock(version, nil) {
continue // restart
}
return
}
}
// Iterator in range (start, end].
// Iterator is concurrently safe, but doesn't guarantee to provide consistent
// snapshot of the tree state.
func (t *Tree[T]) Iterator(start, end []byte) *iterator[T] {
return &iterator[T]{
tree: t,
cursor: start,
terminate: end,
}
}
type Ordered interface {
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64
}
func min[T Ordered](a T, b T) T {
if a < b {
return a
}
return b
}