-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.go
77 lines (64 loc) · 1.19 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
package main
import (
"sync"
"time"
)
type cachedRR struct {
rr resourceRecord
createdAt time.Time
}
type cache struct {
cache map[string][]cachedRR
mutex *sync.Mutex
}
func (c *cache) Get(domain string) (*message, bool) {
c.mutex.Lock()
crrs, exists := c.cache[domain]
c.mutex.Unlock()
if !exists {
return nil, false
}
minTtlCrr := crrs[0]
for _, crr := range crrs {
if crr.rr.Ttl < minTtlCrr.rr.Ttl {
minTtlCrr = crr
}
}
t := time.Since(minTtlCrr.createdAt).Seconds()
if t > float64(minTtlCrr.rr.Ttl) {
c.remove(domain)
return nil, false
}
m := &message{
Answer: make([]resourceRecord, 0, len(crrs)),
}
for _, crr := range crrs {
rr := crr.rr
rr.Ttl -= int32(t)
switch crr.rr.Type {
case 1, 28:
m.Answer = append(m.Answer, rr)
}
}
return m, true
}
func (c *cache) Add(domain string, rrs []resourceRecord) {
crr := make([]cachedRR, 0, len(rrs))
for _, rr := range rrs {
if rr.Ttl <= 0 {
continue
}
crr = append(crr, cachedRR{
rr: rr,
createdAt: time.Now(),
})
}
c.mutex.Lock()
c.cache[domain] = crr
c.mutex.Unlock()
}
func (c *cache) remove(domain string) {
c.mutex.Lock()
delete(c.cache, domain)
c.mutex.Unlock()
}