diff options
| author | Patrick Spek <p.spek@tyil.nl> | 2024-12-08 08:16:03 +0100 |
|---|---|---|
| committer | Patrick Spek <p.spek@tyil.nl> | 2024-12-08 08:16:03 +0100 |
| commit | 125410025f74a765292d1711871b25b1ccf933f8 (patch) | |
| tree | 95a06806af6e8a29ccbf9eb6b21d0cda562e6261 | |
| download | cache-125410025f74a765292d1711871b25b1ccf933f8.tar.gz cache-125410025f74a765292d1711871b25b1ccf933f8.tar.bz2 | |
| -rw-r--r-- | cache.go | 101 | ||||
| -rw-r--r-- | go.mod | 3 |
2 files changed, 104 insertions, 0 deletions
diff --git a/cache.go b/cache.go new file mode 100644 index 0000000..887f672 --- /dev/null +++ b/cache.go @@ -0,0 +1,101 @@ +package cache + +import ( + "fmt" + "log/slog" + "time" +) + +type Cache struct { + items map[string]*CacheItem +} + +type CacheItem struct { + Value interface{} + CreatedAt time.Time +} + +// Create a new Cache object with no auto expiration. +func New() *Cache { + slog.Debug("") + + return &Cache{ + items: make(map[string]*CacheItem), + } +} + +// Get the age of a cached item. +func (this *Cache) Age(key string) time.Duration { + item, ok := this.items[key] + + if !ok { + return 0 + } + + return time.Since(item.CreatedAt) +} + +// Delete an item from the cache. +func (this *Cache) Delete(key string) { + delete(this.items, key) +} + +// Delete all items older than the given duration. +func (this *Cache) Expire(duration time.Duration) uint { + var counter uint = 0 + + for key, item := range this.items { + if time.Since(item.CreatedAt) < duration { + continue + } + + slog.Debug( + "Expiring", + "package", "cache", + "type", "Cache", + "func", "GetSet", + "key", key, + "value", fmt.Sprintf("%+v", item.Value), + "age", this.Age(key), + ) + + this.Delete(key) + counter++ + } + + return counter +} + +// Get the value of a cached item. +func (this *Cache) Get(key string) interface{} { + item, ok := this.items[key] + + if !ok { + return nil + } + + return item.Value +} + +// Get or set a cache item in a single statement. +func (this *Cache) GetSet(key string, f func() interface{}) interface{} { + value := this.Get(key) + + if value != nil { + slog.Debug("Cache hit", "package", "cache", "type", "Cache", "func", "GetSet", "age", this.Age(key), "value", fmt.Sprintf("%+v", value)) + return value + } + + slog.Debug("Cache miss", "package", "cache", "type", "Cache", "func", "GetSet") + this.Set(key, f()) + + return this.Get(key) +} + +// Set a cached value. +func (this *Cache) Set(key string, value interface{}) { + this.items[key] = &CacheItem{ + Value: value, + CreatedAt: time.Now(), + } +} @@ -0,0 +1,3 @@ +module git.tyil.nl/go/cache.git + +go 1.22.6 |
