mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 22:51:17 +07:00
CPP-40400: WorkspaceBuilderChangeLog: use persistent collections instead of immutable
GitOrigin-RevId: 5d8c98a6b165f8336c0126970a4fdc259430bc59
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c228ac9115
commit
bb4ea4e545
@@ -8,6 +8,7 @@ import com.intellij.platform.workspace.storage.ConnectionId
|
||||
import com.intellij.platform.workspace.storage.WorkspaceEntity
|
||||
import com.intellij.platform.workspace.storage.WorkspaceEntityWithSymbolicId
|
||||
import com.intellij.platform.workspace.storage.impl.exceptions.ApplyChangesFromException
|
||||
import kotlinx.collections.immutable.PersistentSet
|
||||
import java.util.*
|
||||
|
||||
internal class ApplyChangesFromOperation(val target: MutableEntityStorageImpl, val diff: MutableEntityStorageImpl) {
|
||||
@@ -223,7 +224,7 @@ internal class ApplyChangesFromOperation(val target: MutableEntityStorageImpl, v
|
||||
newEntityId: ParentEntityId,
|
||||
addedChildrenMap: MutableMap<ConnectionId, MutableList<ChildEntityId>>,
|
||||
removedChildrenMap: MutableMap<ConnectionId, MutableList<ChildEntityId>>,
|
||||
childrenOrdering: Map<ConnectionId, LinkedHashSet<ChildEntityId>>?,
|
||||
childrenOrdering: Map<ConnectionId, PersistentSet<ChildEntityId>>?,
|
||||
) {
|
||||
// Children from target store with connectionIds of affected references
|
||||
val existingChildrenOfAffectedIds: MutableMap<ConnectionId, List<ChildEntityId>> = HashMap()
|
||||
|
||||
@@ -8,8 +8,8 @@ import com.intellij.platform.diagnostic.telemetry.TelemetryManager
|
||||
import com.intellij.platform.diagnostic.telemetry.helpers.MillisecondsMeasurer
|
||||
import com.intellij.platform.workspace.storage.ConnectionId
|
||||
import com.intellij.platform.workspace.storage.WorkspaceEntity
|
||||
import com.intellij.util.containers.with
|
||||
import io.opentelemetry.api.metrics.Meter
|
||||
import kotlinx.collections.immutable.*
|
||||
|
||||
internal typealias ChangeLog = MutableMap<EntityId, ChangeEntry>
|
||||
|
||||
@@ -84,21 +84,21 @@ internal class WorkspaceBuilderChangeLog {
|
||||
val existingChange = changeLog[entityId]
|
||||
|
||||
val updateReplaceEvent = { replaceEntity: ChangeEntry.ReplaceEntity ->
|
||||
val newAddedParents: Map<ConnectionId, ParentEntityId> = if (replaceEntity.references != null) {
|
||||
val newAddedParents = if (replaceEntity.references != null) {
|
||||
if (!replaceEntity.references.newParents.contains(newConnectionId, newParentId)
|
||||
&& !replaceEntity.references.removedParents.contains(newConnectionId, newParentId)) {
|
||||
replaceEntity.references.newParents.toMutableMap().also { it[newConnectionId] = newParentId }
|
||||
replaceEntity.references.newParents.put(newConnectionId, newParentId)
|
||||
}
|
||||
else {
|
||||
replaceEntity.references.newParents
|
||||
}
|
||||
}
|
||||
else mapOf(newConnectionId to newParentId)
|
||||
else persistentHashMapOf(newConnectionId to newParentId)
|
||||
|
||||
val newRemovedParents = if (replaceEntity.references != null) {
|
||||
replaceEntity.references.removedParents.toMutableMap().also { it.remove(newConnectionId, newParentId) }
|
||||
replaceEntity.references.removedParents.remove(newConnectionId, newParentId)
|
||||
}
|
||||
else emptyMap()
|
||||
else persistentHashMapOf()
|
||||
|
||||
if (replaceEntity.references != null) {
|
||||
if (replaceEntity.references.newChildren.isEmpty() && replaceEntity.references.removedChildren.isEmpty() && replaceEntity.references.childrenOrdering.isEmpty() && newAddedParents.isEmpty() && newRemovedParents.isEmpty()) {
|
||||
@@ -115,7 +115,7 @@ internal class WorkspaceBuilderChangeLog {
|
||||
if (existingChange == null) {
|
||||
changeLog[entityId] = ChangeEntry.ReplaceEntity(
|
||||
null,
|
||||
ChangeEntry.ReplaceEntity.References(newParents = mapOf(newConnectionId to newParentId))
|
||||
ChangeEntry.ReplaceEntity.References(newParents = persistentHashMapOf(newConnectionId to newParentId))
|
||||
)
|
||||
}
|
||||
else {
|
||||
@@ -152,16 +152,16 @@ internal class WorkspaceBuilderChangeLog {
|
||||
val newRemovedParents = if (replaceEntity.references != null) {
|
||||
if (!replaceEntity.references.removedParents.contains(removedConnectionId, removedParentId)
|
||||
&& !replaceEntity.references.newParents.contains(removedConnectionId, removedParentId)) {
|
||||
replaceEntity.references.removedParents.toMutableMap().also { it[removedConnectionId] = removedParentId }
|
||||
replaceEntity.references.removedParents.put(removedConnectionId, removedParentId)
|
||||
}
|
||||
else replaceEntity.references.removedParents
|
||||
}
|
||||
else mapOf(removedConnectionId to removedParentId)
|
||||
else persistentHashMapOf(removedConnectionId to removedParentId)
|
||||
|
||||
val newAddedParents: Map<ConnectionId, ParentEntityId> = if (replaceEntity.references != null) {
|
||||
replaceEntity.references.newParents.toMutableMap().also { it.remove(removedConnectionId, removedParentId) }
|
||||
val newAddedParents = if (replaceEntity.references != null) {
|
||||
replaceEntity.references.newParents.remove(removedConnectionId, removedParentId)
|
||||
}
|
||||
else emptyMap()
|
||||
else persistentHashMapOf()
|
||||
|
||||
if (replaceEntity.references != null) {
|
||||
if (replaceEntity.references.newChildren.isEmpty() && replaceEntity.references.removedChildren.isEmpty() && replaceEntity.references.childrenOrdering.isEmpty() && newAddedParents.isEmpty() && newRemovedParents.isEmpty()) {
|
||||
@@ -178,7 +178,7 @@ internal class WorkspaceBuilderChangeLog {
|
||||
if (existingChange == null) {
|
||||
changeLog[entityId] = ChangeEntry.ReplaceEntity(
|
||||
null,
|
||||
ChangeEntry.ReplaceEntity.References(removedParents = mapOf(removedConnectionId to removedParentId))
|
||||
ChangeEntry.ReplaceEntity.References(removedParents = persistentHashMapOf(removedConnectionId to removedParentId))
|
||||
)
|
||||
}
|
||||
else {
|
||||
@@ -215,27 +215,24 @@ internal class WorkspaceBuilderChangeLog {
|
||||
val connectionToId = addedChildConnectionId to addedChildId
|
||||
val newAddedChildren = if (replaceEntity.references != null) {
|
||||
if (connectionToId !in replaceEntity.references.newChildren && connectionToId !in replaceEntity.references.removedChildren) {
|
||||
replaceEntity.references.newChildren + connectionToId
|
||||
replaceEntity.references.newChildren.add(connectionToId)
|
||||
}
|
||||
else {
|
||||
replaceEntity.references.newChildren
|
||||
}
|
||||
}
|
||||
else {
|
||||
setOf(connectionToId)
|
||||
persistentHashSetOf(connectionToId)
|
||||
}
|
||||
val newRemovedChildren = if (replaceEntity.references != null) {
|
||||
replaceEntity.references.removedChildren - connectionToId
|
||||
replaceEntity.references.removedChildren.remove(connectionToId)
|
||||
}
|
||||
else emptySet()
|
||||
else persistentHashSetOf()
|
||||
|
||||
val newOrder = if (replaceEntity.references != null) {
|
||||
val prevSet = replaceEntity.references.childrenOrdering.getOrElse(addedChildConnectionId) { LinkedHashSet() }
|
||||
val set = LinkedHashSet(prevSet)
|
||||
set.add(addedChildId)
|
||||
set
|
||||
replaceEntity.references.childrenOrdering.getOrElse(addedChildConnectionId) { persistentSetOf() }.add(addedChildId)
|
||||
} else {
|
||||
LinkedHashSet<ChildEntityId?>().also { it.add(addedChildId) }
|
||||
persistentSetOf(addedChildId)
|
||||
}
|
||||
|
||||
if (replaceEntity.references != null) {
|
||||
@@ -243,23 +240,23 @@ internal class WorkspaceBuilderChangeLog {
|
||||
if (replaceEntity.data == null) null else replaceEntity.copy(references = null)
|
||||
}
|
||||
else {
|
||||
val ordering = replaceEntity.references.childrenOrdering.with(addedChildConnectionId, newOrder)
|
||||
val ordering = replaceEntity.references.childrenOrdering.put(addedChildConnectionId, newOrder)
|
||||
replaceEntity.copy(
|
||||
references = replaceEntity.references.copy(newChildren = newAddedChildren, removedChildren = newRemovedChildren,
|
||||
childrenOrdering = ordering))
|
||||
}
|
||||
}
|
||||
else {
|
||||
val ordering = mapOf(addedChildConnectionId to newOrder)
|
||||
val ordering = persistentHashMapOf(addedChildConnectionId to newOrder)
|
||||
replaceEntity.copy(references = ChangeEntry.ReplaceEntity.References(newAddedChildren, newRemovedChildren, ordering))
|
||||
}
|
||||
}
|
||||
|
||||
if (existingChange == null) {
|
||||
val ordering = mapOf(addedChildConnectionId to LinkedHashSet<ChildEntityId>().also { it.add(addedChildId) })
|
||||
val ordering = persistentHashMapOf(addedChildConnectionId to persistentSetOf(addedChildId))
|
||||
changeLog[entityId] = ChangeEntry.ReplaceEntity(
|
||||
null,
|
||||
ChangeEntry.ReplaceEntity.References(setOf(addedChildConnectionId to addedChildId), emptySet(), ordering)
|
||||
ChangeEntry.ReplaceEntity.References(persistentHashSetOf(addedChildConnectionId to addedChildId), persistentHashSetOf(), ordering)
|
||||
)
|
||||
}
|
||||
else {
|
||||
@@ -297,26 +294,23 @@ internal class WorkspaceBuilderChangeLog {
|
||||
|
||||
val newRemovedChildren = if (replaceEntity.references != null) {
|
||||
if (connectionToId !in replaceEntity.references.removedChildren && connectionToId !in replaceEntity.references.newChildren) {
|
||||
replaceEntity.references.removedChildren + connectionToId
|
||||
replaceEntity.references.removedChildren.add(connectionToId)
|
||||
}
|
||||
else {
|
||||
replaceEntity.references.removedChildren
|
||||
}
|
||||
}
|
||||
else setOf(connectionToId)
|
||||
else persistentHashSetOf(connectionToId)
|
||||
|
||||
val newAddedChildren = if (replaceEntity.references != null) {
|
||||
replaceEntity.references.newChildren - connectionToId
|
||||
replaceEntity.references.newChildren.remove(connectionToId)
|
||||
}
|
||||
else emptySet()
|
||||
else persistentHashSetOf()
|
||||
|
||||
val newOrder = if (replaceEntity.references != null) {
|
||||
val prevSet = replaceEntity.references.childrenOrdering.getOrElse(removedChildConnectionId) { LinkedHashSet() }
|
||||
val set = LinkedHashSet(prevSet)
|
||||
set.remove(removedChildId)
|
||||
set
|
||||
replaceEntity.references.childrenOrdering.getOrElse(removedChildConnectionId) { persistentSetOf() }.remove(removedChildId)
|
||||
} else {
|
||||
LinkedHashSet<ChildEntityId?>()
|
||||
persistentSetOf()
|
||||
}
|
||||
|
||||
if (replaceEntity.references != null) {
|
||||
@@ -324,7 +318,7 @@ internal class WorkspaceBuilderChangeLog {
|
||||
if (replaceEntity.data == null) null else replaceEntity.copy(references = null)
|
||||
}
|
||||
else {
|
||||
val ordering = replaceEntity.references.childrenOrdering.with(removedChildConnectionId, newOrder)
|
||||
val ordering = replaceEntity.references.childrenOrdering.put(removedChildConnectionId, newOrder)
|
||||
replaceEntity.copy(references = replaceEntity.references.copy(
|
||||
newChildren = newAddedChildren,
|
||||
removedChildren = newRemovedChildren,
|
||||
@@ -333,16 +327,16 @@ internal class WorkspaceBuilderChangeLog {
|
||||
}
|
||||
}
|
||||
else {
|
||||
val ordering = mapOf(removedChildConnectionId to newOrder)
|
||||
val ordering = persistentHashMapOf(removedChildConnectionId to newOrder)
|
||||
replaceEntity.copy(references = ChangeEntry.ReplaceEntity.References(newAddedChildren, newRemovedChildren, ordering))
|
||||
}
|
||||
}
|
||||
|
||||
if (existingChange == null) {
|
||||
val ordering = mapOf(removedChildConnectionId to LinkedHashSet<ChildEntityId>())
|
||||
val ordering = persistentHashMapOf(removedChildConnectionId to persistentSetOf<ChildEntityId>())
|
||||
changeLog[entityId] = ChangeEntry.ReplaceEntity(
|
||||
null,
|
||||
ChangeEntry.ReplaceEntity.References(removedChildren = setOf(removedChildConnectionId to removedChildId), childrenOrdering = ordering)
|
||||
ChangeEntry.ReplaceEntity.References(removedChildren = persistentHashSetOf(removedChildConnectionId to removedChildId), childrenOrdering = ordering)
|
||||
)
|
||||
}
|
||||
else {
|
||||
@@ -531,11 +525,11 @@ internal sealed class ChangeEntry {
|
||||
)
|
||||
|
||||
data class References(
|
||||
val newChildren: Set<Pair<ConnectionId, ChildEntityId>> = emptySet(),
|
||||
val removedChildren: Set<Pair<ConnectionId, ChildEntityId>> = emptySet(),
|
||||
val childrenOrdering: Map<ConnectionId, LinkedHashSet<ChildEntityId>> = emptyMap(),
|
||||
val newParents: Map<ConnectionId, ParentEntityId> = emptyMap(),
|
||||
val removedParents: Map<ConnectionId, ParentEntityId> = emptyMap(),
|
||||
val newChildren: PersistentSet<Pair<ConnectionId, ChildEntityId>> = persistentHashSetOf(),
|
||||
val removedChildren: PersistentSet<Pair<ConnectionId, ChildEntityId>> = persistentHashSetOf(),
|
||||
val childrenOrdering: PersistentMap<ConnectionId, PersistentSet<ChildEntityId>> = persistentHashMapOf(),
|
||||
val newParents: PersistentMap<ConnectionId, ParentEntityId> = persistentHashMapOf(),
|
||||
val removedParents: PersistentMap<ConnectionId, ParentEntityId> = persistentHashMapOf(),
|
||||
) {
|
||||
fun isEmpty(): Boolean {
|
||||
return newChildren.isEmpty()
|
||||
|
||||
@@ -11,6 +11,9 @@ import com.intellij.platform.workspace.storage.testEntities.entities.AnotherSour
|
||||
import com.intellij.platform.workspace.storage.testEntities.entities.MySource
|
||||
import com.intellij.platform.workspace.storage.tests.createBuilderFrom
|
||||
import com.intellij.platform.workspace.storage.tests.createEmptyBuilder
|
||||
import kotlinx.collections.immutable.persistentHashMapOf
|
||||
import kotlinx.collections.immutable.toPersistentHashSet
|
||||
import kotlinx.collections.immutable.toPersistentMap
|
||||
import org.jetbrains.jetCheck.Generator
|
||||
import org.jetbrains.jetCheck.ImperativeCommand
|
||||
import org.jetbrains.jetCheck.PropertyChecker
|
||||
@@ -150,14 +153,14 @@ private class ApplyChangesFromCheckChangelog(val preBuilder: MutableEntityStorag
|
||||
private fun assertEntries(updatedChangelog: Map<EntityId, ChangeEntry>, actualChangelog: Map<EntityId, ChangeEntry>) {
|
||||
val left = updatedChangelog.mapValues { (k, v) ->
|
||||
if (v is ChangeEntry.ReplaceEntity) {
|
||||
val newRefs = v.references?.copy(childrenOrdering = emptyMap()).takeUnless { it?.isEmpty() == true }
|
||||
val newRefs = v.references?.copy(childrenOrdering = persistentHashMapOf()).takeUnless { it?.isEmpty() == true }
|
||||
v.copy(references = newRefs).takeUnless { it.data == null && it.references == null }
|
||||
}
|
||||
else v
|
||||
}.filterValues { it != null }
|
||||
val right = actualChangelog.mapValues { (k, v) ->
|
||||
if (v is ChangeEntry.ReplaceEntity) {
|
||||
val references = v.references?.copy(childrenOrdering = emptyMap()).takeUnless { it?.isEmpty() == true }
|
||||
val references = v.references?.copy(childrenOrdering = persistentHashMapOf()).takeUnless { it?.isEmpty() == true }
|
||||
v.copy(references = references).takeUnless { it.data == null && it.references == null }
|
||||
}
|
||||
else v
|
||||
@@ -198,14 +201,14 @@ private class ApplyChangesFromCheckChangelog(val preBuilder: MutableEntityStorag
|
||||
}
|
||||
newEntry = newEntry.copy(
|
||||
references = entry.references?.copy(
|
||||
newChildren = entry.references.newChildren.mapTo(HashSet()) {
|
||||
newChildren = entry.references.newChildren.map {
|
||||
it.copy(second = replaceMap[it.second.id.notThis()]?.id?.asChild() ?: it.second)
|
||||
},
|
||||
removedChildren = entry.references.removedChildren.mapTo(HashSet()) {
|
||||
}.toPersistentHashSet(),
|
||||
removedChildren = entry.references.removedChildren.map {
|
||||
it.copy(second = replaceMap[it.second.id.notThis()]?.id?.asChild() ?: it.second)
|
||||
},
|
||||
newParents = entry.references.newParents.mapValues { (_, v) -> replaceMap[v.id.notThis()]?.id?.asParent() ?: v },
|
||||
removedParents = entry.references.removedParents.mapValues { (_, v) -> replaceMap[v.id.notThis()]?.id?.asParent() ?: v },
|
||||
}.toPersistentHashSet(),
|
||||
newParents = entry.references.newParents.mapValues { (_, v) -> replaceMap[v.id.notThis()]?.id?.asParent() ?: v }.toPersistentMap(),
|
||||
removedParents = entry.references.removedParents.mapValues { (_, v) -> replaceMap[v.id.notThis()]?.id?.asParent() ?: v }.toPersistentMap(),
|
||||
)
|
||||
)
|
||||
put(newId, newEntry)
|
||||
|
||||
Reference in New Issue
Block a user