[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;
This commit is contained in:
Nadya Zabrodina
2016-10-19 19:23:38 +03:00
parent a43147207c
commit 2e5c909f3a
11 changed files with 120 additions and 43 deletions
@@ -812,6 +812,18 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
}
@NotNull
public Couple<Integer> getIgnoredFilesSize() {
synchronized (myDataLock) {
IgnoredFilesCompositeHolder ignoredFileHolder = myComposite.getIgnoredFileHolder();
return Couple.of(ignoredFileHolder.getFilesNum(), ignoredFileHolder.getDirNum());
}
}
boolean isIgnoredInUpdateMode() {
return myComposite.getIgnoredFileHolder().isInUpdatingMode();
}
public List<VirtualFile> getLockedFolders() {
synchronized (myDataLock) {
return myComposite.getVFHolder(FileHolder.HolderType.LOCKED).getFiles();
@@ -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();
@@ -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;
@@ -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<VirtualFile> values();
void cleanAndAdjustScope(VcsModifiableDirtyScope scope);
}
@@ -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<T> 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);
@@ -22,6 +22,8 @@ import org.jetbrains.annotations.NotNull;
public interface VcsIgnoredFilesHolder extends IgnoredFilesHolder {
ExtensionPointName<VcsIgnoredFilesHolder> VCS_IGNORED_FILES_HOLDER_EP = ExtensionPointName.create("com.intellij.vcs.ignoredFilesHolder");
default boolean isInUpdatingMode() {return false;}
@NotNull
AbstractVcs getVcs();
}
@@ -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
@@ -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() {
@@ -107,12 +107,11 @@ public class TreeModelBuilder {
}
@NotNull
public TreeModelBuilder setIgnored(@Nullable List<VirtualFile> ignoredFiles) {
public TreeModelBuilder setIgnored(@Nullable List<VirtualFile> ignoredFiles, Couple<Integer> 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
@@ -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<VirtualFile> mySet;
private final Set<VirtualFile> myVcsIgnoredSet;
private final HgVcs myVcs;
private final Map<HgRepository, HgLocalIgnoredHolder> 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<VirtualFile> 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
@@ -120,4 +120,8 @@ public class HgLocalIgnoredHolder implements Disposable {
SET_LOCK.writeLock().unlock();
}
}
public int getSize() {
return getIgnoredFiles().size();
}
}