cache.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package utils
  3. import (
  4. "container/list"
  5. "fmt"
  6. "sync"
  7. )
  8. var _ = fmt.Print
  9. type LRUCache[K comparable, V any] struct {
  10. data map[K]V
  11. lock sync.RWMutex
  12. max_size int
  13. lru *list.List
  14. }
  15. func NewLRUCache[K comparable, V any](max_size int) *LRUCache[K, V] {
  16. ans := LRUCache[K, V]{data: map[K]V{}, max_size: max_size, lru: list.New()}
  17. return &ans
  18. }
  19. func (self *LRUCache[K, V]) Get(key K) (ans V, found bool) {
  20. self.lock.RLock()
  21. ans, found = self.data[key]
  22. self.lock.RUnlock()
  23. return
  24. }
  25. func (self *LRUCache[K, V]) Set(key K, val V) {
  26. self.lock.RLock()
  27. self.data[key] = val
  28. self.lock.RUnlock()
  29. return
  30. }
  31. func (self *LRUCache[K, V]) GetOrCreate(key K, create func(key K) (V, error)) (V, error) {
  32. self.lock.RLock()
  33. ans, found := self.data[key]
  34. self.lock.RUnlock()
  35. if found {
  36. return ans, nil
  37. }
  38. ans, err := create(key)
  39. if err == nil {
  40. self.lock.Lock()
  41. self.data[key] = ans
  42. self.lru.PushFront(key)
  43. if self.max_size > 0 && self.lru.Len() > self.max_size {
  44. k := self.lru.Remove(self.lru.Back())
  45. delete(self.data, k.(K))
  46. }
  47. self.lock.Unlock()
  48. }
  49. return ans, err
  50. }
  51. func (self *LRUCache[K, V]) MustGetOrCreate(key K, create func(key K) V) V {
  52. self.lock.RLock()
  53. ans, found := self.data[key]
  54. self.lock.RUnlock()
  55. if found {
  56. return ans
  57. }
  58. ans = create(key)
  59. self.lock.Lock()
  60. self.data[key] = ans
  61. self.lock.Unlock()
  62. return ans
  63. }