From 90f7a06e754c7350fcee898b40d105a90c0b0c92 Mon Sep 17 00:00:00 2001 From: Nikita Katkov Date: Thu, 22 Feb 2024 17:10:30 +0100 Subject: [PATCH] [json] IJ-CR-124164 Support concurrent properties map modification via employing atomic reference paired with a persistent map GitOrigin-RevId: 6129515c562ae2fd1f9df79d6919f3baa93d4d5e --- .../JsonSchemaObjectBackedByJacksonBase.kt | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/json/src/com/jetbrains/jsonSchema/impl/light/nodes/JsonSchemaObjectBackedByJacksonBase.kt b/json/src/com/jetbrains/jsonSchema/impl/light/nodes/JsonSchemaObjectBackedByJacksonBase.kt index abdc570b4b16..7f42f2a46a9f 100644 --- a/json/src/com/jetbrains/jsonSchema/impl/light/nodes/JsonSchemaObjectBackedByJacksonBase.kt +++ b/json/src/com/jetbrains/jsonSchema/impl/light/nodes/JsonSchemaObjectBackedByJacksonBase.kt @@ -14,6 +14,7 @@ import com.jetbrains.jsonSchema.impl.light.legacy.JsonSchemaObjectReadingUtils import com.jetbrains.jsonSchema.impl.light.legacy.isOldParserAwareOfFieldName import com.jetbrains.jsonSchema.impl.light.legacy.tryReadEnumMetadata import java.util.* +import java.util.concurrent.atomic.AtomicReference private val ONE_OF_KEY = Key>("oneOf") private val ANY_OF_KEY = Key>("anyOf") @@ -31,13 +32,24 @@ internal abstract class JsonSchemaObjectBackedByJacksonBase( abstract fun getRootSchemaObject(): RootJsonSchemaObjectBackedByJackson - private var myCompositeObjectsCache = KeyFMap.EMPTY_MAP + private var myCompositeObjectsCache = AtomicReference(KeyFMap.EMPTY_MAP) protected fun getOrComputeValue(key: Key, computation: () -> V): V { - val existingValue = myCompositeObjectsCache.get(key) - if (existingValue != null) return existingValue - val newValue = computation() - myCompositeObjectsCache = myCompositeObjectsCache.plus(key, newValue) + var existingMap: KeyFMap + var newValue: V? + + do { + existingMap = myCompositeObjectsCache.get() + newValue = existingMap[key] + if (newValue == null) { + val mapWithNewValue = existingMap.plus(key, computation()) + if (myCompositeObjectsCache.compareAndSet(existingMap, mapWithNewValue)) { + newValue = mapWithNewValue.get(key) + } + } + } + while (newValue == null) + return newValue }