cache2go源码最后一讲 - examples
先看一下我们讲到哪里了:
cache2go的源码前面我们已经讲完了cacheitem和cachetable的实现,今天cahce和examples会一起讲完~
1、cache.go源码
前面的代码看完之后现在看cache.go就太简单了,上代码吧~
1var (
2 cache = make(map[string]*CacheTable)
3 mutex sync.RWMutex
4)
5
6// Cache returns the existing cache table with given name or creates a new one
7// if the table does not exist yet.
8//【表存在则返回表,表不存在的时候创建一个不包含items的空表,然后返回之】
9func Cache(table string) *CacheTable {
10 mutex.RLock()
11 //【注意cache的类型,这是一个用于存CacheTable的map】
12 t, ok := cache[table]
13 mutex.RUnlock()
14
15 if !ok {
16 mutex.Lock()
17 //【表不存在的时候需要创建一个空表,这时候做了一个二次检查,为的是并发安全】
18 t, ok = cache[table]
19 // Double check whether the table exists or not.
20 if !ok {
21 t = &CacheTable{
22 name: table,
23 items: make(map[interface{}]*CacheItem),
24 }
25 cache[table] = t
26 }
27 mutex.Unlock()
28 }
29
30 return t
31}
2、example
如上图,项目中还有一个examples目录,大家肯定已经猜到了里面的内容了,没错,就是上面介绍的一堆代码组成的缓存库,怎么玩?
下面我们一个一个来看这3个示例吧~
1、callbacks.go
1func main() {
2 //【创建一个名为myCache的缓存表】
3 cache := cache2go.Cache("myCache")
4
5 // This callback will be triggered every time a new item
6 // gets added to the cache.
7 //【每次有新item被加入到这个缓存表的时候会被触发的回调函数】
8 //【这个函数只做了一个输出的动作】
9 cache.SetAddedItemCallback(func(entry *cache2go.CacheItem) {
10 fmt.Println("Added:", entry.Key(), entry.Data(), entry.CreatedOn())
11 })
12 // This callback will be triggered every time an item
13 // is about to be removed from the cache.
14 //【当一个item被删除时被触发执行的回调函数,同样只有一个打印功能】
15 cache.SetAboutToDeleteItemCallback(func(entry *cache2go.CacheItem) {
16 fmt.Println("Deleting:", entry.Key(), entry.Data(), entry.CreatedOn())
17 })
18
19 // Caching a new item will execute the AddedItem callback.
20 //【缓存中添加一条记录】
21 cache.Add("someKey", 0, "This is a test!")
22
23 // Let's retrieve the item from the cache
24 //【读取刚才存入的数据】
25 res, err := cache.Value("someKey")
26 if err == nil {
27 fmt.Println("Found value in cache:", res.Data())
28 } else {
29 fmt.Println("Error retrieving value from cache:", err)
30 }
31
32 // Deleting the item will execute the AboutToDeleteItem callback.
33 //【删除someKey对应的记录】
34 cache.Delete("someKey")
35
36 // Caching a new item that expires in 3 seconds
37 //【添加设置了3s存活时间的记录】
38 res = cache.Add("anotherKey", 3*time.Second, "This is another test")
39
40 // This callback will be triggered when the item is about to expire
41 //【一旦触发了删除操作就会调用到下面这个回调函数,在这里也就是3s到期时被执行
42 res.SetAboutToExpireCallback(func(key interface{}) {
43 fmt.Println("About to expire:", key.(string))
44 })
45
46 //【为了等上面的3s时间到】
47 time.Sleep(5 * time.Second)
48}
2、dataloader.go
1func main() {
2 cache := cache2go.Cache("myCache")
3
4 // The data loader gets called automatically whenever something
5 // tries to retrieve a non-existing key from the cache.
6 //【当从cache中访问一个不存在的key时会触发这个回调函数】
7 cache.SetDataLoader(func(key interface{}, args ...interface{}) *cache2go.CacheItem {
8 // Apply some clever loading logic here, e.g. read values for
9 // this key from database, network or file.
10 //【这里可以做一些机智的处理,比如说从数据库,网络或者文件中读取数据,这当然也是缓存的意义】
11 //key.(string)是类型断言,将interface{}类型的数据转回到string类型
12 val := "This is a test with key " + key.(string)
13
14 // This helper method creates the cached item for us. Yay!
15 //【很棒,这样就构造了一个value,然后构造出item】
16 item := cache2go.NewCacheItem(key, 0, val)
17 return item
18 })
19
20 // Let's retrieve a few auto-generated items from the cache.
21 //【试着检索一些自动生成的items】
22 for i := 0; i < 10; i++ {
23 //【将i转换为字符串,拼接成someKey_1的形式】
24 res, err := cache.Value("someKey_" + strconv.Itoa(i))
25 if err == nil {
26 fmt.Println("Found value in cache:", res.Data())
27 } else {
28 fmt.Println("Error retrieving value from cache:", err)
29 }
30 }
31}
3、mycachedapp.go
1// Keys & values in cache2go can be of arbitrary types, e.g. a struct.
2//【这个例子中要存储的数据是如下结构体类型】
3type myStruct struct {
4 text string
5 moreData []byte
6}
7
8func main() {
9 // Accessing a new cache table for the first time will create it.
10 //【创建缓存表myCache】
11 cache := cache2go.Cache("myCache")
12
13 // We will put a new item in the cache. It will expire after
14 // not being accessed via Value(key) for more than 5 seconds.
15 //【构造一个数据】
16 val := myStruct{"This is a test!", []byte{}}
17 //【存入数据,设置存活时间为5s】
18 cache.Add("someKey", 5*time.Second, &val)
19
20 // Let's retrieve the item from the cache.
21 //【试着读取】
22 res, err := cache.Value("someKey")
23 if err == nil {
24 fmt.Println("Found value in cache:", res.Data().(*myStruct).text)
25 } else {
26 fmt.Println("Error retrieving value from cache:", err)
27 }
28
29 // Wait for the item to expire in cache.
30 //【等待6s之后,明显是该过期了】
31 time.Sleep(6 * time.Second)
32 res, err = cache.Value("someKey")
33 if err != nil {
34 fmt.Println("Item is not cached (anymore).")
35 }
36
37 // Add another item that never expires.
38 //【再存入一个永不过期的数据】
39 cache.Add("someKey", 0, &val)
40
41 // cache2go supports a few handy callbacks and loading mechanisms.
42 //【设置回调函数,删除数据的时候被调用】
43 cache.SetAboutToDeleteItemCallback(func(e *cache2go.CacheItem) {
44 fmt.Println("Deleting:", e.Key(), e.Data().(*myStruct).text, e.CreatedOn())
45 })
46
47 // Remove the item from the cache.
48 //【手动执行删除操作,当然,上面设置的函数将被调用】
49 cache.Delete("someKey")
50
51 // And wipe the entire cache table.
52 //【抹去整个cache中的数据】
53 cache.Flush()
54}
终于全部讲完了~
如上,整个项目除了测试代码外,实现逻辑部分全部分析完了,cache2go算是非常简短的go开源项目了,很适合作为第一个读源码项目,下面要分析的groupcache也是和cache相关,但是相比cache2go要复杂很多,groupcache是大名鼎鼎的memcache的go语言版,我们下周开始分析!
cache2go源码最后一讲 - examples的更多相关文章
- Pytorch学习之源码理解:pytorch/examples/mnists
Pytorch学习之源码理解:pytorch/examples/mnists from __future__ import print_function import argparse import ...
- 启航 - cache2go源码分析
一.概述 我们今天开始第一部分“golang技能提升”.这一块我计划分析3个项目,一个是很流行的golang源码阅读入门项目cache2go,接着是非常流行的memcache的go语言版groupca ...
- Kettle 4.2源码分析第二讲--Kettle插件结构体系简介
1. 插件体系结构 1.1. 插件技术原理 1.1.1. 插件概念说明 插件是一种遵循统一的预定义接口规范编写出来的程序,应用程序在运行时通过接口规范对插件进行调用,以扩展应用程序的功能.在英 ...
- 建议收藏!利用Spring解决循环依赖,深入源码给你讲明白!
前置知识 只有单例模式下的bean会通过三级缓存提前暴露来解决循环依赖的问题.而非单例的bean每次获取都会重新创建,并不会放入三级缓存,所以多实例的bean循环依赖问题不能解决. 首先需要明白处于各 ...
- Kettle 4.2源码分析第一讲--Kettle 简介
Pentaho Data Integration(PDI)简介 1. PDI结构简介 图 1‑1 PDI核心组件 Spoon是构建ETL Jobs和Transformations的工具.Spoon可以 ...
- anki_vector SDK源码解析(教程)
一:最近anki vector robot开放了Python SDK,我听到的第一时间就赶快上网查了查,先抛几个官网重要链接吧: Python编程API手册及环境搭建等: https://sdk-re ...
- Redux异步解决方案之Redux-Thunk原理及源码解析
前段时间,我们写了一篇Redux源码分析的文章,也分析了跟React连接的库React-Redux的源码实现.但是在Redux的生态中还有一个很重要的部分没有涉及到,那就是Redux的异步解决方案.本 ...
- 手写@koa/router源码
上一篇文章我们讲了Koa的基本架构,可以看到Koa的基本架构只有中间件内核,并没有其他功能,路由功能也没有.要实现路由功能我们必须引入第三方中间件,本文要讲的路由中间件是@koa/router,这个中 ...
- 可视化工具gephi源码探秘(二)---导入netbeans
在上篇<可视化工具gephi源码探秘(一)>中主要介绍了如何将gephi的源码导入myeclipse中遇到的一些问题,此篇接着上篇而来,主要讲解当下通过myeclipse导入gephi源码 ...
随机推荐
- 我的 FPGA 学习历程(14)—— PWM 脉冲宽度调制
PWM 是一种调节输出功率的技术(俗称调压),其原理在于改变输出方波的占空比,具体输出见下图: 输出信号为电压值,当负载为恒阻时,上图中的输出功率分别为 25%.50%.75%. 实现方法如下: 设置 ...
- Python PE8 编程规范
1.使用四个空格而不是tab进行缩进 2.默认使用utf-8编码 3.尽量不要使用魔术方法 4.类中使用self作为默认参数 5.命名时,尽量使用驼峰式或单词+下划线,要保证见名知意 6.操作符和逗号 ...
- 无法运行 vue-manage-system@3.1.0 dev: `webpack-dev-server --inline --progress --
一个项目的变大好多人开发,难免会有很多的冲突.每次跟新代码都要一个坑一个坑的解决的.这次遇到这个坑好大.急死了.... 百度了好多说占用端口,试了好几遍不行.最终还是要去查原因的....经过了几个小时 ...
- 11、js 数组详细操作方法及解析合集
js 数组详细操作方法及解析合集 前言 在开发中,数组的使用场景非常多,平日中也涉及到很多数组的api/相关操作,一直也没有对这块内容进行一块整理总结,很多时候就算用过几次这个api,在开发中也很容易 ...
- MVC Web.Config 配置错误
配置一个MVC项目的 SessionState,查阅了大量的资料,发现都是直接在web.config中直接加入类似的语句就可以了 <sessionState timeout="60&q ...
- 【二代示波器教程】第12章 示波器设计—DAC信号发生器的实现
第12章 示波器设计—DAC信号发生器的实现 本章节为大家讲解二代示波器中信号发生器的实现.这个功能还是比较实用的,方便为二代示波器提供测试信号.实现了正弦波,方波和三角波的频率,幅度以及占 ...
- Java编程题: 写一个Singleton出来
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 一般Singleton模式通常有几种种形式: 第一种形式: 定义一个类,它的构造函数为private的, ...
- [Swift]LeetCode90. 子集 II | Subsets II
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the ...
- [Swift]LeetCode147. 对链表进行插入排序 | Insertion Sort List
Sort a linked list using insertion sort. A graphical example of insertion sort. The partial sorted l ...
- [Swift]LeetCode189. 旋转数组 | Rotate Array
Given an array, rotate the array to the right by k steps, where k is non-negative. Example 1: Input: ...