-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecord.go
68 lines (60 loc) · 1.19 KB
/
record.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
package main
import (
"container/list"
"crypto/md5"
"time"
)
type Record struct {
Time time.Time
Content []byte
}
func (r Record) String() string {
return string(r.Content)
}
type Records struct {
capacity int
elements map[[16]byte]*list.Element
order *list.List
}
func NewRecords(capacity int) *Records {
return &Records{
capacity: capacity,
elements: make(map[[16]byte]*list.Element),
order: list.New(),
}
}
func (r *Records) Add(content []byte) bool {
md5Bytes := md5.Sum(content)
if e, ok := r.elements[md5Bytes]; ok {
if e == r.order.Front() {
return false
}
rd := e.Value.(Record)
rd.Time = time.Now()
e.Value = rd
r.order.MoveToFront(e)
} else {
if r.order.Len() < 5 {
r.capacity++
} else {
// evict last
last := r.order.Back()
rd := r.order.Remove(last).(Record)
delete(r.elements, md5.Sum(rd.Content))
}
r.elements[md5Bytes] = r.order.PushFront(Record{time.Now(), content})
}
return true
}
func (r *Records) Len() int {
return r.order.Len()
}
func (r *Records) Slice() [][]byte {
slice := make([][]byte, 0)
e := r.order.Front()
for e != nil {
slice = append(slice, e.Value.(Record).Content)
e = e.Next()
}
return slice
}