From 375288539efdde4859817de99fa5f4afe51d795d Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Tue, 28 Mar 2023 20:43:13 +0200 Subject: [PATCH] [LL FIR] Add `NullableCaffeineCache` - `NullableCaffeineCache` wraps a Caffeine cache and allows storing `null` values returned by the computation in the form of explicit `NullValue`s in the cache. --- .../api/fir/caches/NullableCaffeineCache.kt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/caches/NullableCaffeineCache.kt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/caches/NullableCaffeineCache.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/caches/NullableCaffeineCache.kt new file mode 100644 index 00000000000..d4279ea21d2 --- /dev/null +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/caches/NullableCaffeineCache.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.low.level.api.fir.caches + +import com.github.benmanes.caffeine.cache.Cache +import com.github.benmanes.caffeine.cache.Caffeine +import org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.NullValue +import org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.nullValueToNull + +/** + * A wrapper around a Caffeine [Cache] which stores `null` values returned by the computation in the form of explicit [NullValue]s. On a + * conceptual level, this allows the cache to store failures so that future accesses to the same key don't recompute the same failure. + */ +internal class NullableCaffeineCache(configure: (Caffeine) -> Caffeine) { + private val cache: Cache = configure(Caffeine.newBuilder()).build() + + /** + * Returns the value for the given [key] if it's contained in the cache, or computes the value with [compute] and adds it to the cache. + */ + fun get(key: K, compute: (K) -> V?): V? = cache.get(key) { compute(it) ?: NullValue }?.nullValueToNull() +}