github.com/cs3org/reva/v2@v2.27.7/pkg/storage/utils/decomposedfs/mtimesyncedcache/mtimesyncedcache.go (about)

     1  package mtimesyncedcache
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  )
     7  
     8  type Cache[K comparable, T any] struct {
     9  	entries Map[K, *entry[T]]
    10  }
    11  
    12  type entry[T any] struct {
    13  	mtime time.Time
    14  	value T
    15  
    16  	mu sync.Mutex
    17  }
    18  
    19  func New[K comparable, T any]() Cache[K, T] {
    20  	return Cache[K, T]{
    21  		entries: Map[K, *entry[T]]{},
    22  	}
    23  }
    24  
    25  func (c *Cache[K, T]) Store(key K, mtime time.Time, value T) error {
    26  	c.entries.Store(key, &entry[T]{
    27  		mtime: mtime,
    28  		value: value,
    29  	})
    30  	return nil
    31  }
    32  
    33  func (c *Cache[K, T]) Load(key K) (T, bool) {
    34  	entry, ok := c.entries.Load(key)
    35  	if !ok {
    36  		var t T
    37  		return t, false
    38  	}
    39  	return entry.value, true
    40  }
    41  
    42  func (c *Cache[K, T]) LoadOrStore(key K, mtime time.Time, f func() (T, error)) (T, error) {
    43  	e, _ := c.entries.LoadOrStore(key, &entry[T]{})
    44  
    45  	e.mu.Lock()
    46  	defer e.mu.Unlock()
    47  	if mtime.After(e.mtime) {
    48  		e.mtime = mtime
    49  		v, err := f()
    50  		if err != nil {
    51  			var t T
    52  			return t, err
    53  		}
    54  		e.value = v
    55  		c.entries.Store(key, e)
    56  	}
    57  
    58  	return e.value, nil
    59  }