forked from scryner/bptree
-
Notifications
You must be signed in to change notification settings - Fork 2
/
recognizable_bptree.go
87 lines (65 loc) · 1.55 KB
/
recognizable_bptree.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
package bptree
import (
"github.com/scryner/lfreequeue"
"sync"
"time"
)
// Instantly recognizable when tree changed
type RecognizableBptree struct {
*Bptree
lastModified int64
lastModifiedLock *sync.RWMutex
notifyQueue *lfreequeue.Queue
}
func NewRecognizableBptree(maxDegree, maxDepth int, allowOverlap bool) (*RecognizableBptree, error) {
bptree, err := NewBptree(maxDegree, maxDepth, allowOverlap)
if err != nil {
return nil, err
}
return &RecognizableBptree{
Bptree: bptree,
lastModified: -1,
lastModifiedLock: new(sync.RWMutex),
notifyQueue: lfreequeue.NewQueue(),
}, nil
}
func (tree *RecognizableBptree) GetLastModified() int64 {
tree.lastModifiedLock.RLock()
defer tree.lastModifiedLock.RUnlock()
return tree.lastModified
}
func (tree *RecognizableBptree) AddWatch() <-chan int {
ch := make(chan int)
tree.notifyQueue.Enqueue(ch)
return ch
}
func (tree *RecognizableBptree) notify() {
for v := range tree.notifyQueue.Iter() {
ch := v.(chan int)
go func() {
ch <- 1
}()
}
}
func (tree *RecognizableBptree) Insert(elem Elem) error {
tree.lastModifiedLock.Lock()
defer tree.lastModifiedLock.Unlock()
tree.lastModified = time.Now().UnixNano()
err := tree.Bptree.Insert(elem)
if err != nil {
return err
}
tree.notify()
return nil
}
func (tree *RecognizableBptree) Remove(key Key) error {
tree.lastModifiedLock.Lock()
defer tree.lastModifiedLock.Unlock()
tree.lastModified = time.Now().UnixNano()
err := tree.Bptree.Remove(key)
if err != nil {
return err
}
tree.notify()
return nil
}