Skip to content

Instantly share code, notes, and snippets.

@pellse
Created September 10, 2019 02:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pellse/940fed6998da93347e12166cb570e473 to your computer and use it in GitHub Desktop.
Save pellse/940fed6998da93347e12166cb570e473 to your computer and use it in GitHub Desktop.
import java.util.concurrent.ConcurrentHashMap
import kotlin.LazyThreadSafetyMode.SYNCHRONIZED
object NoParamKey
data class K2<T1, T2>(val k1: T1, val k2: T2)
data class K3<T1, T2, T3>(val k1: T1, val k2: T2, val k3: T3)
data class K4<T1, T2, T3, T4>(val k1: T1, val k2: T2, val k3: T3, val k4: T4)
data class K5<T1, T2, T3, T4, T5>(val k1: T1, val k2: T2, val k3: T3, val k4: T4, val k5: T5)
data class K6<T1, T2, T3, T4, T5, T6>(val k1: T1, val k2: T2, val k3: T3, val k4: T4, val k5: T5, val k6: T6)
data class K7<T1, T2, T3, T4, T5, T6, T7>(val k1: T1, val k2: T2, val k3: T3, val k4: T4, val k5: T5, val k6: T6, val k7: T7)
data class K8<T1, T2, T3, T4, T5, T6, T7, T8>(val k1: T1, val k2: T2, val k3: T3, val k4: T4, val k5: T5, val k6: T6, val k7: T7, val k8: T8)
data class K9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(val k1: T1, val k2: T2, val k3: T3, val k4: T4, val k5: T5, val k6: T6, val k7: T7, val k8: T8, val k9: T9)
data class K10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(val k1: T1, val k2: T2, val k3: T3, val k4: T4, val k5: T5, val k6: T6, val k7: T7, val k8: T8, val k9: T9, val k10: T10)
typealias CacheInitializer<T, R> = (T) -> R
typealias Cache<T, R> = (T, CacheInitializer<T, R>) -> R
class DefaultCache<T, R>(mapSupplier: () -> MutableMap<T, R> = ::ConcurrentHashMap) : Cache<T, R> {
private val delegateCache: MutableMap<T, R> = mapSupplier()
override fun invoke(key: T, cacheInitializer: CacheInitializer<T, R>): R = delegateCache.computeIfAbsent(key, cacheInitializer)
}
fun <R> (() -> R).lazy(mode: LazyThreadSafetyMode = SYNCHRONIZED): () -> R = object : () -> R {
private val cache: R by lazy(mode, this@lazy)
override fun invoke() = cache
}
fun <R> (() -> R).memoized(cache: Cache<NoParamKey, R> = DefaultCache()): () -> R =
{ cache(NoParamKey) { this() } }
fun <T1, R> ((T1) -> R).memoized(cache: Cache<T1, R> = DefaultCache()): (T1) -> R =
{ p1 -> cache(p1, this) }
fun <T1, T2, R> ((T1, T2) -> R).memoized(cache: Cache<K2<T1, T2>, R> = DefaultCache()): (T1, T2) -> R =
{ p1, p2 -> cache(K2(p1, p2)) { (k1, k2) -> this(k1, k2) } }
fun <T1, T2, T3, R> ((T1, T2, T3) -> R).memoized(cache: Cache<K3<T1, T2, T3>, R> = DefaultCache()): (T1, T2, T3) -> R =
{ p1, p2, p3 -> cache(K3(p1, p2, p3)) { (k1, k2, k3) -> this(k1, k2, k3) } }
fun <T1, T2, T3, T4, R> ((T1, T2, T3, T4) -> R).memoized(cache: Cache<K4<T1, T2, T3, T4>, R> = DefaultCache()): (T1, T2, T3, T4) -> R =
{ p1, p2, p3, p4 -> cache(K4(p1, p2, p3, p4)) { (k1, k2, k3, k4) -> this(k1, k2, k3, k4) } }
fun <T1, T2, T3, T4, T5, R> ((T1, T2, T3, T4, T5) -> R).memoized(cache: Cache<K5<T1, T2, T3, T4, T5>, R> = DefaultCache()): (T1, T2, T3, T4, T5) -> R =
{ p1, p2, p3, p4, p5 -> cache(K5(p1, p2, p3, p4, p5)) { (k1, k2, k3, k4, k5) -> this(k1, k2, k3, k4, k5) } }
fun <T1, T2, T3, T4, T5, T6, R> ((T1, T2, T3, T4, T5, T6) -> R).memoized(cache: Cache<K6<T1, T2, T3, T4, T5, T6>, R> = DefaultCache()): (T1, T2, T3, T4, T5, T6) -> R =
{ p1, p2, p3, p4, p5, p6 -> cache(K6(p1, p2, p3, p4, p5, p6)) { (k1, k2, k3, k4, k5, k6) -> this(k1, k2, k3, k4, k5, k6) } }
fun <T1, T2, T3, T4, T5, T6, T7, R> ((T1, T2, T3, T4, T5, T6, T7) -> R).memoized(cache: Cache<K7<T1, T2, T3, T4, T5, T6, T7>, R> = DefaultCache()): (T1, T2, T3, T4, T5, T6, T7) -> R =
{ p1, p2, p3, p4, p5, p6, p7 -> cache(K7(p1, p2, p3, p4, p5, p6, p7)) { (k1, k2, k3, k4, k5, k6, k7) -> this(k1, k2, k3, k4, k5, k6, k7) } }
fun <T1, T2, T3, T4, T5, T6, T7, T8, R> ((T1, T2, T3, T4, T5, T6, T7, T8) -> R).memoized(cache: Cache<K8<T1, T2, T3, T4, T5, T6, T7, T8>, R> = DefaultCache()): (T1, T2, T3, T4, T5, T6, T7, T8) -> R =
{ p1, p2, p3, p4, p5, p6, p7, p8 -> cache(K8(p1, p2, p3, p4, p5, p6, p7, p8)) { (k1, k2, k3, k4, k5, k6, k7, k8) -> this(k1, k2, k3, k4, k5, k6, k7, k8) } }
fun <T1, T2, T3, T4, T5, T6, T7, T8, T9, R> ((T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R).memoized(cache: Cache<K9<T1, T2, T3, T4, T5, T6, T7, T8, T9>, R> = DefaultCache()): (T1, T2, T3, T4, T5, T6, T7, T8, T9) -> R =
{ p1, p2, p3, p4, p5, p6, p7, p8, p9 -> cache(K9(p1, p2, p3, p4, p5, p6, p7, p8, p9)) { (k1, k2, k3, k4, k5, k6, k7, k8, k9) -> this(k1, k2, k3, k4, k5, k6, k7, k8, k9) } }
fun <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> ((T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R).memoized(cache: Cache<K10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>, R> = DefaultCache()): (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R =
{ p1, p2, p3, p4, p5, p6, p7, p8, p9, p10 -> cache(K10(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)) { (k1, k2, k3, k4, k5, k6, k7, k8, k9, k10) -> this(k1, k2, k3, k4, k5, k6, k7, k8, k9, k10) } }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment