From 2e5c909f3a2ce603f88c8b039c746097e2cc0338 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Wed, 12 Oct 2016 21:02:16 +0300 Subject: [PATCH] [vcs]: use per Repository ignored holders in VcsIgnored; add get size methods * (IDEA-113185, IDEA-137014, IDEA-138132, IDEA-159684) fix performance; * provide dir and file sizes method for Ignored files; * improve ignored rendering with "updating" word; * do not ask for ignored if they shouldn't be shown (to avoid map union); * remove VF set from HgIgnoredFilesHolder, it was already moved to Composite holder and used as IDE ignored files storage; --- .../vcs/changes/ChangeListManagerImpl.java | 12 +++++ .../vcs/changes/ChangesViewManager.java | 19 ++++--- .../changes/IgnoredFilesCompositeHolder.java | 15 ++++++ .../vcs/changes/IgnoredFilesHolder.java | 7 +++ .../vcs/changes/RecursiveFileHolder.java | 13 ++++- .../vcs/changes/VcsIgnoredFilesHolder.java | 2 + .../ui/ChangesBrowserIgnoredFilesNode.java | 14 ++++- .../ui/ChangesBrowserSpecificFilesNode.java | 16 ++---- .../vcs/changes/ui/TreeModelBuilder.java | 7 ++- .../hg4idea/provider/HgIgnoredFileHolder.java | 54 ++++++++++++------- .../provider/HgLocalIgnoredHolder.java | 4 ++ 11 files changed, 120 insertions(+), 43 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java index 27a29db7d0c5..13c89e8f9a89 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java @@ -812,6 +812,18 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + @NotNull + public Couple getIgnoredFilesSize() { + synchronized (myDataLock) { + IgnoredFilesCompositeHolder ignoredFileHolder = myComposite.getIgnoredFileHolder(); + return Couple.of(ignoredFileHolder.getFilesNum(), ignoredFileHolder.getDirNum()); + } + } + + boolean isIgnoredInUpdateMode() { + return myComposite.getIgnoredFileHolder().isInUpdatingMode(); + } + public List getLockedFolders() { synchronized (myDataLock) { return myComposite.getVFHolder(FileHolder.HolderType.LOCKED).getFiles(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java index cd3f4397be28..54949af48cca 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesViewManager.java @@ -335,15 +335,18 @@ public class ChangesViewManager implements ChangesViewI, ProjectComponent, Persi ChangeListManagerImpl changeListManager = ChangeListManagerImpl.getInstanceImpl(myProject); + TreeModelBuilder treeModelBuilder = new TreeModelBuilder(myProject, myView.isShowFlatten()) + .set(changeListManager.getChangeListsCopy(), changeListManager.getDeletedFiles(), changeListManager.getModifiedWithoutEditing(), + changeListManager.getSwitchedFilesMap(), changeListManager.getSwitchedRoots(), + changeListManager.getLockedFolders(), + changeListManager.getLogicallyLockedFolders()) + .setUnversioned(changeListManager.getUnversionedFiles(), changeListManager.getUnversionedFilesSize()); + if (myState.myShowIgnored) { + treeModelBuilder.setIgnored(changeListManager.getIgnoredFiles(), changeListManager.getIgnoredFilesSize(), + changeListManager.isIgnoredInUpdateMode()); + } myView.updateModel( - new TreeModelBuilder(myProject, myView.isShowFlatten()) - .set(changeListManager.getChangeListsCopy(), changeListManager.getDeletedFiles(), changeListManager.getModifiedWithoutEditing(), - changeListManager.getSwitchedFilesMap(), changeListManager.getSwitchedRoots(), - changeListManager.getLockedFolders(), - changeListManager.getLogicallyLockedFolders()) - .setUnversioned(changeListManager.getUnversionedFiles(), changeListManager.getUnversionedFilesSize()) - .setIgnored(myState.myShowIgnored ? changeListManager.getIgnoredFiles() : null) - .build() + treeModelBuilder.build() ); changeDetails(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesCompositeHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesCompositeHolder.java index 81e4d3e7a853..0372744acdb2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesCompositeHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesCompositeHolder.java @@ -79,6 +79,11 @@ public class IgnoredFilesCompositeHolder implements IgnoredFilesHolder { myIdeIgnoredFilesHolder.addFile(file); } + public boolean isInUpdatingMode() { + return myVcsIgnoredHolderMap.values().stream() + .anyMatch((holder) -> (holder instanceof VcsIgnoredFilesHolder) && ((VcsIgnoredFilesHolder)holder).isInUpdatingMode()); + } + @Override public boolean containsFile(VirtualFile file) { if (myIdeIgnoredFilesHolder.containsFile(file)) return true; @@ -96,6 +101,16 @@ public class IgnoredFilesCompositeHolder implements IgnoredFilesHolder { return result; } + @Override + public int getDirNum() { + return myIdeIgnoredFilesHolder.getDirNum() + myVcsIgnoredHolderMap.values().stream().mapToInt(IgnoredFilesHolder::getDirNum).sum(); + } + + @Override + public int getFilesNum() { + return myIdeIgnoredFilesHolder.getFilesNum() + myVcsIgnoredHolderMap.values().stream().mapToInt(IgnoredFilesHolder::getFilesNum).sum(); + } + @Override public void notifyVcsStarted(AbstractVcs vcs) { myCurrentVcs = vcs; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesHolder.java index f48355c49ddc..3ed7a1254034 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/IgnoredFilesHolder.java @@ -26,7 +26,14 @@ import java.util.Collection; */ public interface IgnoredFilesHolder extends FileHolder { void addFile(VirtualFile file); + + int getDirNum(); + + int getFilesNum(); + boolean containsFile(VirtualFile file); + Collection values(); + void cleanAndAdjustScope(VcsModifiableDirtyScope scope); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RecursiveFileHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RecursiveFileHolder.java index 3f1f0582aa96..4b9e58fc9026 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RecursiveFileHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/RecursiveFileHolder.java @@ -8,6 +8,7 @@ import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.vcsUtil.VcsUtil; +import org.jetbrains.annotations.NotNull; import java.util.*; @@ -53,7 +54,17 @@ public class RecursiveFileHolder implements IgnoredFilesHolder { } } - public void removeFile(final VirtualFile file) { + @Override + public int getDirNum() { + return myDirMap.size(); + } + + @Override + public int getFilesNum() { + return myMap.size(); + } + + public void removeFile(@NotNull final VirtualFile file) { myMap.remove(file); if (file.isDirectory()) { myDirMap.remove(file); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsIgnoredFilesHolder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsIgnoredFilesHolder.java index 616f4d55c812..0de5dd7e02b9 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsIgnoredFilesHolder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsIgnoredFilesHolder.java @@ -22,6 +22,8 @@ import org.jetbrains.annotations.NotNull; public interface VcsIgnoredFilesHolder extends IgnoredFilesHolder { ExtensionPointName VCS_IGNORED_FILES_HOLDER_EP = ExtensionPointName.create("com.intellij.vcs.ignoredFilesHolder"); + default boolean isInUpdatingMode() {return false;} + @NotNull AbstractVcs getVcs(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserIgnoredFilesNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserIgnoredFilesNode.java index ce28b23e6f2e..bd6a9d64bd47 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserIgnoredFilesNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserIgnoredFilesNode.java @@ -19,11 +19,23 @@ package com.intellij.openapi.vcs.changes.ui; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.changes.ChangeListOwner; import com.intellij.openapi.vcs.changes.IgnoredViewDialog; +import org.jetbrains.annotations.NotNull; public class ChangesBrowserIgnoredFilesNode extends ChangesBrowserSpecificFilesNode { - protected ChangesBrowserIgnoredFilesNode(Project project, int filesSize, int dirsSize, boolean many) { + private final boolean myUpdatingMode; + + protected ChangesBrowserIgnoredFilesNode(Project project, int filesSize, int dirsSize, boolean many, boolean updatingMode) { super(IGNORED_FILES_TAG, filesSize, dirsSize, many, () -> new IgnoredViewDialog(project).show()); + myUpdatingMode = updatingMode; + } + + @Override + public void render(@NotNull ChangesBrowserNodeRenderer renderer, boolean selected, boolean expanded, boolean hasFocus) { + super.render(renderer, selected, expanded, hasFocus); + if (myUpdatingMode) { + appendUpdatingState(renderer); + } } @Override diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserSpecificFilesNode.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserSpecificFilesNode.java index 4d6dfa32dcff..68ff5feaaaa7 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserSpecificFilesNode.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserSpecificFilesNode.java @@ -19,15 +19,14 @@ import com.intellij.ui.SimpleTextAttributes; import org.jetbrains.annotations.NotNull; public class ChangesBrowserSpecificFilesNode extends ChangesBrowserNode { - protected final int myFilesSize; - protected final int myDirsSize; protected final boolean myIsMany; @NotNull protected final Runnable myDialogShower; protected ChangesBrowserSpecificFilesNode(Object userObject, int filesSize, int dirsSize, boolean many, @NotNull Runnable shower) { super(userObject); - myFilesSize = filesSize; - myDirsSize = dirsSize; + // if files presented in the same view recalculate number of dirs and files -> provide -1; otherwise use from model + myCount = many ? filesSize : -1; + myDirectoryCount = many ? dirsSize : -1; myIsMany = many; myDialogShower = shower; } @@ -43,17 +42,12 @@ public class ChangesBrowserSpecificFilesNode extends ChangesBrowserNode { } public int getFilesSize() { - return myFilesSize; + return myCount; } @Override public int getCount() { - return myFilesSize - myDirsSize; - } - - @Override - public int getDirectoryCount() { - return myDirsSize; + return super.getCount() - getDirectoryCount(); } public boolean isManyFiles() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeModelBuilder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeModelBuilder.java index a1b08faba5fb..7b9e44a438d2 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeModelBuilder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/TreeModelBuilder.java @@ -107,12 +107,11 @@ public class TreeModelBuilder { } @NotNull - public TreeModelBuilder setIgnored(@Nullable List ignoredFiles) { + public TreeModelBuilder setIgnored(@Nullable List ignoredFiles, Couple sizes, boolean updatingMode) { if (ContainerUtil.isEmpty(ignoredFiles)) return this; - // todo some ignoredFiles files holder may provide directories in the future, now show only files counter return insertSpecificNodeToModel(ignoredFiles, - new ChangesBrowserIgnoredFilesNode(myProject, ignoredFiles.size(), 0, - ignoredFiles.size() > UNVERSIONED_MAX_SIZE)); + new ChangesBrowserIgnoredFilesNode(myProject, sizes.getFirst(), sizes.getSecond(), + ignoredFiles.size() > UNVERSIONED_MAX_SIZE, updatingMode)); } @NotNull diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgIgnoredFileHolder.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgIgnoredFileHolder.java index c7f63f35191f..0186a644541f 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgIgnoredFileHolder.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgIgnoredFileHolder.java @@ -24,56 +24,66 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.zmlx.hg4idea.HgVcs; +import org.zmlx.hg4idea.repo.HgRepository; +import org.zmlx.hg4idea.util.HgUtil; import java.util.Collection; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; public class HgIgnoredFileHolder implements VcsIgnoredFilesHolder { private final Project myProject; - private HgVcs myVcs; - private final Set mySet; - private final Set myVcsIgnoredSet; + private final HgVcs myVcs; + private final Map myVcsIgnoredHolderMap; public HgIgnoredFileHolder(Project project) { myProject = project; myVcs = HgVcs.getInstance(myProject); - mySet = ContainerUtil.newHashSet(); - myVcsIgnoredSet = ContainerUtil.newHashSet(); //collect ignored files from VcsChangeProvider -> processIgnored + myVcsIgnoredHolderMap = ContainerUtil.newHashMap(); } @Override public void addFile(VirtualFile file) { - // todo fix more. take from x0x branch - //LOG.assertTrue(! file.isDirectory()); - mySet.add(file); - myVcsIgnoredSet.add(file); + } + + @Override + public int getDirNum() { + return 0; + } + + @Override + public int getFilesNum() { + return myVcsIgnoredHolderMap.values().stream().mapToInt(HgLocalIgnoredHolder::getSize).sum(); } @Override public boolean containsFile(VirtualFile file) { - return mySet.contains(file) || myVcsIgnoredSet.contains(file); + HgRepository repositoryForFile = HgUtil.getRepositoryForFile(myProject, file); + if (repositoryForFile == null) return false; + HgLocalIgnoredHolder localIgnoredHolder = myVcsIgnoredHolderMap.get(repositoryForFile); + return localIgnoredHolder != null && localIgnoredHolder.contains(file); } @Override public Collection values() { - return ContainerUtil.union(mySet, myVcsIgnoredSet); + return myVcsIgnoredHolderMap.values().stream().map(HgLocalIgnoredHolder::getIgnoredFiles).flatMap(Set::stream) + .collect(Collectors.toSet()); } - - @Override + + @Override public void cleanAndAdjustScope(final VcsModifiableDirtyScope scope) { } @Override public void cleanAll() { - mySet.clear(); - myVcsIgnoredSet.clear();// not sure we need to delete + myVcsIgnoredHolderMap.clear(); } @Override public FileHolder copy() { final HgIgnoredFileHolder result = new HgIgnoredFileHolder(myProject); - result.mySet.addAll(mySet); - result.myVcsIgnoredSet.addAll(myVcsIgnoredSet); + result.myVcsIgnoredHolderMap.putAll(myVcsIgnoredHolderMap); return result; } @@ -84,7 +94,15 @@ public class HgIgnoredFileHolder implements VcsIgnoredFilesHolder { @Override public void notifyVcsStarted(AbstractVcs scope) { - cleanAll(); + myVcsIgnoredHolderMap.clear(); + for (HgRepository repository : HgUtil.getRepositoryManager(myProject).getRepositories()) { + myVcsIgnoredHolderMap.put(repository, repository.getLocalIgnoredHolder()); + } + } + + @Override + public boolean isInUpdatingMode() { + return myVcsIgnoredHolderMap.values().stream().anyMatch(HgLocalIgnoredHolder::isInUpdateMode); } @NotNull diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java index 115a208cc112..964d8924a3e8 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgLocalIgnoredHolder.java @@ -120,4 +120,8 @@ public class HgLocalIgnoredHolder implements Disposable { SET_LOCK.writeLock().unlock(); } } + + public int getSize() { + return getIgnoredFiles().size(); + } }