Skip to content

Commit

Permalink
add memory_cache;update other cache
Browse files Browse the repository at this point in the history
  • Loading branch information
lejianwen committed May 22, 2024
1 parent f29b5f0 commit fec5903
Show file tree
Hide file tree
Showing 6 changed files with 377 additions and 62 deletions.
44 changes: 33 additions & 11 deletions lib/cache/cache.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package cache

import (
"github.com/go-redis/redis/v8"
"sync"
"encoding/json"
)

type Handler interface {
Get(key string, value interface{}) error
Set(key string, value interface{}, exp int) (bool, error)
Gc() error
EncodeValue(value interface{}) (string, error)
DecodeValue(value string, rtv interface{}) error
}

// MaxTimeOut 最大超时时间

const (
TypeMem = "memory"
TypeRedis = "redis"
TypeFile = "file"
MaxTimeOut = 365 * 24 * 3600
Expand All @@ -28,19 +26,43 @@ func New(typ string) Handler {
cache = NewFileCache()
case TypeRedis:
cache = new(RedisCache)
case TypeMem: // memory
cache = NewMemoryCache(0)
default:
cache = NewFileCache()
cache = NewMemoryCache(0)
}
return cache
}

func NewRedis(conf *redis.Options) *RedisCache {
cache := RedisCacheInit(conf)
return cache
func EncodeValue(value interface{}) (string, error) {
if v, ok := value.(string); ok {
return v, nil
}
if v, ok := value.([]byte); ok {
return string(v), nil
}
b, err := json.Marshal(value)
if err != nil {
return "", err
}
return string(b), nil
}

func NewFileCache() *FileCache {
return &FileCache{
locks: make(map[string]*sync.Mutex),
func DecodeValue(value string, rtv interface{}) error {
//判断rtv的类型是否是string,如果是string,直接赋值并返回
switch rtv.(type) {
case *string:
*(rtv.(*string)) = value
return nil
case *[]byte:
*(rtv.(*[]byte)) = []byte(value)
return nil
//struct
case *interface{}:
err := json.Unmarshal(([]byte)(value), rtv)
return err
default:
err := json.Unmarshal(([]byte)(value), rtv)
return err
}
}
40 changes: 17 additions & 23 deletions lib/cache/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ package cache

import (
"crypto/md5"
"encoding/json"
"fmt"
"os"
"sync"
"time"
)

var Dir string = os.TempDir()

type FileCache struct {
mu sync.Mutex
locks map[string]*sync.Mutex
Dir string
}

func (fc *FileCache) getLock(key string) *sync.Mutex {
Expand All @@ -30,21 +28,21 @@ func (fc *FileCache) getLock(key string) *sync.Mutex {

func (c *FileCache) Get(key string, value interface{}) error {
f := c.fileName(key)

fileInfo, err := os.Stat(f)
if err != nil {
return err
//文件不存在
return nil
}
difT := time.Now().Sub(fileInfo.ModTime())
if difT >= 0 {
os.Remove(f)
return err
return nil
}
data, err := os.ReadFile(f)
if err != nil {
return err
}
err1 := c.DecodeValue(string(data), value)
err1 := DecodeValue(string(data), value)
return err1
}

Expand All @@ -55,7 +53,7 @@ func (c *FileCache) Set(key string, value interface{}, exp int) (bool, error) {
lock.Lock()
defer lock.Unlock()

str, err := c.EncodeValue(value)
str, err := EncodeValue(value)
if err != nil {
return false, err
}
Expand All @@ -67,35 +65,31 @@ func (c *FileCache) Set(key string, value interface{}, exp int) (bool, error) {
if exp <= 0 {
exp = MaxTimeOut
}
twoDaysFromNow := time.Now().Add(time.Duration(exp) * time.Second)
err = os.Chtimes(f, twoDaysFromNow, twoDaysFromNow)
expFromNow := time.Now().Add(time.Duration(exp) * time.Second)
err = os.Chtimes(f, expFromNow, expFromNow)
if err != nil {
return false, err
}
return true, nil
}

func (c *FileCache) EncodeValue(value interface{}) (string, error) {
js, err := json.Marshal(value)
if err != nil {
return "", err
}
return string(js), err
}
func (c *FileCache) DecodeValue(value string, rtv interface{}) error {
err := json.Unmarshal(([]byte)(value), rtv)
return err
}
func (c *FileCache) SetDir(path string) {
Dir = path
c.Dir = path
}

func (c *FileCache) fileName(key string) string {
f := Dir + string(os.PathSeparator) + fmt.Sprintf("%x", md5.Sum([]byte(key)))
f := c.Dir + string(os.PathSeparator) + fmt.Sprintf("%x", md5.Sum([]byte(key)))
return f
}

func (c *FileCache) Gc() error {
//检查文件过期时间,并删除
return nil
}

func NewFileCache() *FileCache {
return &FileCache{
locks: make(map[string]*sync.Mutex),
Dir: os.TempDir(),
}
}
40 changes: 27 additions & 13 deletions lib/cache/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import (
)

func TestFileSet(t *testing.T) {
fc := &FileCache{}
fc := NewFileCache()
re, err := fc.Set("123", "ddd", 0)
fmt.Println(Dir)
fmt.Println(re)
if err != nil {
fmt.Println(err.Error())
Expand All @@ -18,25 +17,39 @@ func TestFileSet(t *testing.T) {
}

func TestFileGet(t *testing.T) {
fc := &FileCache{}
_, err := fc.Set("123", "45156", 300)
if err != nil {
t.Fatalf("写入失败")
}
fc := NewFileCache()
res := ""
err = fc.Get("123", &res)
err := fc.Get("123", &res)
if err != nil {
fmt.Println(err.Error())
t.Fatalf("读取失败")
}
fmt.Println("res", res)
}

func TestFileGetJson(t *testing.T) {
fc := &FileCache{}
fc := NewFileCache()
type r struct {
Aa string `json:"a"`
B string `json:"c"`
}

res := &r{
Aa: "ab", B: "cdc",
}
err2 := fc.Get("123", res)
fmt.Println("res", res)
if err2 != nil {
t.Fatalf("读取失败" + err2.Error())
}
}
func TestFileSetGetJson(t *testing.T) {
fc := NewFileCache()
type r struct {
Aa string `json:"a"`
B string `json:"c"`
}

old := &r{
Aa: "ab", B: "cdc",
}
Expand All @@ -47,25 +60,26 @@ func TestFileGetJson(t *testing.T) {

res := &r{}
err2 := fc.Get("123", res)
fmt.Println("res", res)
if err2 != nil {
t.Fatalf("读取失败")
t.Fatalf("读取失败" + err2.Error())
}
if !reflect.DeepEqual(res, old) {
t.Fatalf("读取错误")
}
fmt.Println(res, res.Aa)
fmt.Println("res", res)
}

func BenchmarkSet(b *testing.B) {
fc := &FileCache{}
fc := NewFileCache()
b.ResetTimer()
for i := 0; i < b.N; i++ {
fc.Set("123", "{dsv}", 1000)
}
}

func BenchmarkGet(b *testing.B) {
fc := &FileCache{}
fc := NewFileCache()
b.ResetTimer()
v := ""
for i := 0; i < b.N; i++ {
Expand Down
Loading

0 comments on commit fec5903

Please sign in to comment.