github.com/neohugo/neohugo@v0.123.8/common/maps/cache.go (about) 1 // Copyright 2024 The Hugo Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package maps 15 16 import "sync" 17 18 // Cache is a simple thread safe cache backed by a map. 19 type Cache[K comparable, T any] struct { 20 m map[K]T 21 sync.RWMutex 22 } 23 24 // NewCache creates a new Cache. 25 func NewCache[K comparable, T any]() *Cache[K, T] { 26 return &Cache[K, T]{m: make(map[K]T)} 27 } 28 29 // Delete deletes the given key from the cache. 30 func (c *Cache[K, T]) Get(key K) (T, bool) { 31 c.RLock() 32 v, found := c.m[key] 33 c.RUnlock() 34 return v, found 35 } 36 37 // GetOrCreate gets the value for the given key if it exists, or creates it if not. 38 func (c *Cache[K, T]) GetOrCreate(key K, create func() T) T { 39 c.RLock() 40 v, found := c.m[key] 41 c.RUnlock() 42 if found { 43 return v 44 } 45 c.Lock() 46 defer c.Unlock() 47 v, found = c.m[key] 48 if found { 49 return v 50 } 51 v = create() 52 c.m[key] = v 53 return v 54 } 55 56 // Set sets the given key to the given value. 57 func (c *Cache[K, T]) Set(key K, value T) { 58 c.Lock() 59 c.m[key] = value 60 c.Unlock() 61 } 62 63 // SliceCache is a simple thread safe cache backed by a map. 64 type SliceCache[T any] struct { 65 m map[string][]T 66 sync.RWMutex 67 } 68 69 func NewSliceCache[T any]() *SliceCache[T] { 70 return &SliceCache[T]{m: make(map[string][]T)} 71 } 72 73 func (c *SliceCache[T]) Get(key string) ([]T, bool) { 74 c.RLock() 75 v, found := c.m[key] 76 c.RUnlock() 77 return v, found 78 } 79 80 func (c *SliceCache[T]) Append(key string, values ...T) { 81 c.Lock() 82 c.m[key] = append(c.m[key], values...) 83 c.Unlock() 84 } 85 86 func (c *SliceCache[T]) Reset() { 87 c.Lock() 88 c.m = make(map[string][]T) 89 c.Unlock() 90 }