1 2 3 4 5 6 7 |
SetMemory(size string) bool Set(key string, val interface{}, expire time.Duration) bool Get(key string) (interface{}, bool) Del(key string) bool Exists(key string) bool Flush() bool Keys() int64 |
下面为具体实现代码:
接口
1 2 3 4 5 6 7 8 9 10 11 |
package cache import "time" type Cache interface { SetMemory(size string) bool Set(key string, val interface{}, expire time.Duration) bool Get(key string) (interface{}, bool) Del(key string) bool Exists(key string) bool Flush() bool Keys() int64 } |
实现类
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 151 152 |
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 //} |
工具类
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 |
package cache
import ( "log" "regexp" "strconv" "strings" )
const ( B = 1 << (iota * 10) KB MB GB TB PB )
func ParseSize(size string) (int64, string) {
//默认大小为 100M re, _ := regexp.Compile("[0-9]+") unit := string(re.ReplaceAll([]byte(size), []byte(""))) num, _ := strconv.ParseInt(strings.Replace(size, unit, "", 1), 10, 64) unit = strings.ToUpper(unit) var byteNum int64 = 0 switch unit { case "B": byteNum = num break case "KB": byteNum = num * KB break case "MB": byteNum = num * MB break case "GB": byteNum = num * GB break case "TB": byteNum = num * TB break case "PB": byteNum = num * PB break default: num = 0 byteNum = 0
} if num == 0 { log.Println("ParseSize 仅支持B,KB,MB,GB,TB,PB") num = 100 * MB byteNum = num unit = "MB" } sizeStr := strconv.FormatInt(num, 10) + unit return byteNum, sizeStr
}
func GetValSize(val interface{}) int64 { return 0 } |
代理类
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 |
package server
import ( "go_lang_pro/cache" "time" )
type cacheServer struct { memCache cache.Cache }
func NewMemoryCache() *cacheServer { return &cacheServer{ memCache: cache.NewMemCache(), } }
func (cs *cacheServer) SetMemory(size string) bool { return cs.memCache.SetMemory(size) }
func (cs *cacheServer) Set(key string, val interface{}, expire ...time.Duration) bool { expirets := time.Second * 0 if len(expire) > 0 { expirets = expire[0] } return cs.memCache.Set(key, val, expirets) }
func (cs *cacheServer) Get(key string) (interface{}, bool) { return cs.memCache.Get(key) } func (cs *cacheServer) Del(key string) bool { return cs.memCache.Del(key) }
func (cs *cacheServer) Exists(key string) bool { return cs.memCache.Exists(key) }
func (cs *cacheServer) Flush() bool { return cs.memCache.Flush() }
func (cs *cacheServer) Keys() int64 { return cs.memCache.Keys() } |
main 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package main
import ( "go_lang_pro/cache" "time" )
func main() {
cache := cache.NewMemCache() cache.SetMemory("100MB") cache.Set("int", 1, time.Second) cache.Set("bool", false, time.Second) cache.Set("data", map[string]interface{}{"a": 1}, time.Second) cache.Get("int") cache.Del("int") cache.Flush() cache.Keys()
} |