summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Spek <p.spek@tyil.nl>2024-12-08 08:16:03 +0100
committerPatrick Spek <p.spek@tyil.nl>2024-12-08 08:16:03 +0100
commit125410025f74a765292d1711871b25b1ccf933f8 (patch)
tree95a06806af6e8a29ccbf9eb6b21d0cda562e6261
downloadcache-125410025f74a765292d1711871b25b1ccf933f8.tar.gz
cache-125410025f74a765292d1711871b25b1ccf933f8.tar.bz2
Initial commitHEADmaster
-rw-r--r--cache.go101
-rw-r--r--go.mod3
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(),
+ }
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..1136c4c
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module git.tyil.nl/go/cache.git
+
+go 1.22.6