github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/objcache/impl.go (about) 1 /* 2 * Copyright (c) 2023-present Sigma-Soft, Ltd. 3 * @author: Nikolay Nikitin 4 * 5 * This source code is licensed under the MIT license found in the 6 * LICENSE file in the root directory of this source tree. 7 */ 8 9 package objcache 10 11 import ( 12 lru "github.com/hashicorp/golang-lru/v2" 13 ) 14 15 // internally used interface 16 type refCounter interface { 17 tryAddRef() bool 18 Release() 19 } 20 21 // LRU cache implemented by hashicorp LRU cache 22 type cache[K comparable, V any] struct { 23 lru *lru.Cache[K, V] 24 } 25 26 func (c *cache[K, V]) Get(key K) (value V, ok bool) { 27 value, ok = c.lru.Get(key) 28 if ok { 29 if ref, auto := any(value).(refCounter); auto { 30 ok = ref.tryAddRef() 31 } 32 } 33 return value, ok 34 } 35 36 func (c *cache[K, V]) Put(key K, value V) { 37 // The problem of the twice put (value won’t be freed) is solved by convention (*DO NOT PUT SAME VALUE TWICE*) 38 // if old, exists := c.lru.Peek(key); exists && (any(old) == any(value)) { return } 39 40 if ref, auto := any(value).(refCounter); auto { 41 if !ref.tryAddRef() { 42 // notest: looks like value right now released 43 return 44 } 45 } 46 _ = c.lru.Add(key, value) 47 } 48 49 func (c *cache[K, V]) evicted(_ K, value V) { 50 if ref, ok := any(value).(refCounter); ok { 51 ref.Release() 52 } 53 }