github.com/searKing/golang/go@v1.2.117/container/lru/lru.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 // LRU takes advantage of list's sequence and map's efficient locate 14 type LRU struct { 15 ll *list.List // list.Element.Value type is of interface{} 16 m map[any]*list.Element 17 once sync.Once 18 } 19 type Pair struct { 20 Key any 21 Value any 22 } 23 24 // lazyInit lazily initializes a zero List value. 25 func (lru *LRU) lazyInit() { 26 lru.once.Do(func() { 27 lru.ll = &list.List{} 28 lru.m = make(map[any]*list.Element) 29 }) 30 } 31 32 func (lru *LRU) Keys() []any { 33 var keys []any 34 for key := range lru.m { 35 keys = append(keys, key) 36 } 37 return keys 38 } 39 func (lru *LRU) Values() []any { 40 var values []any 41 for _, value := range lru.m { 42 values = append(values, value) 43 } 44 return values 45 } 46 47 func (lru *LRU) Pairs() []Pair { 48 var pairs []Pair 49 for key, value := range lru.m { 50 pairs = append(pairs, Pair{ 51 Key: key, 52 Value: value, 53 }) 54 } 55 return pairs 56 } 57 func (lru *LRU) AddPair(pair Pair) error { 58 return lru.Add(pair.Key, pair.Value) 59 } 60 61 // Add adds Key to the head of the linked list. 62 func (lru *LRU) Add(key any, value any) error { 63 lru.lazyInit() 64 ele := lru.ll.PushFront(Pair{ 65 Key: key, 66 Value: value, 67 }) 68 if _, ok := lru.m[key]; ok { 69 return errors.New("key was already in LRU") 70 } 71 lru.m[key] = ele 72 return nil 73 } 74 75 func (lru *LRU) AddOrUpdate(key any, value any) error { 76 lru.Remove(key) 77 return lru.Add(key, value) 78 } 79 80 func (lru *LRU) RemoveOldest() any { 81 if lru.ll == nil { 82 return nil 83 } 84 ele := lru.ll.Back() 85 pair := ele.Value.(Pair) 86 v := lru.ll.Remove(ele) 87 delete(lru.m, pair.Key) 88 return v 89 } 90 91 // Remove removes Key from cl. 92 func (lru *LRU) Remove(key any) any { 93 if ele, ok := lru.m[key]; ok { 94 v := lru.ll.Remove(ele) 95 delete(lru.m, key) 96 return v 97 } 98 return nil 99 } 100 101 func (lru *LRU) Find(key any) (any, bool) { 102 e, ok := lru.m[key] 103 if !ok { 104 return nil, ok 105 } 106 return e.Value.(Pair).Value, true 107 } 108 109 func (lru *LRU) Peek(key any) (any, bool) { 110 e, ok := lru.m[key] 111 if ok { 112 lru.Remove(key) 113 } 114 return e.Value.(Pair).Value, ok 115 } 116 117 // Len returns the number of items in the cache. 118 func (lru *LRU) Len() int { 119 return len(lru.m) 120 }