Go-Cache/main.go
2023-07-31 01:14:43 +08:00

226 lines
4.0 KiB
Go

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)
}