caching | kvutils | sandbox: Use a size-based cache for LF value translation. (#6432)

* caching: Split caches into new files.

* caching: Rename `Cache.from` to `WeightedCache.from`.

* caching: Move `Configuration` inside `WeightedCache`.

* caching: Add test cases.

* caching: Allow for Caffeine builders to be covariant.

* caching: When instrumenting the Caffeine cache, compose, don't inherit.

* caching: Add a size-based cache.

* caching: Extract out common test cases into base classes.

* caching: Use the size-based cache for LF value translation.

CHANGELOG_BEGIN
CHANGELOG_END

* caching: Simplify the eviction tests.

* caching: Increase the encapsulation in CaffeineCache.

* caching: Commas are important.

Co-authored-by: Stefano Baghino <43749967+stefanobaghino-da@users.noreply.github.com>

Co-authored-by: Stefano Baghino <43749967+stefanobaghino-da@users.noreply.github.com>
This commit is contained in:
Samir Talwar 2020-06-19 16:42:40 +02:00 committed by GitHub
parent ec8c209b65
commit 6496ddd903
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 410 additions and 152 deletions

View File

@ -4,6 +4,7 @@
load(
"//bazel_tools:scala.bzl",
"da_scala_library",
"da_scala_test_suite",
)
da_scala_library(
@ -20,3 +21,24 @@ da_scala_library(
"@maven//:org_scala_lang_modules_scala_java8_compat_2_12",
],
)
da_scala_library(
name = "caching-test-lib",
srcs = glob(["src/test/lib/scala/**/*.scala"]),
deps = [
":caching",
"@maven//:org_scalactic_scalactic_2_12",
"@maven//:org_scalatest_scalatest_2_12",
],
)
da_scala_test_suite(
name = "caching-tests",
srcs = glob(["src/test/suite/scala/**/*.scala"]),
deps = [
":caching",
":caching-test-lib",
"@maven//:org_scalactic_scalactic_2_12",
"@maven//:org_scalatest_scalatest_2_12",
],
)

View File

@ -3,13 +3,7 @@
package com.daml.caching
import com.codahale.metrics.Gauge
import com.daml.metrics.CacheMetrics
import com.github.benmanes.caffeine.{cache => caffeine}
import scala.compat.java8.OptionConverters._
sealed abstract class Cache[Key, Value] {
abstract class Cache[Key, Value] {
def put(key: Key, value: Value): Unit
def get(key: Key, acquire: Key => Value): Value
@ -23,79 +17,4 @@ object Cache {
def none[Key, Value]: Cache[Key, Value] = new NoCache
def from[Key <: AnyRef: Weight, Value <: AnyRef: Weight](
configuration: Configuration,
): Cache[Key, Value] =
from(configuration, None)
def from[Key <: AnyRef: Weight, Value <: AnyRef: Weight](
configuration: Configuration,
metrics: CacheMetrics,
): Cache[Key, Value] =
from(configuration, Some(metrics))
private def from[Key <: AnyRef: Weight, Value <: AnyRef: Weight](
configuration: Configuration,
metrics: Option[CacheMetrics],
): Cache[Key, Value] =
configuration match {
case Configuration(maximumWeight) if maximumWeight <= 0 =>
none
case Configuration(maximumWeight) =>
val builder =
caffeine.Caffeine
.newBuilder()
.maximumWeight(maximumWeight)
.weigher(Weight.weigher[Key, Value])
metrics.fold(new CaffeineCache(builder))(new InstrumentedCaffeineCache(builder, _))
}
final class NoCache[Key, Value] private[Cache] extends Cache[Key, Value] {
override def put(key: Key, value: Value): Unit = ()
override def get(key: Key, acquire: Key => Value): Value = acquire(key)
override def getIfPresent(key: Key): Option[Value] = None
}
sealed class CaffeineCache[Key, Value] private[Cache] (builder: caffeine.Caffeine[Key, Value])
extends Cache[Key, Value] {
private val cache = init(builder)
protected def init(builder: caffeine.Caffeine[Key, Value]): caffeine.Cache[Key, Value] =
builder.build()
override def put(key: Key, value: Value): Unit = cache.put(key, value)
override def get(key: Key, acquire: Key => Value): Value =
cache.get(key, key => acquire(key))
override def getIfPresent(key: Key): Option[Value] =
Option(cache.getIfPresent(key))
}
private def size(cache: caffeine.Cache[_, _]): Gauge[Long] =
() => cache.estimatedSize()
private def weight(cache: caffeine.Cache[_, _]): Gauge[Long] =
() => cache.policy().eviction().asScala.flatMap(_.weightedSize.asScala).getOrElse(0)
final class InstrumentedCaffeineCache[Key, Value] private[Cache] (
builder: caffeine.Caffeine[Key, Value],
metrics: CacheMetrics,
) extends CaffeineCache[Key, Value](builder) {
override protected def init(
builder: caffeine.Caffeine[Key, Value],
): caffeine.Cache[Key, Value] = {
val cache = super.init(builder.recordStats(() => new DropwizardStatsCounter(metrics)))
metrics.registerSizeGauge(size(cache))
metrics.registerWeightGauge(weight(cache))
cache
}
}
}

View File

@ -0,0 +1,56 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
import com.daml.metrics.CacheMetrics
import com.github.benmanes.caffeine.{cache => caffeine}
import scala.compat.java8.OptionConverters._
object CaffeineCache {
def apply[Key <: AnyRef, Value <: AnyRef](
builder: caffeine.Caffeine[_ >: Key, _ >: Value],
metrics: Option[CacheMetrics],
): Cache[Key, Value] = {
val cache = builder.build[Key, Value]
metrics match {
case None => new SimpleCaffeineCache(cache)
case Some(metrics) => new InstrumentedCaffeineCache(cache, metrics)
}
}
private final class SimpleCaffeineCache[Key <: AnyRef, Value <: AnyRef](
cache: caffeine.Cache[Key, Value],
) extends Cache[Key, Value] {
override def put(key: Key, value: Value): Unit = cache.put(key, value)
override def get(key: Key, acquire: Key => Value): Value =
cache.get(key, key => acquire(key))
override def getIfPresent(key: Key): Option[Value] =
Option(cache.getIfPresent(key))
}
private final class InstrumentedCaffeineCache[Key <: AnyRef, Value <: AnyRef](
cache: caffeine.Cache[Key, Value],
metrics: CacheMetrics,
) extends Cache[Key, Value] {
metrics.registerSizeGauge(() => cache.estimatedSize())
metrics.registerWeightGauge(() =>
cache.policy().eviction().asScala.flatMap(_.weightedSize.asScala).getOrElse(0))
private val delegate = new SimpleCaffeineCache(cache)
override def get(key: Key, acquire: Key => Value): Value =
delegate.get(key, acquire)
override def getIfPresent(key: Key): Option[Value] =
delegate.getIfPresent(key)
override def put(key: Key, value: Value): Unit =
delegate.put(key, value)
}
}

View File

@ -1,12 +0,0 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
final case class Configuration(maximumWeight: Long) extends AnyVal
object Configuration {
val none: Configuration = Configuration(maximumWeight = 0)
}

View File

@ -0,0 +1,12 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
final class NoCache[Key, Value] private[caching] extends Cache[Key, Value] {
override def put(key: Key, value: Value): Unit = ()
override def get(key: Key, acquire: Key => Value): Value = acquire(key)
override def getIfPresent(key: Key): Option[Value] = None
}

View File

@ -0,0 +1,42 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
import com.daml.metrics.CacheMetrics
import com.github.benmanes.caffeine.{cache => caffeine}
object SizedCache {
def from[Key <: AnyRef, Value <: AnyRef](configuration: Configuration): Cache[Key, Value] =
from(configuration, None)
def from[Key <: AnyRef, Value <: AnyRef](
configuration: Configuration,
metrics: CacheMetrics,
): Cache[Key, Value] =
from(configuration, Some(metrics))
private def from[Key <: AnyRef, Value <: AnyRef](
configuration: Configuration,
metrics: Option[CacheMetrics],
): Cache[Key, Value] =
configuration match {
case Configuration(maximumSize) if maximumSize <= 0 =>
Cache.none
case Configuration(maximumSize) =>
val builder = caffeine.Caffeine
.newBuilder()
.maximumSize(maximumSize)
CaffeineCache[Key, Value](builder, metrics)
}
final case class Configuration(maximumSize: Long) extends AnyVal
object Configuration {
val none: Configuration = Configuration(maximumSize = 0)
}
}

View File

@ -0,0 +1,46 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
import com.daml.metrics.CacheMetrics
import com.github.benmanes.caffeine.{cache => caffeine}
object WeightedCache {
def from[Key <: AnyRef: Weight, Value <: AnyRef: Weight](
configuration: Configuration,
): Cache[Key, Value] =
from(configuration, None)
def from[Key <: AnyRef: Weight, Value <: AnyRef: Weight](
configuration: Configuration,
metrics: CacheMetrics,
): Cache[Key, Value] =
from(configuration, Some(metrics))
private def from[Key <: AnyRef: Weight, Value <: AnyRef: Weight](
configuration: Configuration,
metrics: Option[CacheMetrics],
): Cache[Key, Value] =
configuration match {
case Configuration(maximumWeight) if maximumWeight <= 0 =>
Cache.none
case Configuration(maximumWeight) =>
val builder =
caffeine.Caffeine
.newBuilder()
.maximumWeight(maximumWeight)
.weigher(Weight.weigher[Key, Value])
CaffeineCache(builder, metrics)
}
final case class Configuration(maximumWeight: Long) extends AnyVal
object Configuration {
val none: Configuration = Configuration(maximumWeight = 0)
}
}

View File

@ -0,0 +1,21 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
import org.scalatest.{Matchers, WordSpec}
abstract class CacheBehaviorSpecBase(name: String) extends WordSpec with Matchers {
protected def newCache(): Cache[Integer, String]
name should {
"compute the correct results" in {
val cache = newCache()
cache.get(1, _.toString) should be("1")
cache.get(2, _.toString) should be("2")
cache.get(3, _.toString) should be("3")
cache.get(2, _.toString) should be("2")
}
}
}

View File

@ -0,0 +1,57 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
import java.util.concurrent.atomic.AtomicInteger
abstract class CacheSpecBase(name: String) extends CacheBehaviorSpecBase(name) {
name should {
"compute once, and cache" in {
val cache = newCache()
val counter = new AtomicInteger(0)
def compute(value: Integer): String = {
counter.incrementAndGet()
value.toString
}
cache.get(1, compute)
cache.get(1, compute)
cache.get(1, compute)
cache.get(2, compute)
counter.get() should be(2)
}
"return `None` on `getIfPresent` if the value is not present" in {
val cache = newCache()
cache.getIfPresent(7) should be(None)
}
"return the value on `getIfPresent` if the value is present" in {
val cache = newCache()
cache.get(7, _.toString) should be("7")
cache.getIfPresent(7) should be(Some("7"))
}
"`put` values" in {
val cache = newCache()
cache.put(7, "7")
cache.getIfPresent(7) should be(Some("7"))
val counter = new AtomicInteger(0)
def compute(value: Integer): String = {
counter.incrementAndGet()
value.toString
}
cache.get(7, compute) should be("7")
counter.get() should be(0)
}
}
}

View File

@ -0,0 +1,55 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
import java.util.concurrent.atomic.AtomicInteger
class NoCacheSpec extends CacheBehaviorSpecBase("a non-existent cache") {
override protected def newCache(): Cache[Integer, String] =
Cache.none
"a non-existent cache" should {
"compute every time" in {
val cache = newCache()
val counter = new AtomicInteger(0)
def compute(value: Integer): String = {
counter.incrementAndGet()
value.toString
}
cache.get(1, compute)
cache.get(1, compute)
cache.get(1, compute)
cache.get(2, compute)
counter.get() should be(4)
}
"always return `None` on `getIfPresent`" in {
val cache = Cache.none[Integer, String]
cache.getIfPresent(7) should be(None)
cache.get(7, _.toString) should be("7")
cache.getIfPresent(7) should be(None)
}
"do nothing on `put`" in {
val cache = Cache.none[Integer, String]
cache.put(7, "7")
cache.getIfPresent(7) should be(None)
val counter = new AtomicInteger(0)
def compute(value: Integer): String = {
counter.incrementAndGet()
value.toString
}
cache.get(7, compute) should be("7")
counter.get() should be(1)
}
}
}

View File

@ -0,0 +1,26 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
import scala.util.Random
class SizedCacheSpec extends CacheSpecBase("a sized cache") {
override protected def newCache(): Cache[Integer, String] =
SizedCache.from[Integer, String](SizedCache.Configuration(maximumSize = 16))
"a sized cache" should {
"evict values eventually, once the size limit has been reached" in {
val cache =
SizedCache.from[Integer, String](SizedCache.Configuration(maximumSize = 256))
val values = Iterator.continually[Integer](Random.nextInt).take(1000).toSet.toVector
values.foreach { value =>
cache.get(value, _.toString)
}
val cachedValues = values.map(cache.getIfPresent).filter(_.isDefined)
cachedValues.length should (be > 16 and be < 500)
}
}
}

View File

@ -0,0 +1,29 @@
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
package com.daml.caching
import scala.util.Random
class WeightedCacheSpec extends CacheSpecBase("a weighted cache") {
implicit val `Int Weight`: Weight[Integer] = (_: Integer) => 1
implicit val `String Weight`: Weight[String] = _.length.toLong
override protected def newCache(): Cache[Integer, String] =
WeightedCache.from[Integer, String](WeightedCache.Configuration(maximumWeight = 16))
"a weighted cache" should {
"evict values eventually, once the weight limit has been reached" in {
val cache =
WeightedCache.from[Integer, String](WeightedCache.Configuration(maximumWeight = 256))
val values = Iterator.continually[Integer](Random.nextInt).take(1000).toSet.toVector
values.foreach { value =>
cache.get(value, _.toString)
}
val cachedValues = values.map(cache.getIfPresent).filter(_.isDefined)
cachedValues.length should (be > 16 and be < 500)
}
}
}

View File

@ -68,7 +68,7 @@ object Main {
config.extra.batchingLedgerWriterConfig,
participantId = participantConfig.participantId,
metrics = metrics,
stateValueCache = caching.Cache.from(
stateValueCache = caching.WeightedCache.from(
configuration = config.stateValueCache,
metrics = metrics.daml.kvutils.submission.validator.stateValueCache,
),

View File

@ -70,7 +70,7 @@ object SqlLedgerFactory extends LedgerFactory[ReadWriteService, ExtraConfig] {
metrics = metrics,
engine,
jdbcUrl,
stateValueCache = caching.Cache.from(
stateValueCache = caching.WeightedCache.from(
configuration = config.stateValueCache,
metrics = metrics.daml.kvutils.submission.validator.stateValueCache,
),

View File

@ -25,9 +25,9 @@ final case class Config[Extra](
participants: Seq[ParticipantConfig],
maxInboundMessageSize: Int,
eventsPageSize: Int,
stateValueCache: caching.Configuration,
lfValueTranslationEventCache: caching.Configuration,
lfValueTranslationContractCache: caching.Configuration,
stateValueCache: caching.WeightedCache.Configuration,
lfValueTranslationEventCache: caching.SizedCache.Configuration,
lfValueTranslationContractCache: caching.SizedCache.Configuration,
seeding: Seeding,
metricsReporter: Option[MetricsReporter],
metricsReportingInterval: Duration,
@ -65,9 +65,9 @@ object Config {
participants = Vector.empty,
maxInboundMessageSize = DefaultMaxInboundMessageSize,
eventsPageSize = IndexConfiguration.DefaultEventsPageSize,
stateValueCache = caching.Configuration.none,
lfValueTranslationEventCache = caching.Configuration.none,
lfValueTranslationContractCache = caching.Configuration.none,
stateValueCache = caching.WeightedCache.Configuration.none,
lfValueTranslationEventCache = caching.SizedCache.Configuration.none,
lfValueTranslationContractCache = caching.SizedCache.Configuration.none,
seeding = Seeding.Strong,
metricsReporter = None,
metricsReportingInterval = Duration.ofSeconds(10),
@ -176,9 +176,9 @@ object Config {
.action((maximumLfValueTranslationCacheEntries, config) =>
config.copy(
lfValueTranslationEventCache = config.lfValueTranslationEventCache.copy(
maximumWeight = maximumLfValueTranslationCacheEntries),
maximumSize = maximumLfValueTranslationCacheEntries),
lfValueTranslationContractCache = config.lfValueTranslationContractCache.copy(
maximumWeight = maximumLfValueTranslationCacheEntries),
maximumSize = maximumLfValueTranslationCacheEntries),
))
private val seedingMap =

View File

@ -3,7 +3,7 @@
package com.daml.ledger.validator.caching
import com.daml.caching.{Cache, Configuration}
import com.daml.caching.{Cache, WeightedCache}
import com.daml.ledger.participant.state.kvutils.DamlKvutils.{
DamlLogEntry,
DamlLogEntryId,
@ -51,7 +51,7 @@ class CachingCommitStrategySpec extends AsyncWordSpec with Matchers with Mockito
}
private def newCache(): Cache[DamlStateKey, DamlStateValue] =
Cache.from[DamlStateKey, DamlStateValue](Configuration(1024))
WeightedCache.from[DamlStateKey, DamlStateValue](WeightedCache.Configuration(1024))
private def createInstance(
cache: Cache[DamlStateKey, DamlStateValue],

View File

@ -3,7 +3,7 @@
package com.daml.ledger.validator.caching
import com.daml.caching.{Cache, Configuration}
import com.daml.caching.WeightedCache
import com.daml.ledger.participant.state.kvutils.DamlKvutils.{DamlStateKey, DamlStateValue}
import com.daml.ledger.participant.state.kvutils.caching.`Message Weight`
import com.daml.ledger.validator.{DamlLedgerStateReader, DefaultStateKeySerializationStrategy}
@ -81,7 +81,7 @@ class CachingDamlLedgerStateReaderSpec
private def newInstance(damlLedgerStateReader: DamlLedgerStateReader, shouldCache: Boolean)(
implicit executionContext: ExecutionContext): CachingDamlLedgerStateReader = {
val cache = Cache.from[DamlStateKey, DamlStateValue](Configuration(1024))
val cache = WeightedCache.from[DamlStateKey, DamlStateValue](WeightedCache.Configuration(1024))
new CachingDamlLedgerStateReader(
cache,
_ => shouldCache,

View File

@ -290,10 +290,10 @@ object Cli {
config.copy(
lfValueTranslationEventCacheConfiguration =
config.lfValueTranslationEventCacheConfiguration
.copy(maximumWeight = maximumLfValueTranslationCacheEntries),
.copy(maximumSize = maximumLfValueTranslationCacheEntries),
lfValueTranslationContractCacheConfiguration =
config.lfValueTranslationContractCacheConfiguration
.copy(maximumWeight = maximumLfValueTranslationCacheEntries)
.copy(maximumSize = maximumLfValueTranslationCacheEntries)
)
)

View File

@ -8,7 +8,7 @@ import java.nio.file.Path
import java.time.Duration
import ch.qos.logback.classic.Level
import com.daml.caching
import com.daml.caching.SizedCache
import com.daml.ledger.api.auth.AuthService
import com.daml.ledger.api.tls.TlsConfiguration
import com.daml.ledger.participant.state.v1.SeedService.Seeding
@ -41,8 +41,8 @@ final case class SandboxConfig(
metricsReporter: Option[MetricsReporter],
metricsReportingInterval: Duration,
eventsPageSize: Int,
lfValueTranslationEventCacheConfiguration: caching.Configuration,
lfValueTranslationContractCacheConfiguration: caching.Configuration,
lfValueTranslationEventCacheConfiguration: SizedCache.Configuration,
lfValueTranslationContractCacheConfiguration: SizedCache.Configuration,
profileDir: Option[Path],
)
@ -55,7 +55,8 @@ object SandboxConfig {
val DefaultTimeProviderType: TimeProviderType = TimeProviderType.WallClock
val DefaultLfValueTranslationCacheConfiguration = caching.Configuration.none
val DefaultLfValueTranslationCacheConfiguration: SizedCache.Configuration =
SizedCache.Configuration.none
lazy val nextDefault: SandboxConfig =
SandboxConfig(

View File

@ -142,8 +142,8 @@ class Runner(config: SandboxConfig) extends ResourceOwner[Port] {
resetOnStartup = isReset,
timeProvider = timeServiceBackend.getOrElse(TimeProvider.UTC),
seedService = SeedService(seeding),
stateValueCache = caching.Cache.from(
caching.Configuration(
stateValueCache = caching.WeightedCache.from(
caching.WeightedCache.Configuration(
maximumWeight = MaximumStateValueCacheSize,
)),
engine = engine

View File

@ -5,9 +5,9 @@ package com.daml.platform.store.dao.events
import anorm.NamedParameter
import com.daml.caching
import com.daml.ledger.api.v1.value.{Record => ApiRecord, Value => ApiValue}
import com.daml.ledger.EventId
import com.daml.ledger.api.v1.event.{CreatedEvent, ExercisedEvent}
import com.daml.ledger.api.v1.value.{Record => ApiRecord, Value => ApiValue}
import com.daml.metrics.Metrics
import com.daml.platform.participant.util.LfEngineToApi
import com.daml.platform.store.dao.events.{Value => LfValue}
@ -185,17 +185,19 @@ object LfValueTranslation {
def none: Cache = Cache(caching.Cache.none, caching.Cache.none)
def newInstance(
eventConfiguration: caching.Configuration,
contractConfiguration: caching.Configuration): Cache =
eventConfiguration: caching.SizedCache.Configuration,
contractConfiguration: caching.SizedCache.Configuration
): Cache =
Cache(
events = EventCache.newInstance(eventConfiguration),
contracts = ContractCache.newInstance(contractConfiguration),
)
def newInstrumentedInstance(
eventConfiguration: caching.Configuration,
contractConfiguration: caching.Configuration,
metrics: Metrics): Cache =
eventConfiguration: caching.SizedCache.Configuration,
contractConfiguration: caching.SizedCache.Configuration,
metrics: Metrics
): Cache =
Cache(
events = EventCache.newInstrumentedInstance(eventConfiguration, metrics),
contracts = ContractCache.newInstrumentedInstance(contractConfiguration, metrics),
@ -204,23 +206,14 @@ object LfValueTranslation {
object EventCache {
private implicit object `Key Weight` extends caching.Weight[Key] {
override def weigh(value: Key): caching.Cache.Size =
0 // make sure that only the value is counted
}
private implicit object `Value Weight` extends caching.Weight[Value] {
override def weigh(value: Value): caching.Cache.Size =
1 // TODO replace this with something to avoid weights entirely
}
def newInstance(configuration: caching.Configuration): EventCache =
caching.Cache.from(configuration)
def newInstance(configuration: caching.SizedCache.Configuration): EventCache =
caching.SizedCache.from(configuration)
def newInstrumentedInstance(
configuration: caching.Configuration,
metrics: Metrics): EventCache =
caching.Cache.from(
configuration: caching.SizedCache.Configuration,
metrics: Metrics
): EventCache =
caching.SizedCache.from(
configuration = configuration,
metrics = metrics.daml.index.db.translation.cache,
)
@ -250,23 +243,14 @@ object LfValueTranslation {
object ContractCache {
private implicit object `Key Weight` extends caching.Weight[Key] {
override def weigh(value: Key): caching.Cache.Size =
0 // make sure that only the value is counted
}
private implicit object `Value Weight` extends caching.Weight[Value] {
override def weigh(value: Value): caching.Cache.Size =
1 // TODO replace this with something to avoid weights entirely
}
def newInstance(configuration: caching.Configuration): ContractCache =
caching.Cache.from(configuration)
def newInstance(configuration: caching.SizedCache.Configuration): ContractCache =
caching.SizedCache.from(configuration)
def newInstrumentedInstance(
configuration: caching.Configuration,
metrics: Metrics): ContractCache =
caching.Cache.from(
configuration: caching.SizedCache.Configuration,
metrics: Metrics
): ContractCache =
caching.SizedCache.from(
configuration = configuration,
metrics = metrics.daml.index.db.translation.cache,
)