diff --git a/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/StorageIndexes.kt b/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/StorageIndexes.kt index e0d89890f0dd..79880684f1d4 100644 --- a/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/StorageIndexes.kt +++ b/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/StorageIndexes.kt @@ -136,6 +136,18 @@ internal class MutableStorageIndexes( persistentIdIndex.index(entityId) } + fun simpleUpdateSoftReferences(copiedData: WorkspaceEntityData) { + val pid = copiedData.createPid() + if (copiedData is SoftLinkable) { + val beforeSoftLinks = HashSet(this.softLinks.getKeys(pid)) + val afterSoftLinks = copiedData.getLinks() + if (beforeSoftLinks != afterSoftLinks) { + beforeSoftLinks.forEach { this.softLinks.remove(it, pid) } + afterSoftLinks.forEach { this.softLinks.put(it, pid) } + } + } + } + @OptIn(ExperimentalStdlibApi::class) fun updateSoftReferences(beforePersistentId: PersistentEntityId<*>?, copiedData: WorkspaceEntityData, diff --git a/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/WorkspaceEntityStorageImpl.kt b/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/WorkspaceEntityStorageImpl.kt index a789c7db1a7b..f872649886dc 100644 --- a/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/WorkspaceEntityStorageImpl.kt +++ b/platform/workspaceModel/storage/src/com/intellij/workspaceModel/storage/impl/WorkspaceEntityStorageImpl.kt @@ -121,15 +121,11 @@ internal class WorkspaceEntityStorageBuilderImpl( } // Add an entry to changelog - val pid = e.id - val parents = this.refs.getParentRefsOfChild(pid) - val children = this.refs.getChildrenRefsOfParentBy(pid) - updateChangeLog { it.add(ChangeEntry.ReplaceEntity(copiedData, children, parents)) } + addReplaceChange(copiedData) val updatedEntity = copiedData.createEntity(this) - if (updatedEntity is WorkspaceEntityWithPersistentId) indexes.persistentIdIndex.index(pid, updatedEntity.persistentId()) - indexes.updateSoftReferences(beforePersistentId, copiedData, this) + updatePersistentIdIndexes(updatedEntity, beforePersistentId, copiedData) // Assert consistency this.assertConsistencyInStrictMode() @@ -137,6 +133,41 @@ internal class WorkspaceEntityStorageBuilderImpl( return updatedEntity } + private fun updatePersistentIdIndexes(updatedEntity: WorkspaceEntity, + beforePersistentId: PersistentEntityId<*>?, + copiedData: WorkspaceEntityData) { + val pid = (updatedEntity as WorkspaceEntityBase).id + if (updatedEntity is WorkspaceEntityWithPersistentId) { + val newPersistentId = updatedEntity.persistentId() + if (beforePersistentId != null && beforePersistentId != newPersistentId) { + indexes.persistentIdIndex.index(pid, newPersistentId) + updateComposedIds(beforePersistentId, newPersistentId) + } + } + indexes.simpleUpdateSoftReferences(copiedData) + } + + private fun updateComposedIds(beforePersistentId: PersistentEntityId<*>, newPersistentId: PersistentEntityId<*> ) { + val idsWithSoftRef = HashSet(indexes.softLinks.getValues(beforePersistentId)) + for (entityId in idsWithSoftRef) { + val entity = this.entitiesByType.getEntityDataForModification(entityId) + val editingBeforePersistentId = entity.persistentId(this) + (entity as SoftLinkable).updateLink(beforePersistentId, newPersistentId, ArrayList()) + + // Add an entry to changelog + addReplaceChange(entity) + + updatePersistentIdIndexes(entity.createEntity(this), editingBeforePersistentId, entity) + } + } + + private fun addReplaceChange(entity: WorkspaceEntityData<*>) { + val pid = entity.createPid() + val parents = this.refs.getParentRefsOfChild(pid) + val children = this.refs.getChildrenRefsOfParentBy(pid) + updateChangeLog { it.add(ChangeEntry.ReplaceEntity(entity, children, parents)) } + } + override fun changeSource(e: T, newSource: EntitySource): T { val copiedData = entitiesByType.getEntityDataForModification((e as WorkspaceEntityBase).id) as WorkspaceEntityData copiedData.entitySource = newSource