gcache
使用方式:
接口文档:
https://godoc.org/github.com/gogf/gf/os/gcache
gcache
可以使用New
方法创建使用,并且也可以使用包方法使用。在通过包方法使用缓存功能时,操作的是gcache
默认提供的一个gcache.Cache
对象,具有全局性,因此在使用时注意全局键名的覆盖。
gcache
存储的键值类型是interface{}
,也就是说可以存储任意的数据类型,当获取数据时返回的也是interface{}
类型,若需要转换为其他的类型可以通过gcache
的Get*
方法便捷获取常见类型。
另外需要注意的是,gcache
的缓存过期时间参数duration
的类型为time.Duration
类型,在Set
缓存变量时,如果缓存时间参数duration = 0
表示不过期,duration < 0
表示立即过期,expire > 0
表示超时过期。
package main
import (
"fmt"
"github.com/gogf/gf/os/gcache"
)
func main() {
// 创建一个缓存对象,
// 当然也可以便捷地直接使用gcache包方法
c := gcache.New()
// 设置缓存,不过期
c.Set("k1", "v1", 0)
fmt.Println(c.Get("k1"))
// 获取缓存大小
// 缓存中是否存在指定键名
fmt.Println(c.Contains("k1"))
// 删除并返回被删除的键值
fmt.Println(c.Remove("k1"))
// 关闭缓存对象,让GC回收资源
c.Close()
}
执行后,输出结果为:
v1
1
true
v1
执行后,输出结果为:
[k1]
[v1]
v2
map[k1:v1 k2:v2]
map[k2:v2]
需要注意的是,GetOrSetFunc
的缓存方法参数f
是在缓存的锁机制外执行,因此在f
内部也可以嵌套调用GetOrSetFunc
。但如果f
的执行比较耗时,高并发的时候容易出现f
被多次执行的情况(缓存设置只有第一个执行的f
返回结果能够设置成功,其余的被抛弃掉)。
而GetOrSetFuncLock
的缓存方法f
是在缓存的锁机制内执行,因此可以保证当缓存项不存在时只会执行一次f
,但是缓存写锁的时间随着f
方法的执行时间而定。
我们来看一个在项目中使用GetOrSetFunc
的示例,该示例遍历检索markdown
文件进行字符串检索,并根据指定的搜索key
缓存该结果值,因此多次搜索该key
时,第一次会执行目录遍历搜索,后续将直接使用缓存结果。
// 根据关键字进行markdown文档搜索,返回文档path列表
func SearchMdByKey(key string) []string {
glog.Cat("search").Println(key)
v := cache.GetOrSetFunc("doc_search_result_" + key, func() interface{} {
// 当该key的检索缓存不存在时,执行检索
array := garray.NewStringArray(0, 0, false)
docPath := g.Config().GetString("doc.path")
// 当目录列表不存在时,执行检索
paths, _ := gfile.ScanDir(docPath, "*.md", true)
return paths
}, 0)
// 遍历markdown文件列表,执行字符串搜索
for _, path := range gconv.Strings(paths) {
content := gfcache.GetContents(path)
if len(content) > 0 {
if strings.Index(content, key) != -1 {
index := gstr.Replace(path, ".md", "")
index = gstr.Replace(index, docPath, "")
array.Append(index)
}
}
}
return array.Slice()
}, 0)
return gconv.Strings(v)
}
10
[2 4 5 7 8 9 0 1 3 6]
1
2
[1 9]
CPU: Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz
SYS: Ubuntu 16.04 amd64