-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkeeper.go
99 lines (83 loc) · 1.87 KB
/
keeper.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
package bingodb
import (
"fmt"
"github.com/emirpasic/gods/utils"
"github.com/robfig/cron"
"github.com/zoyi/skiplist/lazy"
"time"
)
type Keeper struct {
bingo *Bingo
list *lazyskiplist.SkipList
cron *cron.Cron
}
type ExpireKey struct {
expiresAt int64
table *Table
*Document
}
func comparator(aRaw, bRaw interface{}) int {
a := aRaw.(*ExpireKey)
b := bRaw.(*ExpireKey)
var diff int
diff = NumberComparator(a.expiresAt, b.expiresAt)
if diff != 0 {
return diff
}
if a.table == nil || b.table == nil {
if a.table == b.table {
return 0
} else if a.table == nil {
return -1
} else {
return 1
}
}
diff = utils.StringComparator(a.table.name, b.table.name)
if diff != 0 {
return diff
}
if a.table != b.table {
panic(fmt.Sprintf("Two Tables are different: %v, %v", a.table, b.table))
}
return a.table.Compare(a.Document, b.Document)
}
func NewKeeper(bingo *Bingo) *Keeper {
keeper := &Keeper{bingo: bingo, list: lazyskiplist.NewLazySkipList(comparator)}
c := cron.New()
c.AddFunc("@every 1s", keeper.expire)
keeper.cron = c
return keeper
}
func (keeper *Keeper) put(table *Table, doc *Document) {
value, ok := doc.GetExpiresAt()
if ok {
key := &ExpireKey{expiresAt: value, table: table, Document: doc}
keeper.list.Put(key, nil, nil)
}
}
func (keeper *Keeper) remove(table *Table, doc *Document) {
value, ok := doc.GetExpiresAt()
if ok {
key := &ExpireKey{expiresAt: value, table: table, Document: doc}
keeper.list.Remove(key)
}
}
func (keeper *Keeper) expire() {
i := 0
for it := keeper.list.Begin(nil); it.Present(); it.Next() {
key := it.Key().(*ExpireKey)
if key.expiresAt > time.Now().Unix()*1000 { // For millis
break
}
key.table.RemoveByDocument(key.Document)
i++
}
keeper.bingo.AddExpire(int64(i))
}
func (keeper *Keeper) start() {
keeper.cron.Start()
}
func (keeper *Keeper) stop() {
keeper.cron.Stop()
}