Files
gf/g/os/gcache/gcache_mem_cache_lru.go

89 lines
2.2 KiB
Go
Raw Normal View History

2018-03-27 17:53:46 +08:00
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package gcache
import (
"fmt"
"container/list"
2018-03-27 17:53:46 +08:00
"gitee.com/johng/gf/g/container/glist"
"gitee.com/johng/gf/g/container/gqueue"
"gitee.com/johng/gf/g/container/gmap"
2018-03-27 17:53:46 +08:00
)
// LRU算法实现对象底层双向链表使用了标准库的list.List
type memCacheLru struct {
data *gmap.Map // 记录键名与链表中的位置项指针
list *glist.List // 键名历史记录链表
queue *gqueue.Queue // 事件队列
2018-03-27 17:53:46 +08:00
}
// 创建LRU管理对象
func newMemCacheLru() *memCacheLru {
lru := &memCacheLru {
2018-03-27 17:53:46 +08:00
list : glist.New(),
data : gmap.New(),
2018-03-27 17:53:46 +08:00
queue : gqueue.New(),
}
go lru.StartAutoLoop()
return lru
}
// 关闭LRU对象
func (lru *memCacheLru) Close() {
2018-03-27 17:53:46 +08:00
lru.queue.Close()
}
// 删除指定数据项
func (lru *memCacheLru) Remove(key interface{}) {
if v := lru.data.Get(key); v != nil {
lru.data.Remove(key)
lru.list.Remove(v.(*list.Element))
}
}
2018-09-19 09:47:50 +08:00
// 当前LRU数据大小
func (lru *memCacheLru) Size() int {
return lru.data.Size()
}
2018-03-27 17:53:46 +08:00
// 添加LRU数据项
func (lru *memCacheLru) Push(key interface{}) {
lru.queue.Push(key)
2018-03-27 17:53:46 +08:00
}
// 从链表尾删除LRU数据项并返回对应数据
func (lru *memCacheLru) Pop() interface{} {
2018-03-27 17:53:46 +08:00
if v := lru.list.PopBack(); v != nil {
lru.data.Remove(v)
return v
2018-03-27 17:53:46 +08:00
}
return nil
2018-03-27 17:53:46 +08:00
}
// 从链表头打印LRU链表值
func (lru *memCacheLru) Print() {
2018-03-27 17:53:46 +08:00
for _, v := range lru.list.FrontAll() {
fmt.Printf("%v ", v)
2018-03-27 17:53:46 +08:00
}
}
2018-09-19 09:47:50 +08:00
// 异步执行协程将queue中的数据同步到list中
func (lru *memCacheLru) StartAutoLoop() {
2018-03-27 17:53:46 +08:00
for {
if v := lru.queue.Pop(); v != nil {
2018-03-27 17:53:46 +08:00
// 删除对应链表项
if v := lru.data.Get(v); v != nil {
2018-03-27 17:53:46 +08:00
lru.list.Remove(v.(*list.Element))
}
// 将数据插入到链表头,并记录对应的链表项到哈希表中,便于检索
lru.data.Set(v, lru.list.PushFront(v))
2018-03-27 17:53:46 +08:00
} else {
break
}
}
}