Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

本地缓存实现

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package main
import (
"fmt"
"strconv"
"sync"
"time"
)
type Cache interface {
// 添加缓存项,并设置过期时间
Set(key string, val interface{}, expire time.Duration) // 获取缓存项
Get(key string) (interface{}, bool)
// 删除缓存项
Del(key string) bool
// 判断是否存在
Exists(key string) bool
// 刷新缓存
Flush() bool
// 获取键
Keys() int64
}
type CacheItem struct {
value interface{}
expAt time.Time
creAt time.Time
}
func (c CacheItem) Size() int64 { // 计算存储的数据所占用的内存大小 var dataSize int64
switch v := c.value.(type) { case string:
dataSize = int64(len(v))
case int:
dataSize = int64(8)
case bool:
dataSize = int64(1)
default:
dataSize = 1024
}
return dataSize + int64(2*24)
}
type MCache struct {
CItems map[string]CacheItem
MaxM int64
CurM int64
mutex sync.Mutex
}
func NewCache() *MCache {
return &MCache{
CItems: make(map[string]CacheItem),
}
}
func (m *MCache) Set(key string, value interface{}) {
m.SetDefault(key, value, 10*time.Minute)
}
func (m *MCache) SetDefault(key string, value interface{}, exp time.Duration) {
m.mutex.Lock()
defer m.mutex.Unlock()
if _, ok := m.CItems[key]; ok {
m.CurM -= int64(len(key)) + m.CItems[key].Size()
}
m.CItems[key] = CacheItem{
value: value,
expAt: time.Now().Add(exp),
creAt: time.Now(),
}
m.CurM += int64(len(key)) + m.CItems[key].Size()
m.overCache()
}
func (m *MCache) Get(key string) (interface{}, bool) {
m.mutex.Lock()
defer m.mutex.Unlock()
item, ok := m.CItems[key]
if !ok || time.Now().After(item.expAt) {
return nil, false
}
return item.value, true
}
func (m *MCache) Del(key string) bool {
m.mutex.Lock()
defer m.mutex.Unlock()
_, ok := m.CItems[key]
if !ok {
return false
}
m.CurM -= int64(len(key)) + m.CItems[key].Size()
delete(m.CItems, key)
return true
}
func (m *MCache) Exists(key string) bool {
m.mutex.Lock()
defer m.mutex.Unlock()

_, ok := m.CItems[key]
return ok }
func (m *MCache) Flush() bool {
m.mutex.Lock()
defer m.mutex.Unlock()
m.CItems = make(map[string]CacheItem)
m.CurM = 0
return true
}
func (m *MCache) Keys() int64 {
m.mutex.Lock()
defer m.mutex.Unlock()
return int64(len(m.CItems))
}
// 100KB 1MB 2MB 1GB
func (m *MCache) SetMaxMemory(size string) bool {
s1 := size[:2]
num, _ := strconv.Atoi(s1)
unit := size[len(size)-2:]
switch unit {
case "KB":
m.MaxM = 1024 * int64(num)
return true
case "MB":
m.MaxM = 1024 * 1024 * int64(num)
return true
case "GB":
m.MaxM = 1024 * 1024 * 1024 * int64(num)
return true
default:
return false
}
}
func (m *MCache) overCache() {
for m.CurM > m.MaxM {
oldKey := ""
oldTime := time.Time{}
for key, cacheItem := range m.CItems {
if cacheItem.creAt.Before(oldTime) {
oldKey = key
oldTime = cacheItem.creAt
} }
m.CurM -= int64(len(oldKey)) + m.CItems[oldKey].Size()
delete(m.CItems, oldKey)
}
}


func main() {
cache := NewCache()
cache.SetMaxMemory("100MB")
cache.Set("int", 1)
cache.Set("bool", false)
cache.Set("data", map[string]interface{}{"a": 1})
if val, ok := cache.Get("int"); ok {
fmt.Printf("key:%s, value:%d \n", "int", val)
}
cache.Del("int")
fmt.Print(cache.Keys())
//cache.Flush()
}

评论