ENT-9837 Use a cache to avoid resolving contract class name for a contract state repeatedly. (#7348)

This commit is contained in:
Rick Parker 2023-04-26 12:34:57 +01:00 committed by GitHub
parent 32326a168f
commit f4917e08e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 9 deletions

View File

@ -82,6 +82,7 @@ def patchCore = tasks.register('patchCore', Zip) {
exclude 'net/corda/core/serialization/internal/CheckpointSerializationFactory*.class' exclude 'net/corda/core/serialization/internal/CheckpointSerializationFactory*.class'
exclude 'net/corda/core/internal/rules/*.class' exclude 'net/corda/core/internal/rules/*.class'
exclude 'net/corda/core/internal/utilities/PrivateInterner*.class' exclude 'net/corda/core/internal/utilities/PrivateInterner*.class'
exclude 'net/corda/core/internal/ContractStateClassCache*.class'
} }
reproducibleFileOrder = true reproducibleFileOrder = true

View File

@ -0,0 +1,16 @@
package net.corda.core.internal
import net.corda.core.contracts.ContractState
@Suppress("unused")
object ContractStateClassCache {
@Suppress("UNUSED_PARAMETER")
fun contractClassName(key: Class<ContractState>): String? {
return null
}
@Suppress("UNUSED_PARAMETER")
fun cacheContractClassName(key: Class<ContractState>, contractClassName: String?): String? {
return contractClassName
}
}

View File

@ -28,16 +28,20 @@ val Attachment.contractVersion: Version get() = if (this is ContractAttachment)
* one and it inherits from [Contract]. * one and it inherits from [Contract].
*/ */
val ContractState.requiredContractClassName: String? get() { val ContractState.requiredContractClassName: String? get() {
return ContractStateClassCache.contractClassName(this.javaClass) ?: let {
val annotation = javaClass.getAnnotation(BelongsToContract::class.java) val annotation = javaClass.getAnnotation(BelongsToContract::class.java)
if (annotation != null) { val className = if (annotation != null) {
return annotation.value.java.typeName.removePrefix(DJVM_SANDBOX_PREFIX) annotation.value.java.typeName.removePrefix(DJVM_SANDBOX_PREFIX)
} } else {
val enclosingClass = javaClass.enclosingClass ?: return null val enclosingClass = javaClass.enclosingClass ?: return null
return if (Contract::class.java.isAssignableFrom(enclosingClass)) { if (Contract::class.java.isAssignableFrom(enclosingClass)) {
enclosingClass.typeName.removePrefix(DJVM_SANDBOX_PREFIX) enclosingClass.typeName.removePrefix(DJVM_SANDBOX_PREFIX)
} else { } else {
null null
} }
}
ContractStateClassCache.cacheContractClassName(this.javaClass, className)
}
} }
/** /**

View File

@ -0,0 +1,18 @@
package net.corda.core.internal
import com.google.common.collect.MapMaker
import net.corda.core.contracts.ContractState
object ContractStateClassCache {
private val classToString = MapMaker().weakKeys().makeMap<Class<*>, String>()
fun contractClassName(key: Class<ContractState>): String? {
return classToString[key]
}
fun cacheContractClassName(key: Class<ContractState>, contractClassName: String?): String? {
if (contractClassName == null) return null
classToString.putIfAbsent(key, contractClassName)
return contractClassName
}
}