From 96dc32fdeffddfe96f56af520503f7dbadf55221 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurkevich Date: Fri, 8 May 2020 19:29:44 +0300 Subject: [PATCH] [workspace model] Not expose PId outside of the store via external index GitOrigin-RevId: a568520d76ab4126290c02c6b939e5264a88e880 --- .../api/pstorage/ExternalEntityIndexTest.kt | 94 +++++++++---------- .../src/pstorage/PEntityStorage.kt | 13 ++- .../pstorage/external/ExternalEntityIndex.kt | 39 +++++++- 3 files changed, 90 insertions(+), 56 deletions(-) diff --git a/platform/workspaceModel-core-tests/test/com/intellij/workspace/api/pstorage/ExternalEntityIndexTest.kt b/platform/workspaceModel-core-tests/test/com/intellij/workspace/api/pstorage/ExternalEntityIndexTest.kt index c0911ebb1706..1ffd3174e5c8 100644 --- a/platform/workspaceModel-core-tests/test/com/intellij/workspace/api/pstorage/ExternalEntityIndexTest.kt +++ b/platform/workspaceModel-core-tests/test/com/intellij/workspace/api/pstorage/ExternalEntityIndexTest.kt @@ -16,19 +16,19 @@ class ExternalEntityIndexTest { val index = builder.getOrCreateExternalIndex(INDEX_ID) val entity = builder.addPSourceEntity("hello", PSampleEntitySource("source")) - index.index(entity.id, 1) - index.index(entity.id, 2) - assertEquals(2, index.getDataById(entity.id)) - index.remove(entity.id) - assertNull(index.getDataById(entity.id)) - index.update(entity.id, 3) - assertEquals(3, index.getDataById(entity.id)) + index.index(entity, 1) + index.index(entity, 2) + assertEquals(2, index.getDataById(entity)) + index.remove(entity) + assertNull(index.getDataById(entity)) + index.update(entity, 3) + assertEquals(3, index.getDataById(entity)) val storage = builder.toStorage() val newIndex = storage.getExternalIndex(INDEX_ID) assertNotNull(newIndex) - assertEquals(3, newIndex!!.getDataById(entity.id)) - assertEquals(entity.id, newIndex.getIds(3)?.get(0)) + assertEquals(3, newIndex!!.getDataById(entity)) + assertEquals(entity, newIndex.getIds(3)?.get(0)) } @Test @@ -37,26 +37,26 @@ class ExternalEntityIndexTest { val index = builder.getOrCreateExternalIndex(INDEX_ID) val entity = builder.addPSourceEntity("hello", PSampleEntitySource("source")) - index.index(entity.id, 1) - assertEquals(1, index.getDataById(entity.id)) + index.index(entity, 1) + assertEquals(1, index.getDataById(entity)) val diff = PEntityStorageBuilder.from(builder.toStorage()) val externalIndex = diff.getExternalIndex(INDEX_ID) assertNotNull(externalIndex) assertNotEquals(index, externalIndex) - assertEquals(1, externalIndex!!.getDataById(entity.id)) - externalIndex.update(entity.id, 2) - assertEquals(1, index.getDataById(entity.id)) - assertEquals(2, externalIndex.getDataById(entity.id)) + assertEquals(1, externalIndex!!.getDataById(entity)) + externalIndex.update(entity, 2) + assertEquals(1, index.getDataById(entity)) + assertEquals(2, externalIndex.getDataById(entity)) builder.addDiff(diff) - assertEquals(2, index.getDataById(entity.id)) + assertEquals(2, index.getDataById(entity)) val storage = builder.toStorage() val newIndex = storage.getExternalIndex(INDEX_ID) assertNotNull(newIndex) assertNotEquals(index, newIndex) - assertEquals(2, newIndex!!.getDataById(entity.id)) + assertEquals(2, newIndex!!.getDataById(entity)) } @Test @@ -65,26 +65,26 @@ class ExternalEntityIndexTest { val index = builder.getOrCreateExternalIndex(INDEX_ID) val entity = builder.addPSourceEntity("hello", PSampleEntitySource("source")) - index.index(entity.id, 1) - assertEquals(1, index.getDataById(entity.id)) + index.index(entity, 1) + assertEquals(1, index.getDataById(entity)) val diff = PEntityStorageBuilder.from(builder.toStorage()) val externalIndex = diff.getExternalIndex(INDEX_ID) assertNotNull(externalIndex) assertNotEquals(index, externalIndex) - assertEquals(1, externalIndex!!.getDataById(entity.id)) - externalIndex.remove(entity.id) - assertEquals(1, index.getDataById(entity.id)) - assertNull(externalIndex.getDataById(entity.id)) + assertEquals(1, externalIndex!!.getDataById(entity)) + externalIndex.remove(entity) + assertEquals(1, index.getDataById(entity)) + assertNull(externalIndex.getDataById(entity)) builder.addDiff(diff) - assertNull(index.getDataById(entity.id)) + assertNull(index.getDataById(entity)) val storage = builder.toStorage() val newIndex = storage.getExternalIndex(INDEX_ID) assertNotNull(newIndex) assertNotEquals(index, newIndex) - assertNull(newIndex!!.getDataById(entity.id)) + assertNull(newIndex!!.getDataById(entity)) } @Test @@ -93,32 +93,32 @@ class ExternalEntityIndexTest { val index = builder.getOrCreateExternalIndex(INDEX_ID) val entity = builder.addPSourceEntity("hello", PSampleEntitySource("source")) - index.index(entity.id, 1) - assertEquals(1, index.getDataById(entity.id)) + index.index(entity, 1) + assertEquals(1, index.getDataById(entity)) val diff = PEntityStorageBuilder.from(builder.toStorage()) val newEntity = builder.addPSourceEntity("world", PSampleEntitySource("source")) val externalIndex = diff.getExternalIndex(INDEX_ID) assertNotNull(externalIndex) assertNotEquals(index, externalIndex) - assertEquals(1, externalIndex!!.getDataById(entity.id)) - externalIndex.update(newEntity.id, 2) - assertEquals(1, index.getDataById(entity.id)) - assertEquals(1, externalIndex.getDataById(entity.id)) - assertEquals(2, externalIndex.getDataById(newEntity.id)) + assertEquals(1, externalIndex!!.getDataById(entity)) + externalIndex.update(newEntity, 2) + assertEquals(1, index.getDataById(entity)) + assertEquals(1, externalIndex.getDataById(entity)) + assertEquals(2, externalIndex.getDataById(newEntity)) builder.addDiff(diff) - assertEquals(1, index.getDataById(entity.id)) - assertEquals(2, index.getDataById(newEntity.id)) + assertEquals(1, index.getDataById(entity)) + assertEquals(2, index.getDataById(newEntity)) val storage = builder.toStorage() val newIndex = storage.getExternalIndex(INDEX_ID) assertNotNull(newIndex) assertNotEquals(index, newIndex) - assertEquals(1, newIndex!!.getDataById(entity.id)) - assertEquals(2, newIndex.getDataById(newEntity.id)) - assertEquals(entity.id, newIndex.getIds(1)?.get(0)) - assertEquals(newEntity.id, newIndex.getIds(2)?.get(0)) + assertEquals(1, newIndex!!.getDataById(entity)) + assertEquals(2, newIndex.getDataById(newEntity)) + assertEquals(entity, newIndex.getIds(1)?.get(0)) + assertEquals(newEntity, newIndex.getIds(2)?.get(0)) } @Test @@ -127,16 +127,16 @@ class ExternalEntityIndexTest { val index = builder.getOrCreateExternalIndex(INDEX_ID) val entity = builder.addPSourceEntity("hello", PSampleEntitySource("source")) - index.index(entity.id, 1) - assertEquals(1, index.getDataById(entity.id)) + index.index(entity, 1) + assertEquals(1, index.getDataById(entity)) val diff = PEntityStorageBuilder.from(builder.toStorage()) diff.removeExternalIndex(INDEX_ID) assertNull(diff.getExternalIndex(INDEX_ID)) - assertEquals(1, index.getDataById(entity.id)) + assertEquals(1, index.getDataById(entity)) builder.addDiff(diff) - assertEquals(1, index.getDataById(entity.id)) + assertEquals(1, index.getDataById(entity)) assertNull(builder.getExternalIndex(INDEX_ID)) val storage = builder.toStorage() @@ -152,21 +152,21 @@ class ExternalEntityIndexTest { val diff = PEntityStorageBuilder.from(builder.toStorage()) val index = diff.getOrCreateExternalIndex(INDEX_ID) - index.index(entity.id, 1) + index.index(entity, 1) assertNull(builder.getExternalIndex(INDEX_ID)) - assertEquals(1, index.getDataById(entity.id)) + assertEquals(1, index.getDataById(entity)) builder.addDiff(diff) - assertEquals(1, index.getDataById(entity.id)) + assertEquals(1, index.getDataById(entity)) val entityIndex = builder.getExternalIndex(INDEX_ID) assertNotNull(entityIndex) assertNotEquals(index, entityIndex) - assertEquals(1, entityIndex!!.getDataById(entity.id)) + assertEquals(1, entityIndex!!.getDataById(entity)) val storage = builder.toStorage() val newIndex = storage.getExternalIndex(INDEX_ID) assertNotNull(newIndex) assertNotEquals(entityIndex, newIndex) - assertEquals(1, newIndex!!.getDataById(entity.id)) + assertEquals(1, newIndex!!.getDataById(entity)) } } \ No newline at end of file diff --git a/platform/workspaceModel-core/src/pstorage/PEntityStorage.kt b/platform/workspaceModel-core/src/pstorage/PEntityStorage.kt index 51bcdf176ef8..3f75ccf11131 100644 --- a/platform/workspaceModel-core/src/pstorage/PEntityStorage.kt +++ b/platform/workspaceModel-core/src/pstorage/PEntityStorage.kt @@ -766,13 +766,16 @@ internal class PEntityStorageBuilder( @Suppress("UNCHECKED_CAST") fun getOrCreateExternalIndex(identifier: String): MutableExternalEntityIndex { - return externalIndices.computeIfAbsent(identifier) { MutableExternalEntityIndex() } - as MutableExternalEntityIndex + val index = externalIndices.computeIfAbsent(identifier) { MutableExternalEntityIndex() } as MutableExternalEntityIndex + index.setTypedEntityStorage(this) + return index } @Suppress("UNCHECKED_CAST") override fun getExternalIndex(identifier: String): MutableExternalEntityIndex? { - return externalIndices[identifier] as? MutableExternalEntityIndex + val index = externalIndices[identifier] as? MutableExternalEntityIndex + index?.setTypedEntityStorage(this) + return index } @Suppress("UNCHECKED_CAST") @@ -977,7 +980,9 @@ internal sealed class AbstractPEntityStorage : TypedEntityStorage { @Suppress("UNCHECKED_CAST") open fun getExternalIndex(identifier: String): ExternalEntityIndex? { - return externalIndices[identifier] as? ExternalEntityIndex + val index = externalIndices[identifier] as? ExternalEntityIndex + index?.setTypedEntityStorage(this) + return index } } diff --git a/platform/workspaceModel-core/src/pstorage/external/ExternalEntityIndex.kt b/platform/workspaceModel-core/src/pstorage/external/ExternalEntityIndex.kt index fd3c3bce3463..6e12b7ce7cfe 100644 --- a/platform/workspaceModel-core/src/pstorage/external/ExternalEntityIndex.kt +++ b/platform/workspaceModel-core/src/pstorage/external/ExternalEntityIndex.kt @@ -3,14 +3,28 @@ package com.intellij.workspace.api.pstorage.external import com.intellij.util.containers.BidirectionalMap import com.intellij.workspace.api.TypedEntity +import com.intellij.workspace.api.pstorage.AbstractPEntityStorage import com.intellij.workspace.api.pstorage.PId +import com.intellij.workspace.api.pstorage.PTypedEntity import com.intellij.workspace.api.pstorage.external.ExternalEntityIndex.MutableExternalEntityIndex.IndexLogRecord.Add import com.intellij.workspace.api.pstorage.external.ExternalEntityIndex.MutableExternalEntityIndex.IndexLogRecord.Remove import java.util.* open class ExternalEntityIndex private constructor(internal val index: BidirectionalMap, T>) { - internal fun getIds(data: T): List>? = index.getKeysByValue(data) - internal fun getDataById(id: PId): T? = index[id] + private var entityStorage: AbstractPEntityStorage? = null + internal fun getIds(data: T): List? { + val storage = entityStorage ?: return null + return index.getKeysByValue(data)?.toMutableList()?.mapNotNull { storage.entityDataById(it)?.createEntity(storage) } + } + + internal fun getDataById(entity: TypedEntity): T? { + entity as PTypedEntity + return index[entity.id] + } + + internal fun setTypedEntityStorage(storage: AbstractPEntityStorage) { + entityStorage = storage + } internal fun copyIndex(): BidirectionalMap, T> { val copy = BidirectionalMap, T>() @@ -24,17 +38,32 @@ open class ExternalEntityIndex private constructor(internal val index: Bidire ) : ExternalEntityIndex(index) { constructor() : this(BidirectionalMap, T>(), mutableListOf()) - internal fun index(id: PId, data: T) { + internal fun index(entity: TypedEntity, data: T) { + entity as PTypedEntity + index(entity.id, data) + } + + private fun index(id: PId, data: T) { index[id] = data indexLog.add(Add(id, data)) } - internal fun update(id: PId, newData: T) { + internal fun update(entity: TypedEntity, newData: T) { + entity as PTypedEntity + update(entity.id, newData) + } + + private fun update(id: PId, newData: T) { remove(id) index(id, newData) } - internal fun remove(id: PId) { + internal fun remove(entity: TypedEntity) { + entity as PTypedEntity + remove(entity.id) + } + + private fun remove(id: PId) { index.remove(id) indexLog.add(Remove(id)) }