cache.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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]) Clear() {
  20. self.lock.RLock()
  21. clear(self.data)
  22. self.lock.Unlock()
  23. }
  24. func (self *LRUCache[K, V]) Get(key K) (ans V, found bool) {
  25. self.lock.RLock()
  26. ans, found = self.data[key]
  27. self.lock.RUnlock()
  28. return
  29. }
  30. func (self *LRUCache[K, V]) Set(key K, val V) {
  31. self.lock.RLock()
  32. self.data[key] = val
  33. self.lock.RUnlock()
  34. return
  35. }
  36. func (self *LRUCache[K, V]) GetOrCreate(key K, create func(key K) (V, error)) (V, error) {
  37. self.lock.RLock()
  38. ans, found := self.data[key]
  39. self.lock.RUnlock()
  40. if found {
  41. return ans, nil
  42. }
  43. ans, err := create(key)
  44. if err == nil {
  45. self.lock.Lock()
  46. self.data[key] = ans
  47. self.lru.PushFront(key)
  48. if self.max_size > 0 && self.lru.Len() > self.max_size {
  49. k := self.lru.Remove(self.lru.Back())
  50. delete(self.data, k.(K))
  51. }
  52. self.lock.Unlock()
  53. }
  54. return ans, err
  55. }
  56. func (self *LRUCache[K, V]) MustGetOrCreate(key K, create func(key K) V) V {
  57. self.lock.RLock()
  58. ans, found := self.data[key]
  59. self.lock.RUnlock()
  60. if found {
  61. return ans
  62. }
  63. ans = create(key)
  64. self.lock.Lock()
  65. self.data[key] = ans
  66. self.lock.Unlock()
  67. return ans
  68. }