lrucache.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package lrucache
  2. // Element - node to store cache item
  3. type Element struct {
  4. prev, next *Element
  5. Key interface{}
  6. Value interface{}
  7. }
  8. // Next - fetch older element
  9. func (e *Element) Next() *Element {
  10. return e.next
  11. }
  12. // Prev - fetch newer element
  13. func (e *Element) Prev() *Element {
  14. return e.prev
  15. }
  16. // LRUCache - a data structure that is efficient to insert/fetch/delete cache items [both O(1) time complexity]
  17. type LRUCache struct {
  18. cache map[interface{}]*Element
  19. head *Element
  20. tail *Element
  21. capacity int
  22. }
  23. // New - create a new lru cache object
  24. func New(capacity int) *LRUCache {
  25. return &LRUCache{make(map[interface{}]*Element), nil, nil, capacity}
  26. }
  27. // Put - put a cache item into lru cache
  28. func (lc *LRUCache) Put(key interface{}, value interface{}) {
  29. if e, ok := lc.cache[key]; ok {
  30. e.Value = value
  31. lc.refresh(e)
  32. return
  33. }
  34. if lc.capacity == 0 {
  35. return
  36. } else if len(lc.cache) >= lc.capacity {
  37. // evict the oldest item
  38. delete(lc.cache, lc.tail.Key)
  39. lc.remove(lc.tail)
  40. }
  41. e := &Element{nil, lc.head, key, value}
  42. lc.cache[key] = e
  43. if len(lc.cache) != 1 {
  44. lc.head.prev = e
  45. } else {
  46. lc.tail = e
  47. }
  48. lc.head = e
  49. }
  50. // Get - get value of key from lru cache with result
  51. func (lc *LRUCache) Get(key interface{}) (interface{}, bool) {
  52. if e, ok := lc.cache[key]; ok {
  53. lc.refresh(e)
  54. return e.Value, ok
  55. }
  56. return nil, false
  57. }
  58. // Delete - delete item by key from lru cache
  59. func (lc *LRUCache) Delete(key interface{}) {
  60. if e, ok := lc.cache[key]; ok {
  61. delete(lc.cache, key)
  62. lc.remove(e)
  63. }
  64. }
  65. // Range - calls f sequentially for each key and value present in the lru cache
  66. func (lc *LRUCache) Range(f func(key, value interface{}) bool) {
  67. for i := lc.head; i != nil; i = i.Next() {
  68. if !f(i.Key, i.Value) {
  69. break
  70. }
  71. }
  72. }
  73. // Update - inplace update
  74. func (lc *LRUCache) Update(key interface{}, f func(value *interface{})) {
  75. if e, ok := lc.cache[key]; ok {
  76. f(&e.Value)
  77. lc.refresh(e)
  78. }
  79. }
  80. // Front - get front element of lru cache
  81. func (lc *LRUCache) Front() *Element {
  82. return lc.head
  83. }
  84. // Back - get back element of lru cache
  85. func (lc *LRUCache) Back() *Element {
  86. return lc.tail
  87. }
  88. // Len - length of lru cache
  89. func (lc *LRUCache) Len() int {
  90. return len(lc.cache)
  91. }
  92. // Capacity - capacity of lru cache
  93. func (lc *LRUCache) Capacity() int {
  94. return lc.capacity
  95. }
  96. func (lc *LRUCache) refresh(e *Element) {
  97. if e.prev != nil {
  98. e.prev.next = e.next
  99. if e.next == nil {
  100. lc.tail = e.prev
  101. } else {
  102. e.next.prev = e.prev
  103. }
  104. e.prev = nil
  105. e.next = lc.head
  106. lc.head.prev = e
  107. lc.head = e
  108. }
  109. }
  110. func (lc *LRUCache) remove(e *Element) {
  111. if e.prev == nil {
  112. lc.head = e.next
  113. } else {
  114. e.prev.next = e.next
  115. }
  116. if e.next == nil {
  117. lc.tail = e.prev
  118. } else {
  119. e.next.prev = e.prev
  120. }
  121. }