package cache
import (
"fmt"
"sync"
"time"
)
type MemCache struct {
//最大内存
maxMemorySize int64
// 当前已使用的内存
currMemorySize int64
// 最大内存字符串表示
maxMemorySizeStr string
// 缓存键值对
values map[string]*memCacheValue
// 读写锁
lock sync.RWMutex
//设置清除过期缓存的时间间隔
clearExpireTime time.Duration
}
type memCacheValue struct {
//value 值
val interface{}
// 过期时间
expireTime time.Time
//有效时间
expire time.Duration
//value 大小
size int64
}
func NewMemCache() Cache {
mc := &MemCache{
clearExpireTime: time.Second * 10,
values: make(map[string]*memCacheValue),
}
go mc.clearExpireItm()
return mc
}
// SetMemory size 1KB 100KB 1M 2M 1GB
func (mc *MemCache) SetMemory(size string) bool {
mc.maxMemorySize, mc.maxMemorySizeStr = ParseSize(size)
return true
}
// Set 设置缓存
func (mc *MemCache) Set(key string, val interface{}, expire time.Duration) bool {
mc.lock.Lock()
defer mc.lock.Unlock()
v := &memCacheValue{val: val, expireTime: time.Now().Add(expire),
expire: expire,
size: GetValSize(val)}
//mc.values[key] = v
mc.del(key)
mc.add(key, v)
if mc.currMemorySize > mc.maxMemorySize {
mc.del(key)
panic(fmt.Sprintf("max memory size %d", mc.maxMemorySize))
}
return true
}
func (mc *MemCache) get(key string) (*memCacheValue, bool) {
val, ok := mc.values[key]
return val, ok
}
func (mc *MemCache) del(key string) {
tmp, ok := mc.get(key)
if ok && tmp != nil {
mc.currMemorySize -= tmp.size
delete(mc.values, key)
}
}
func (mc *MemCache) add(key string, val *memCacheValue) {
mc.values[key] = val
mc.currMemorySize += val.size
}
// Get 获取缓存值
func (mc *MemCache) Get(key string) (interface{}, bool) {
mc.lock.RLock()
defer mc.lock.RUnlock()
mcv, ok := mc.get(key)
if ok {
if mcv.expire != 0 && mcv.expireTime.Before(time.Now()) {
mc.del(key)
return nil, false
}
return mcv.val, ok
}
return nil, false
}
// Del 删除缓存值
func (mc *MemCache) Del(key string) bool {
mc.lock.Lock()
defer mc.lock.Unlock()
mc.del(key)
return true
}
func (mc *MemCache) Exists(key string) bool {
mc.lock.RLock()
defer mc.lock.RUnlock()
_, ok := mc.get(key)
return ok
}
func (mc *MemCache) Flush() bool {
mc.lock.Lock()
defer mc.lock.Unlock()
mc.values = make(map[string]*memCacheValue, 0)
mc.currMemorySize = 0
return true
}
func (mc *MemCache) Keys() int64 {
mc.lock.RLock()
defer mc.lock.RUnlock()
return int64(len(mc.values))
}
func (mc *MemCache) clearExpireItm() {
ticker := time.NewTicker(mc.clearExpireTime)
defer ticker.Stop()
for {
select {
case <-ticker.C:
for key, v := range mc.values {
if v.expire != 0 && time.Now().After(v.expireTime) {
mc.lock.Lock()
mc.del(key)
mc.lock.Unlock()
}
}
}
}
}
//
//var Cache = NewMemCache()
//
//func Set(key string, val interface{}) bool {
//
// return false
//}
|