-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathbtree.go
107 lines (95 loc) · 2.31 KB
/
btree.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
package tinybtree
import "github.com/tidwall/btree"
// BTree is an ordered set of key/value pairs where the key is a string
// and the value is an interface{}
type BTree struct {
base *btree.BTree
}
type item struct {
key string
value interface{}
}
func (tr *BTree) init() {
tr.base = btree.NewNonConcurrent(func(a, b interface{}) bool {
return a.(*item).key < b.(*item).key
})
}
// Set or replace a value for a key
func (tr *BTree) Set(key string, value interface{}) (prev interface{}, replaced bool) {
if tr.base == nil {
tr.init()
}
if v := tr.base.Set(&item{key, value}); v != nil {
return v.(*item).value, true
}
return nil, false
}
// Get a value for key
func (tr *BTree) Get(key string) (value interface{}, gotten bool) {
if tr.base == nil {
return nil, false
}
if v := tr.base.Get(&item{key, value}); v != nil {
return v.(*item).value, true
}
return nil, false
}
// Delete a value for a key
func (tr *BTree) Delete(key string) (prev interface{}, deleted bool) {
if tr.base == nil {
tr.init()
}
if v := tr.base.Delete(&item{key: key}); v != nil {
return v.(*item).value, true
}
return nil, false
}
// Len returns the number of items in the tree
func (tr *BTree) Len() int {
if tr.base == nil {
return 0
}
return tr.base.Len()
}
// Ascend the tree within the range [pivot, last]
func (tr *BTree) Ascend(
pivot string,
iter func(key string, value interface{}) bool,
) {
if tr.base == nil {
return
}
tr.base.Ascend(&item{key: pivot}, func(v interface{}) bool {
return iter(v.(*item).key, v.(*item).value)
})
}
// Scan all items in tree
func (tr *BTree) Scan(iter func(key string, value interface{}) bool) {
if tr.base == nil {
return
}
tr.base.Ascend(nil, func(v interface{}) bool {
return iter(v.(*item).key, v.(*item).value)
})
}
// Descend the tree within the range [pivot, first]
func (tr *BTree) Descend(
pivot string,
iter func(key string, value interface{}) bool,
) {
if tr.base == nil {
return
}
tr.base.Descend(&item{key: pivot}, func(v interface{}) bool {
return iter(v.(*item).key, v.(*item).value)
})
}
// Reverse interates over all items in tree, in reverse.
func (tr *BTree) Reverse(iter func(key string, value interface{}) bool) {
if tr.base == nil {
return
}
tr.base.Descend(nil, func(v interface{}) bool {
return iter(v.(*item).key, v.(*item).value)
})
}