Skip to content

Commit 82bbe2e

Browse files
author
coder2z
committed
cache
1 parent 9407b7f commit 82bbe2e

File tree

3 files changed

+103
-22
lines changed

3 files changed

+103
-22
lines changed

xcache/basis.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ type (
1313
}
1414

1515
node struct {
16-
data []byte
17-
expire time.Duration
16+
data []byte
17+
expire time.Duration
18+
creatTime time.Time
1819
}
1920
)
2021

@@ -37,7 +38,7 @@ func (b basis) GetE(key string) ([]byte, error) {
3738
if !ok {
3839
return nil, nilError
3940
}
40-
if b.checkExpire(node.expire) {
41+
if b.checkExpire(node) {
4142
b.doDel(key)
4243
return nil, nilError
4344
}
@@ -75,8 +76,9 @@ func (b basis) GetWithCreate(key string, h Handle) []byte {
7576

7677
func (b basis) doSetWithData(key string, data []byte, expire time.Duration) {
7778
b.data[key] = node{
78-
data: data,
79-
expire: expire,
79+
creatTime: time.Now(),
80+
data: data,
81+
expire: expire,
8082
}
8183
}
8284

@@ -100,11 +102,11 @@ func (b basis) IsExist(key string) bool {
100102
return b.doIsExist(key) == nilError
101103
}
102104

103-
func (b basis) checkExpire(ts time.Duration) bool {
104-
if ts.Nanoseconds() == 0 {
105+
func (b basis) checkExpire(n node) bool {
106+
if n.expire == 0 {
105107
return false
106108
}
107-
return time.Now().UnixNano() > ts.Nanoseconds()
109+
return time.Now().After(n.creatTime.Add(n.expire))
108110
}
109111

110112
func (b basis) doIsExist(key string) error {

xcache/basis_test.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
package xcache
22

33
import (
4+
"fmt"
45
"testing"
56
"time"
67
)
78

8-
type testdata struct {
9-
}
9+
type testdata struct{}
1010

1111
func (t testdata) Create() ([]byte, error) {
12-
return []byte("静安里看风景阿卡丽大家啊就完蛋了卡"), nil
12+
return []byte("test"), nil
1313
}
1414

1515
func (t testdata) Expire() time.Duration {
16-
return 0
16+
return time.Second * 3
1717
}
1818

19-
func TestName(t *testing.T) {
20-
b := NewBasis()
19+
func BenchmarkBasis(b *testing.B) {
20+
b.ReportAllocs()
21+
b.StopTimer()
22+
c := NewBasis()
23+
b.StartTimer()
2124

22-
err := b.Set("key", new(testdata))
23-
if err != nil {
24-
return
25-
}
26-
data, err := b.Get("key")
27-
if err != nil {
28-
return
25+
for i := 0; i < b.N; i++ {
26+
_ = c.Set(fmt.Sprintf("key_%d", i), new(testdata))
27+
if string(c.Get(fmt.Sprintf("key_%d", i))) != "test" {
28+
b.Error("data error ")
29+
}
2930
}
30-
t.Log(string(data))
3131
}

xcache/lru/lru.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package lru
2+
3+
import "container/list"
4+
5+
// Cache is a LRU cache. It is not safe for concurrent access.
6+
type Cache struct {
7+
maxBytes int64
8+
nbytes int64
9+
ll *list.List
10+
cache map[string]*list.Element
11+
// optional and executed when an entry is purged.
12+
OnEvicted func(key string, value Value)
13+
}
14+
15+
type entry struct {
16+
key string
17+
value Value
18+
}
19+
20+
// Value use Len to count how many bytes it takes
21+
type Value interface {
22+
Len() int
23+
}
24+
25+
// New is the Constructor of Cache
26+
func New(maxBytes int64, onEvicted func(string, Value)) *Cache {
27+
return &Cache{
28+
maxBytes: maxBytes,
29+
ll: list.New(),
30+
cache: make(map[string]*list.Element),
31+
OnEvicted: onEvicted,
32+
}
33+
}
34+
35+
// Add adds a value to the cache.
36+
func (c *Cache) Add(key string, value Value) {
37+
if ele, ok := c.cache[key]; ok {
38+
c.ll.MoveToFront(ele)
39+
kv := ele.Value.(*entry)
40+
c.nbytes += int64(value.Len()) - int64(kv.value.Len())
41+
kv.value = value
42+
} else {
43+
ele := c.ll.PushFront(&entry{key, value})
44+
c.cache[key] = ele
45+
c.nbytes += int64(len(key)) + int64(value.Len())
46+
}
47+
for c.maxBytes != 0 && c.maxBytes < c.nbytes {
48+
c.RemoveOldest()
49+
}
50+
}
51+
52+
// Get look ups a key's value
53+
func (c *Cache) Get(key string) (value Value, ok bool) {
54+
if ele, ok := c.cache[key]; ok {
55+
c.ll.MoveToFront(ele)
56+
kv := ele.Value.(*entry)
57+
return kv.value, true
58+
}
59+
return
60+
}
61+
62+
// RemoveOldest removes the oldest item
63+
func (c *Cache) RemoveOldest() {
64+
ele := c.ll.Back()
65+
if ele != nil {
66+
c.ll.Remove(ele)
67+
kv := ele.Value.(*entry)
68+
delete(c.cache, kv.key)
69+
c.nbytes -= int64(len(kv.key)) + int64(kv.value.Len())
70+
if c.OnEvicted != nil {
71+
c.OnEvicted(kv.key, kv.value)
72+
}
73+
}
74+
}
75+
76+
// Len the number of cache entries
77+
func (c *Cache) Len() int {
78+
return c.ll.Len()
79+
}

0 commit comments

Comments
 (0)