github.com/cayleygraph/cayley@v0.7.7/internal/lru/lru.go (about) 1 // Copyright 2014 The Cayley Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lru 16 17 import ( 18 "container/list" 19 "sync" 20 ) 21 22 // TODO(kortschak) Reimplement without container/list. 23 24 // cache implements an LRU cache. 25 type Cache struct { 26 mu sync.Mutex 27 cache map[string]*list.Element 28 priority *list.List 29 maxSize int 30 } 31 32 type kv struct { 33 key string 34 value interface{} 35 } 36 37 func New(size int) *Cache { 38 return &Cache{ 39 maxSize: size, 40 priority: list.New(), 41 cache: make(map[string]*list.Element), 42 } 43 } 44 45 func (lru *Cache) Put(key string, value interface{}) { 46 if _, ok := lru.Get(key); ok { 47 return 48 } 49 50 lru.mu.Lock() 51 defer lru.mu.Unlock() 52 if len(lru.cache) == lru.maxSize { 53 last := lru.priority.Remove(lru.priority.Back()) 54 delete(lru.cache, last.(kv).key) 55 } 56 lru.priority.PushFront(kv{key: key, value: value}) 57 lru.cache[key] = lru.priority.Front() 58 } 59 60 func (lru *Cache) Del(key string) { 61 lru.mu.Lock() 62 defer lru.mu.Unlock() 63 e := lru.cache[key] 64 if e == nil { 65 return 66 } 67 delete(lru.cache, key) 68 lru.priority.Remove(e) 69 } 70 71 func (lru *Cache) Get(key string) (interface{}, bool) { 72 lru.mu.Lock() 73 defer lru.mu.Unlock() 74 if element, ok := lru.cache[key]; ok { 75 lru.priority.MoveToFront(element) 76 return element.Value.(kv).value, true 77 } 78 return nil, false 79 }