From 5c4ac7f1f9a51e408a088aa3c93cae184c0be6ae Mon Sep 17 00:00:00 2001
From: Tordarus <tordarus@protonmail.com>
Date: Wed, 28 May 2025 20:38:22 +0200
Subject: [PATCH] added helper functions with 4 parameters

---
 utils.go | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 210 insertions(+), 2 deletions(-)

diff --git a/utils.go b/utils.go
index 884e020..55ddba8 100644
--- a/utils.go
+++ b/utils.go
@@ -62,6 +62,31 @@ func CacheFunc13[K1 comparable, V1, V2, V3 any](ctx context.Context, cacheDurati
 	}
 }
 
+func CacheFunc14[K1 comparable, V1, V2, V3, V4 any](ctx context.Context, cacheDuration, cleanUpInterval time.Duration, f func(K1) (V1, V2, V3, V4)) func(K1) (V1, V2, V3, V4) {
+	type Value struct {
+		Value1 V1
+		Value2 V2
+		Value3 V3
+		Value4 V4
+	}
+
+	cacheMap := NewSelfCleaning[K1, Value](ctx, cacheDuration, cleanUpInterval)
+	return func(key K1) (V1, V2, V3, V4) {
+		if value, ok := cacheMap.Get(key); ok {
+			return value.Value1, value.Value2, value.Value3, value.Value4
+		}
+
+		value1, value2, value3, value4 := f(key)
+		cacheMap.Put(key, Value{
+			Value1: value1,
+			Value2: value2,
+			Value3: value3,
+			Value4: value4,
+		})
+		return value1, value2, value3, value4
+	}
+}
+
 func CacheFunc21[K1, K2 comparable, V1 any](ctx context.Context, cacheDuration, cleanUpInterval time.Duration, f func(K1, K2) V1) func(K1, K2) V1 {
 	type Key struct {
 		Key1 K1
@@ -140,6 +165,38 @@ func CacheFunc23[K1, K2 comparable, V1, V2, V3 any](ctx context.Context, cacheDu
 	}
 }
 
+func CacheFunc24[K1, K2 comparable, V1, V2, V3, V4 any](ctx context.Context, cacheDuration, cleanUpInterval time.Duration, f func(K1, K2) (V1, V2, V3, V4)) func(K1, K2) (V1, V2, V3, V4) {
+	type Key struct {
+		Key1 K1
+		Key2 K2
+	}
+
+	type Value struct {
+		Value1 V1
+		Value2 V2
+		Value3 V3
+		Value4 V4
+	}
+
+	cacheMap := NewSelfCleaning[Key, Value](ctx, cacheDuration, cleanUpInterval)
+	return func(key1 K1, key2 K2) (V1, V2, V3, V4) {
+		key := Key{Key1: key1, Key2: key2}
+
+		if value, ok := cacheMap.Get(key); ok {
+			return value.Value1, value.Value2, value.Value3, value.Value4
+		}
+
+		value1, value2, value3, value4 := f(key1, key2)
+		cacheMap.Put(key, Value{
+			Value1: value1,
+			Value2: value2,
+			Value3: value3,
+			Value4: value4,
+		})
+		return value1, value2, value3, value4
+	}
+}
+
 func CacheFunc31[K1, K2, K3 comparable, V1 any](ctx context.Context, cacheDuration, cleanUpInterval time.Duration, f func(K1, K2, K3) V1) func(K1, K2, K3) V1 {
 	type Key struct {
 		Key1 K1
@@ -175,7 +232,7 @@ func CacheFunc32[K1, K2, K3 comparable, V1, V2 any](ctx context.Context, cacheDu
 
 	cacheMap := NewSelfCleaning[Key, Value](ctx, cacheDuration, cleanUpInterval)
 	return func(key1 K1, key2 K2, key3 K3) (V1, V2) {
-		key := Key{Key1: key1, Key2: key2}
+		key := Key{Key1: key1, Key2: key2, Key3: key3}
 
 		if value, ok := cacheMap.Get(key); ok {
 			return value.Value1, value.Value2
@@ -205,7 +262,7 @@ func CacheFunc33[K1, K2, K3 comparable, V1, V2, V3 any](ctx context.Context, cac
 
 	cacheMap := NewSelfCleaning[Key, Value](ctx, cacheDuration, cleanUpInterval)
 	return func(key1 K1, key2 K2, key3 K3) (V1, V2, V3) {
-		key := Key{Key1: key1, Key2: key2}
+		key := Key{Key1: key1, Key2: key2, Key3: key3}
 
 		if value, ok := cacheMap.Get(key); ok {
 			return value.Value1, value.Value2, value.Value3
@@ -220,3 +277,154 @@ func CacheFunc33[K1, K2, K3 comparable, V1, V2, V3 any](ctx context.Context, cac
 		return value1, value2, value3
 	}
 }
+
+func CacheFunc34[K1, K2, K3 comparable, V1, V2, V3, V4 any](ctx context.Context, cacheDuration, cleanUpInterval time.Duration, f func(K1, K2, K3) (V1, V2, V3, V4)) func(K1, K2, K3) (V1, V2, V3, V4) {
+	type Key struct {
+		Key1 K1
+		Key2 K2
+		Key3 K3
+	}
+
+	type Value struct {
+		Value1 V1
+		Value2 V2
+		Value3 V3
+		Value4 V4
+	}
+
+	cacheMap := NewSelfCleaning[Key, Value](ctx, cacheDuration, cleanUpInterval)
+	return func(key1 K1, key2 K2, key3 K3) (V1, V2, V3, V4) {
+		key := Key{Key1: key1, Key2: key2, Key3: key3}
+
+		if value, ok := cacheMap.Get(key); ok {
+			return value.Value1, value.Value2, value.Value3, value.Value4
+		}
+
+		value1, value2, value3, value4 := f(key1, key2, key3)
+		cacheMap.Put(key, Value{
+			Value1: value1,
+			Value2: value2,
+			Value3: value3,
+			Value4: value4,
+		})
+		return value1, value2, value3, value4
+	}
+}
+
+func CacheFunc41[K1, K2, K3, K4 comparable, V1 any](ctx context.Context, cacheDuration, cleanUpInterval time.Duration, f func(K1, K2, K3, K4) V1) func(K1, K2, K3, K4) V1 {
+	type Key struct {
+		Key1 K1
+		Key2 K2
+		Key3 K3
+		Key4 K4
+	}
+
+	cacheMap := NewSelfCleaning[Key, V1](ctx, cacheDuration, cleanUpInterval)
+	return func(key1 K1, key2 K2, key3 K3, key4 K4) V1 {
+		key := Key{Key1: key1, Key2: key2, Key3: key3, Key4: key4}
+
+		if value, ok := cacheMap.Get(key); ok {
+			return value
+		}
+
+		value := f(key1, key2, key3, key4)
+		cacheMap.Put(key, value)
+		return value
+	}
+}
+
+func CacheFunc42[K1, K2, K3, K4 comparable, V1, V2 any](ctx context.Context, cacheDuration, cleanUpInterval time.Duration, f func(K1, K2, K3, K4) (V1, V2)) func(K1, K2, K3, K4) (V1, V2) {
+	type Key struct {
+		Key1 K1
+		Key2 K2
+		Key3 K3
+		Key4 K4
+	}
+
+	type Value struct {
+		Value1 V1
+		Value2 V2
+	}
+
+	cacheMap := NewSelfCleaning[Key, Value](ctx, cacheDuration, cleanUpInterval)
+	return func(key1 K1, key2 K2, key3 K3, key4 K4) (V1, V2) {
+		key := Key{Key1: key1, Key2: key2, Key3: key3, Key4: key4}
+
+		if value, ok := cacheMap.Get(key); ok {
+			return value.Value1, value.Value2
+		}
+
+		value1, value2 := f(key1, key2, key3, key4)
+		cacheMap.Put(key, Value{
+			Value1: value1,
+			Value2: value2,
+		})
+		return value1, value2
+	}
+}
+
+func CacheFunc43[K1, K2, K3, K4 comparable, V1, V2, V3 any](ctx context.Context, cacheDuration, cleanUpInterval time.Duration, f func(K1, K2, K3, K4) (V1, V2, V3)) func(K1, K2, K3, K4) (V1, V2, V3) {
+	type Key struct {
+		Key1 K1
+		Key2 K2
+		Key3 K3
+		Key4 K4
+	}
+
+	type Value struct {
+		Value1 V1
+		Value2 V2
+		Value3 V3
+	}
+
+	cacheMap := NewSelfCleaning[Key, Value](ctx, cacheDuration, cleanUpInterval)
+	return func(key1 K1, key2 K2, key3 K3, key4 K4) (V1, V2, V3) {
+		key := Key{Key1: key1, Key2: key2, Key3: key3, Key4: key4}
+
+		if value, ok := cacheMap.Get(key); ok {
+			return value.Value1, value.Value2, value.Value3
+		}
+
+		value1, value2, value3 := f(key1, key2, key3, key4)
+		cacheMap.Put(key, Value{
+			Value1: value1,
+			Value2: value2,
+			Value3: value3,
+		})
+		return value1, value2, value3
+	}
+}
+
+func CacheFunc44[K1, K2, K3, K4 comparable, V1, V2, V3, V4 any](ctx context.Context, cacheDuration, cleanUpInterval time.Duration, f func(K1, K2, K3, K4) (V1, V2, V3, V4)) func(K1, K2, K3, K4) (V1, V2, V3, V4) {
+	type Key struct {
+		Key1 K1
+		Key2 K2
+		Key3 K3
+		Key4 K4
+	}
+
+	type Value struct {
+		Value1 V1
+		Value2 V2
+		Value3 V3
+		Value4 V4
+	}
+
+	cacheMap := NewSelfCleaning[Key, Value](ctx, cacheDuration, cleanUpInterval)
+	return func(key1 K1, key2 K2, key3 K3, key4 K4) (V1, V2, V3, V4) {
+		key := Key{Key1: key1, Key2: key2, Key3: key3, Key4: key4}
+
+		if value, ok := cacheMap.Get(key); ok {
+			return value.Value1, value.Value2, value.Value3, value.Value4
+		}
+
+		value1, value2, value3, value4 := f(key1, key2, key3, key4)
+		cacheMap.Put(key, Value{
+			Value1: value1,
+			Value2: value2,
+			Value3: value3,
+			Value4: value4,
+		})
+		return value1, value2, value3, value4
+	}
+}