-
Notifications
You must be signed in to change notification settings - Fork 40
/
nodeownercache.go
91 lines (79 loc) · 2.15 KB
/
nodeownercache.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
package icstate
import (
"github.com/icon-project/goloop/common/containerdb"
"github.com/icon-project/goloop/common/errors"
"github.com/icon-project/goloop/icon/iiss/icutils"
"github.com/icon-project/goloop/module"
"github.com/icon-project/goloop/service/scoredb"
)
var nodeOwnerDictPrefix = containerdb.ToKey(
containerdb.HashBuilder,
scoredb.DictDBPrefix,
"node_owner",
)
// TODO: Remove old nodes which is not used anymore
type NodeOwnerCache struct {
dict *containerdb.DictDB
nodeToOwner map[string]module.Address
}
// Add adds alias, node-to-owner.
// It doesn't record alias to self.
// If there is same alias, it ignores the request.
func (c *NodeOwnerCache) Add(node, owner module.Address) error {
if node == nil || owner == nil {
// No need to add
return nil
}
if cur := c.get(node, nil); cur == nil {
if node.Equal(owner) {
return nil
}
} else {
if cur.Equal(owner) {
return nil
} else {
return errors.Errorf("AlreadyExist(owner=%s,node=%s)", cur, node)
}
}
c.nodeToOwner[icutils.ToKey(node)] = owner
return nil
}
func (c *NodeOwnerCache) Get(node module.Address) module.Address {
return c.get(node, node)
}
func (c *NodeOwnerCache) get(node module.Address, fallback module.Address) module.Address {
key := icutils.ToKey(node)
owner := c.nodeToOwner[key]
if owner != nil {
return owner
}
o := c.dict.Get(node)
if o == nil {
// owner address is equal to node address
return fallback
}
return o.Address()
}
func (c *NodeOwnerCache) Contains(node module.Address) bool {
return c.get(node, nil) != nil
}
func (c *NodeOwnerCache) Clear() {
c.Flush()
}
func (c *NodeOwnerCache) Reset() {
c.nodeToOwner = make(map[string]module.Address)
}
func (c *NodeOwnerCache) Flush() {
for node, owner := range c.nodeToOwner {
if err := c.dict.Set(node, owner); err != nil {
panic(errors.Errorf("DictDB.Set(%s, %s) is failed", node, owner))
}
}
c.nodeToOwner = make(map[string]module.Address)
}
func newNodeOwnerCache(store containerdb.ObjectStoreState) *NodeOwnerCache {
return &NodeOwnerCache{
dict: containerdb.NewDictDB(store, 1, nodeOwnerDictPrefix),
nodeToOwner: make(map[string]module.Address),
}
}