forked from facesea/banshee
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.go
124 lines (110 loc) · 2.47 KB
/
cache.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
// Copyright 2015 Eleme Inc. All rights reserved.
package admindb
import (
"github.com/eleme/banshee/models"
"github.com/eleme/banshee/util/log"
"github.com/eleme/banshee/util/safemap"
"github.com/jinzhu/gorm"
)
type rulesCache struct {
// Cache
rules *safemap.SafeMap
// Listeners
lnsAdd []chan *models.Rule
lnsDel []chan *models.Rule
}
// newRulesCache creates a rulesCache.
func newRulesCache() *rulesCache {
c := new(rulesCache)
c.rules = safemap.New()
c.lnsAdd = make([]chan *models.Rule, 0)
c.lnsDel = make([]chan *models.Rule, 0)
return c
}
// Init cache from db.
func (c *rulesCache) Init(db *gorm.DB) error {
log.Debugf("init rules from admindb..")
// Query
var rules []models.Rule
err := db.Find(&rules).Error
if err != nil {
return err
}
// Load
for i := 0; i < len(rules); i++ {
rule := &rules[i]
rule.Share()
c.rules.Set(rule.ID, rule)
}
return nil
}
// Len returns the number of rules in cache.
func (c *rulesCache) Len() int {
return c.rules.Len()
}
// Get returns rule.
func (c *rulesCache) Get(id int) (*models.Rule, bool) {
r, ok := c.rules.Get(id)
if !ok {
return nil, false
}
rule := r.(*models.Rule)
return rule.Copy(), true
}
// Put a rule into cache.
func (c *rulesCache) Put(rule *models.Rule) bool {
if c.rules.Has(rule.ID) {
return false
}
r := rule.Copy()
r.Share()
c.rules.Set(rule.ID, r)
c.pushAdded(rule)
return true
}
// All returns all rules.
func (c *rulesCache) All() (rules []*models.Rule) {
for _, v := range c.rules.Items() {
rule := v.(*models.Rule)
rules = append(rules, rule.Copy())
}
return rules
}
// Delete a rule from cache.
func (c *rulesCache) Delete(id int) bool {
r, ok := c.rules.Pop(id)
if ok {
rule := r.(*models.Rule)
c.pushDeled(rule.Copy())
return true
}
return false
}
// OnAdd listens rules changes.
func (c *rulesCache) OnAdd(ch chan *models.Rule) {
c.lnsAdd = append(c.lnsAdd, ch)
}
// OnDel listens rules changes.
func (c *rulesCache) OnDel(ch chan *models.Rule) {
c.lnsDel = append(c.lnsDel, ch)
}
// pushAdded pushes changed rule to listeners.
func (c *rulesCache) pushAdded(rule *models.Rule) {
for _, ch := range c.lnsAdd {
select {
case ch <- rule:
default:
log.Errorf("buffered added rules chan is full, skipping..")
}
}
}
// pushDeled pushes changed rule to listeners.
func (c *rulesCache) pushDeled(rule *models.Rule) {
for _, ch := range c.lnsDel {
select {
case ch <- rule:
default:
log.Errorf("buffered deleted rules chan is full, skipping..")
}
}
}