package main import ( "fmt" "log" "strconv" "strings" "time" "unsafe" ) type CacheInterface interface { // size: 1KB 100KB 1MB 2MB 1GB SetMaxMemory(size string) error // value写入缓存 Set(key string, val interface{}, expire time.Duration) error // 根据key获取value Get(key string) (interface{}, error) // 删除key值 Del(key string) error // 判断key是否存在 Exists(key string) (bool, error) // 清空所有key Flush() error // 获取缓存中所有key的数量 Keys() int64 } type Cache struct { ObjectCount int64 // 缓存中对象数量 CurrentMemory int64 // 当前缓存占用内存大小 MaxMemory *int64 // 最大缓存内存大小 Storage map[string]interface{} // 缓存存储 } /* * 设置最大内存 * size: 1KB 100KB 1MB 2MB 1GB */ func (C *Cache) SetMaxMemory(size string) (err error) { var ( gb bool = strings.Contains(size, "GB") || strings.Contains(size, "gb") mb bool = strings.Contains(size, "MB") || strings.Contains(size, "mb") kb bool = strings.Contains(size, "KB") || strings.Contains(size, "kb") kilobyte int64 = 1024 megabyte int64 = 1024 * kilobyte gigabyte int64 = 1024 * megabyte sizeCount int64 errorHandling = func() (err error) { return fmt.Errorf("set max memory error") } ) if len(size) <= 2 || (!gb && !mb && !kb) { err = fmt.Errorf("max memory illegal") return } if gb { sizeCount, err = strconv.ParseInt(size[:len(size)-2], 10, 64) if err != nil { return errorHandling() } sizeCount *= gigabyte C.MaxMemory = &sizeCount } if mb { sizeCount, err = strconv.ParseInt(size[:len(size)-2], 10, 64) if err != nil { return errorHandling() } sizeCount *= megabyte C.MaxMemory = &sizeCount } if kb { sizeCount, err = strconv.ParseInt(size[:len(size)-2], 10, 64) if err != nil { return errorHandling() } sizeCount *= kilobyte C.MaxMemory = &sizeCount } return } /* * 设置缓存 * key: 缓存key * val: 缓存value * expire: 过期时间 */ func (C *Cache) Set(key string, val interface{}, expire time.Duration) (err error) { // 判断是否超过最大内存 valSize := unsafe.Sizeof(val) if valSize+uintptr(C.CurrentMemory) > uintptr(*C.MaxMemory) { return fmt.Errorf("exceed maximum memory, set failed") } // 设置缓存 C.Storage[key] = val C.CurrentMemory += int64(valSize) C.ObjectCount++ // 设置过期时间 go func() { time.Sleep(expire) C.Del(key) }() return } /* * 获取缓存 * key: 缓存key */ func (C *Cache) Get(key string) (val interface{}, err error) { var ok bool if val, ok = C.Storage[key]; ok { return } else { err = fmt.Errorf("key don't exists") return } } /* * 删除缓存 * key: 缓存key */ func (C *Cache) Del(key string) (err error) { if val, ok := C.Storage[key]; ok { delete(C.Storage, key) C.ObjectCount-- valSize := unsafe.Sizeof(val) *C.MaxMemory = C.CurrentMemory - int64(valSize) return } else { return fmt.Errorf("key don't exists") } } /* * 判断key是否存在 * key: 缓存key */ func (C *Cache) Exists(key string) (exist bool, err error) { if _, ok := C.Storage[key]; ok { exist = true return } else { exist = false return } } /* * 清空所有缓存 */ func (C *Cache) Flush() (err error) { C.Storage = make(map[string]interface{}) C.ObjectCount = 0 C.CurrentMemory = 0 return } /* * 获取缓存中所有key的数量 */ func (C *Cache) Keys() (count int64) { return C.ObjectCount } func main() { cache := &Cache{ Storage: make(map[string]interface{}), } err := cache.SetMaxMemory("1gb") if err != nil { log.Fatal(err.Error()) return } err = cache.Set("hello", "world", 2*time.Second) if err != nil { log.Fatalln(err.Error()) return } result, err := cache.Get("hello") if err != nil { log.Fatalln(err.Error()) return } fmt.Println(result) fmt.Println(cache.Exists("hello")) fmt.Println(cache.Keys()) time.Sleep(3 * time.Second) fmt.Println(cache.Exists("hello")) fmt.Println(cache.Keys()) cache.Flush() fmt.Println(cache) }