-
Notifications
You must be signed in to change notification settings - Fork 79
/
cache.go
73 lines (58 loc) · 1.33 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
package consensus
import (
"container/list"
"sync"
"github.com/nspcc-dev/neo-go/pkg/util"
)
// relayCache is payload cache which is used to store
// last consensus payloads.
type relayCache struct {
*sync.RWMutex
maxCap int
elems map[util.Uint256]*list.Element
queue *list.List
}
// hashable is the type of items which can be stored in the relayCache.
type hashable interface {
Hash() util.Uint256
}
func newFIFOCache(capacity int) *relayCache {
return &relayCache{
RWMutex: new(sync.RWMutex),
maxCap: capacity,
elems: make(map[util.Uint256]*list.Element),
queue: list.New(),
}
}
// Add adds payload into cache if it doesn't already exist there.
func (c *relayCache) Add(p hashable) {
c.Lock()
defer c.Unlock()
h := p.Hash()
if c.elems[h] != nil {
return
}
if c.queue.Len() >= c.maxCap {
first := c.queue.Front()
c.queue.Remove(first)
delete(c.elems, first.Value.(hashable).Hash())
}
e := c.queue.PushBack(p)
c.elems[h] = e
}
// Has checks if the item is already in cache.
func (c *relayCache) Has(h util.Uint256) bool {
c.RLock()
defer c.RUnlock()
return c.elems[h] != nil
}
// Get returns payload with the specified hash from cache.
func (c *relayCache) Get(h util.Uint256) hashable {
c.RLock()
defer c.RUnlock()
e, ok := c.elems[h]
if !ok {
return hashable(nil)
}
return e.Value.(hashable)
}