在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
package main; import ( "container/list" "errors" "sync" "fmt" "encoding/json" ) //LRU(Least recently used)最近最少使用,算法根据数据的历史访问记录来进行淘汰数据 //核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高" //常见的实现方式是用一个链表保存数据 //1. 新数据插入到链表头部 //2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部 //3. 当链表满的时候,将链表尾部的数据丢弃 type cacheItem struct { Key string; Val interface{}; } type LRU struct { //最大存储数量 maxNum int; //当前存储数量 curNum int; //锁,保证数据一致性 mutex sync.Mutex; //链表 data *list.List; } //添加数据 func (l *LRU) add(key string, value interface{}) error { //判断key是否存在 if e, _ := l.exist(key); e { return errors.New(key + "已存在"); } //判断当前存储数量与最大存储数量 if l.maxNum == l.curNum { //链表已满,则删除链表尾部元素 l.clear(); } l.mutex.Lock(); l.curNum++; //json序列化数据 data, _ := json.Marshal(cacheItem{key, value}); //把数据保存到链表头部 l.data.PushFront(data); l.mutex.Unlock(); return nil; } //设置数据 func (l *LRU) set(key string, value interface{}) error { e, item := l.exist(key); if !e { return l.add(key, value); } l.mutex.Lock(); data, _ := json.Marshal(cacheItem{key, value}); //设置链表元素数据 item.Value = data; l.mutex.Unlock(); return nil; } //清理数据 func (l *LRU) clear() interface{} { l.mutex.Lock(); l.curNum--; //删除链表尾部元素 v := l.data.Remove(l.data.Back()); l.mutex.Unlock(); return v; } //获取数据 func (l *LRU) get(key string) interface{} { e, item := l.exist(key); if !e { return nil; } l.mutex.Lock(); //数据被访问,则把元素移动到链表头部 l.data.MoveToFront(item); l.mutex.Unlock(); var data cacheItem; json.Unmarshal(item.Value.([]byte), &data); return data.Val; } //删除数据 func (l *LRU) del(key string) error { e, item := l.exist(key); if !e { return errors.New(key + "不存在"); } l.mutex.Lock(); l.curNum--; //删除链表元素 l.data.Remove(item); l.mutex.Unlock(); return nil; } //判断是否存在 func (l *LRU) exist(key string) (bool, *list.Element) { var data cacheItem; //循环链表,判断key是否存在 for v := l.data.Front(); v != nil; v = v.Next() { json.Unmarshal(v.Value.([]byte), &data); if key == data.Key { return true, v; } } return false, nil; } //返回长度 func (l *LRU) len() int { return l.curNum; } //打印链表 func (l *LRU) print() { var data cacheItem; for v := l.data.Front(); v != nil; v = v.Next() { json.Unmarshal(v.Value.([]byte), &data); fmt.Println("key:", data.Key, " value:", data.Val); } } //创建一个新的LRU func LRUNew(maxNum int) *LRU { return &LRU{ maxNum: maxNum, curNum: 0, mutex: sync.Mutex{}, data: list.New(), }; } func main() { lru := LRUNew(5); lru.add("1111", 1111); lru.add("2222", 2222); lru.add("3333", 3333); lru.add("4444", 4444); lru.add("5555", 5555); lru.print(); //get成功后,可以看到3333元素移动到了链表头 fmt.Println(lru.get("3333")); lru.print(); //再次添加元素,如果超过最大数量,则删除链表尾部元素,将新元素添加到链表头 lru.add("6666", 6666); lru.print(); lru.del("4444"); lru.print(); lru.set("2222", "242424"); lru.print(); }
|
请发表评论