2009-10-18 04:40:02 +02:00
|
|
|
package xsbt.boot
|
|
|
|
|
|
2010-01-28 00:22:42 +01:00
|
|
|
import java.lang.ref.{Reference, SoftReference}
|
2009-10-18 04:40:02 +02:00
|
|
|
import java.util.HashMap
|
|
|
|
|
|
2009-10-19 04:25:50 +02:00
|
|
|
final class Cache[K,V](create: K => V) extends NotNull
|
2009-10-18 04:40:02 +02:00
|
|
|
{
|
2010-01-28 00:22:42 +01:00
|
|
|
private[this] val delegate = new HashMap[K,Reference[V]]
|
2009-10-18 04:40:02 +02:00
|
|
|
def apply(k: K): V =
|
|
|
|
|
{
|
2010-01-28 00:22:42 +01:00
|
|
|
val existingRef = delegate.get(k)
|
|
|
|
|
if(existingRef == null)
|
|
|
|
|
newEntry(k)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
val existing = existingRef.get
|
|
|
|
|
if(existing == null)
|
|
|
|
|
{
|
|
|
|
|
println("Cache value for '" + k + "' was garbage collected, recreating it...")
|
|
|
|
|
newEntry(k)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
existing
|
|
|
|
|
}
|
2009-10-18 04:40:02 +02:00
|
|
|
}
|
|
|
|
|
private[this] def newEntry(k: K): V =
|
|
|
|
|
{
|
|
|
|
|
val v = create(k)
|
2009-10-19 04:25:50 +02:00
|
|
|
Pre.assert(v != null, "Value for key " + k + " was null")
|
2010-01-28 00:22:42 +01:00
|
|
|
delegate.put(k, new SoftReference(v))
|
2009-10-18 04:40:02 +02:00
|
|
|
v
|
|
|
|
|
}
|
2009-10-19 04:25:50 +02:00
|
|
|
}
|