github.com/searKing/golang/go@v1.2.117/container/lru/keylru.go (about) 1 // Copyright 2020 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package lru 6 7 import ( 8 "container/list" 9 "errors" 10 "sync" 11 ) 12 13 // KeyLRU takes advantage of list's sequence and map's efficient locate 14 type KeyLRU struct { 15 ll *list.List // list.Element.Value type is of interface{} 16 m map[any]*list.Element 17 once sync.Once 18 } 19 20 // lazyInit lazily initializes a zero List value. 21 func (lru *KeyLRU) lazyInit() { 22 lru.once.Do(func() { 23 lru.ll = &list.List{} 24 lru.m = make(map[any]*list.Element) 25 }) 26 } 27 func (lru *KeyLRU) Keys() []any { 28 var keys []any 29 for key := range lru.m { 30 keys = append(keys, key) 31 } 32 return keys 33 } 34 35 // add adds Key to the head of the linked list. 36 func (lru *KeyLRU) Add(key any) error { 37 lru.lazyInit() 38 ele := lru.ll.PushFront(key) 39 if _, ok := lru.m[key]; ok { 40 return errors.New("key was already in LRU") 41 } 42 lru.m[key] = ele 43 return nil 44 } 45 func (lru *KeyLRU) AddOrUpdate(key any) error { 46 lru.Remove(key) 47 return lru.Add(key) 48 } 49 50 func (lru *KeyLRU) RemoveOldest() any { 51 if lru.ll == nil { 52 return nil 53 } 54 ele := lru.ll.Back() 55 key := ele.Value.(any) 56 lru.ll.Remove(ele) 57 delete(lru.m, key) 58 return key 59 } 60 61 // Remove removes Key from cl. 62 func (lru *KeyLRU) Remove(key any) any { 63 if ele, ok := lru.m[key]; ok { 64 v := lru.ll.Remove(ele) 65 delete(lru.m, key) 66 return v 67 } 68 return nil 69 } 70 71 func (lru *KeyLRU) Find(key any) (any, bool) { 72 e, ok := lru.m[key] 73 return e, ok 74 } 75 76 func (lru *KeyLRU) Peek(key any) (any, bool) { 77 e, ok := lru.m[key] 78 if ok { 79 lru.Remove(key) 80 } 81 return e, ok 82 } 83 84 // Len returns the number of items in the cache. 85 func (lru *KeyLRU) Len() int { 86 return len(lru.m) 87 }