-
接口型函数:-
// 定义接口 type Getter interface {Get(key string) ([]byte, error) }// 定义函数 type GetterFunc func(key string) ([]byte, error)// 实现接口 func (f GetterFunc) Get(key string) ([]byte, error) {return f(key) } -
价值:能将普通的函数类型作为参数,也能将结构体作为参数,使用更为灵活
-
例如:
-
// 若GetFromSource定义如下,需要传一个Getter作为参数 func GetFromSource(getter Getter, key string) []byte // 1.传函数(匿名函数和非匿名函数,下面是匿名) // 将函数类型转换为GetterFunc,这是实现了Getter接口的,可以传 GetFromSource(GetterFunc(func(key string) ([]byte, error) {return []byte(key), nil }), "hello") // 2.传结构体 type DB struct{ url string} func (db *DB) Get(key string) ([]byte, error) {// ...return []byte(v), nil } func main() {GetFromSource(new(DB), "hello") }
-
-
net/http包下的Handler就是使用这种特性-
type Handler interface {ServeHTTP(ResponseWriter, *Request) } type HandlerFunc func(ResponseWriter, *Request)func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {f(w, r) }
-
-
-
sync.Mutex:Go 语言标准库提供的一个互斥锁,当一个协程(goroutine)获得了这个锁的拥有权后,其它请求锁的协程(goroutine) 就会阻塞在Lock()方法的调用上,直到调用Unlock()锁被释放。 -
reflect.DeepEqual()- 对于基本数据类型(整数、布尔、字符串),与
==相同 - 可以比较数组、切片、结构体、map、接口等是否相同
- 对于切片,必须切片长度相等且顺序相同,元素相同
- 对于基本数据类型(整数、布尔、字符串),与
-
day2由四个文件组成,分别是lru.go、byteview.go、cache.go、geecache.go-
lru.go:lru缓存淘汰策略 -
byteview.go:缓存值,实现了Value接口 -
cache.go:并发控制 -
geecache.go:与外部交互,在缓存未命中时去查找数据源 -
cache.go将day1中的lru加入了锁机制,实现并发下的互斥访问,geecache.go中实现了Group结构体,其中包含cache和回调函数,在cache未命中时会调用回调函数查找数据库中的内容,同时,使用map结构分配多个缓存,用name进行区分,每个Group有一个唯一的name(例如学生成绩和学生课程的缓存使用不同的name区分) -
代码
// --------------------------------------------------------------------------------------- // ByteView.go 缓存元素的抽象 package gee// 只读数据结构 表示缓存值,实现了Value接口 type ByteView struct {b []byte }func (v ByteView) Len() int {return len(v.b) }func (v ByteView) ByteSlice() []byte {return cloneBytes(v.b) }func cloneBytes(b []byte) []byte {c := make([]byte, len(b))copy(c, b)return c }func (v ByteView) String() string {return string(v.b) } // cache.go 对day1中的lru加上并发控制 package gee // --------------------------------------------------------------------------------------- // 实现并发控制 import ("sync" )type cache struct {mu sync.Mutexlru *CachecacheBytes int64 }func (c *cache) add(key string, value ByteView) {c.mu.Lock()defer c.mu.Unlock()if c.lru == nil { // 延迟初始化c.lru = New(c.cacheBytes, nil)}c.lru.Add(key, value) }func (c *cache) get(key string) (value ByteView, ok bool) {c.mu.Lock()defer c.mu.Unlock()if c.lru == nil {return}if v, ok := c.lru.Get(key); ok {return v.(ByteView), ok}return } // --------------------------------------------------------------------------------------- // geecache.go 与源数据库进行交互 package gee// 实现与外部交互 import ("fmt""sync" )type Getter interface {Get(key string) ([]byte, error) }type GetterFunc func(key string) ([]byte, error)// 接口型函数 func (f GetterFunc) Get(key string) ([]byte, error) {return f(key) }type Group struct {name string // 缓存名称getter Getter // 回调函数mainCache cache // 缓存 }var (mu sync.Mutexgroups = make(map[string]*Group) )func NewGroup(name string, cacheBytes int64, getter Getter) *Group {if getter == nil {panic("Getter nil")}mu.Lock()defer mu.Unlock()g := &Group{name: name,getter: getter,mainCache: cache{cacheBytes: cacheBytes},}groups[name] = greturn g }func GetGroup(name string) *Group {mu.Lock()defer mu.Unlock()g := groups[name]return g }func (g *Group) Get(key string) (ByteView, error) {if key == "" {return ByteView{}, fmt.Errorf("key is nil")}if v, ok := g.mainCache.get(key); ok {fmt.Println("Gee Cache hit")return v, nil}return g.load(key) }func (g *Group) load(key string) (Value ByteView, err error) {return g.getLocally(key) }// 调用回调函数,去源数据库查找内容 func (g *Group) getLocally(key string) (ByteView, error) { bytes, err := g.getter.Get(key)if err != nil {return ByteView{}, err}value := ByteView{b: cloneBytes(bytes)}g.add(key, value)return value, nil}func (g *Group) add(key string, value ByteView) {g.mainCache.add(key, value) }
-
极客兔兔Gee-Cache Day2
2025/11/28 16:32:02
来源:https://blog.csdn.net/qq_40052678/article/details/142708296
浏览:
次
关键词:极客兔兔Gee-Cache Day2
版权声明:
本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。
我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com
热文排行
- 老外讲解用Delphi 12.3作web
- 华为 海思22AP10(SS524)H.265 编解码处理器用户指南
- 数据库物理结构设计
- 基于重要抽样的主动学习不平衡分类方法ALIS
- 开源模型时代的 AI 开发革命:Dify 技术深度解析
- npm install puppeteer 报错 npm ERR! PUPPETEER_DOWNLOAD_HOST is deprecated解决办法
- 《缺失MRI模态下的脑肿瘤分割的潜在相关表示学习》| 文献速递-深度学习肿瘤自动分割
- 【量化策略】均值回归策略
- 如何在 Mac 上清空硬盘后恢复丢失的数据?
- (2)Django生产环境数据库的切换以及环境配置python-dotenv方案
