Ensure caching uses weak references for both keys and values

This commit is contained in:
Matt Dziuban 2025-06-07 23:39:22 -04:00 committed by Eugene Yokota
parent c41c259189
commit 882a10a89f
1 changed files with 7 additions and 7 deletions

View File

@ -1,8 +1,8 @@
package lmcoursier.internal package lmcoursier.internal
import java.io.File import java.io.File
import java.util.GregorianCalendar import java.lang.ref.WeakReference
import java.util.concurrent.ConcurrentHashMap import java.util.{ Collections, GregorianCalendar, WeakHashMap }
import coursier.cache.CacheUrl import coursier.cache.CacheUrl
import coursier.{ Attributes, Dependency, Module, Project, Resolution } import coursier.{ Attributes, Dependency, Module, Project, Resolution }
import coursier.core.{ Classifier, Configuration, Extension, Info, Publication, Type } import coursier.core.{ Classifier, Configuration, Extension, Info, Publication, Type }
@ -18,16 +18,16 @@ private[internal] object SbtUpdateReport {
private def caching[K, V](f: K => V): K => V = { private def caching[K, V](f: K => V): K => V = {
val cache = new ConcurrentHashMap[K, V] val cache = Collections.synchronizedMap(new WeakHashMap[K, WeakReference[V]])
key => key =>
val previousValueOpt = Option(cache.get(key)) val previousValueOpt = Option(cache.get(key))
previousValueOpt.getOrElse { previousValueOpt.fold {
val value = f(key) val value = f(key)
val concurrentValueOpt = Option(cache.putIfAbsent(key, value)) val concurrentValueOpt = Option(cache.putIfAbsent(key, new WeakReference(value)))
concurrentValueOpt.getOrElse(value) concurrentValueOpt.fold(value)(_.get())
} }(_.get())
} }
private def infoProperties(project: Project): Seq[(String, String)] = private def infoProperties(project: Project): Seq[(String, String)] =