mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
optimization: bulk add pointers to container
This commit is contained in:
+36
-21
@@ -35,15 +35,13 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ConcurrentList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.URLUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@@ -189,15 +187,17 @@ public class VirtualFilePointerContainerImpl extends TraceableDisposable impleme
|
||||
assert !myDisposed;
|
||||
dropCaches();
|
||||
|
||||
for (final VirtualFilePointer pointer : that.getList()) {
|
||||
myList.addIfAbsent(duplicate(pointer));
|
||||
}
|
||||
for (VirtualFilePointer jarDirectory : ((VirtualFilePointerContainerImpl)that).myJarDirectories) {
|
||||
myJarDirectories.add(duplicate(jarDirectory));
|
||||
}
|
||||
for (VirtualFilePointer jarRecursiveDirectory : ((VirtualFilePointerContainerImpl)that).myJarRecursiveDirectories) {
|
||||
myJarRecursiveDirectories.add(duplicate(jarRecursiveDirectory));
|
||||
Set<VirtualFilePointer> set = new THashSet<>(myList);
|
||||
List<VirtualFilePointer> thatList = that.getList();
|
||||
List<VirtualFilePointer> toAddList = new ArrayList<>(thatList.size());
|
||||
for (final VirtualFilePointer pointer : thatList) {
|
||||
if (!set.contains(pointer)) toAddList.add(duplicate(pointer));
|
||||
}
|
||||
myList.addAll(toAddList);
|
||||
List<VirtualFilePointer> jarDups = ContainerUtil.map(((VirtualFilePointerContainerImpl)that).myJarDirectories, this::duplicate);
|
||||
List<VirtualFilePointer> jarRecursiveDups = ContainerUtil.map(((VirtualFilePointerContainerImpl)that).myJarRecursiveDirectories, this::duplicate);
|
||||
myJarDirectories.addAll(jarDups);
|
||||
myJarRecursiveDirectories.addAll(jarRecursiveDups);
|
||||
}
|
||||
|
||||
private void dropCaches() {
|
||||
@@ -334,6 +334,7 @@ public class VirtualFilePointerContainerImpl extends TraceableDisposable impleme
|
||||
return myList.size()+myJarDirectories.size()+myJarRecursiveDirectories.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof VirtualFilePointerContainerImpl)) return false;
|
||||
@@ -345,6 +346,7 @@ public class VirtualFilePointerContainerImpl extends TraceableDisposable impleme
|
||||
myJarRecursiveDirectories.equals(impl.myJarRecursiveDirectories);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myList.hashCode();
|
||||
}
|
||||
@@ -384,15 +386,11 @@ public class VirtualFilePointerContainerImpl extends TraceableDisposable impleme
|
||||
public VirtualFilePointerContainer clone(@NotNull Disposable parent, @Nullable VirtualFilePointerListener listener) {
|
||||
assert !myDisposed;
|
||||
VirtualFilePointerContainerImpl clone = (VirtualFilePointerContainerImpl)myVirtualFilePointerManager.createContainer(parent, listener);
|
||||
for (VirtualFilePointer pointer : myList) {
|
||||
clone.add(pointer.getUrl());
|
||||
}
|
||||
for (VirtualFilePointer jarDirectoryPtr : myJarDirectories) {
|
||||
clone.addJarDirectory(jarDirectoryPtr.getUrl(), false);
|
||||
}
|
||||
for (VirtualFilePointer jarDirectoryPtr : myJarRecursiveDirectories) {
|
||||
clone.addJarDirectory(jarDirectoryPtr.getUrl(), true);
|
||||
}
|
||||
|
||||
List<VirtualFilePointer> toAdd = ContainerUtil.map(myList, p -> clone.create(p.getUrl()));
|
||||
clone.myList.addAll(toAdd);
|
||||
clone.addAllJarDirectories(ContainerUtil.map(myJarDirectories, VirtualFilePointer::getUrl), false);
|
||||
clone.addAllJarDirectories(ContainerUtil.map(myJarRecursiveDirectories, VirtualFilePointer::getUrl), true);
|
||||
return clone;
|
||||
}
|
||||
|
||||
@@ -413,6 +411,23 @@ public class VirtualFilePointerContainerImpl extends TraceableDisposable impleme
|
||||
dropCaches();
|
||||
}
|
||||
|
||||
/** optimization: faster than calling {@link #addJarDirectory(String, boolean)} one by one */
|
||||
public void addAllJarDirectories(@NotNull Collection<String> directoryUrls, boolean recursively) {
|
||||
if (directoryUrls.isEmpty()) return;
|
||||
Set<VirtualFilePointer> jars = new THashSet<>(recursively ? myJarRecursiveDirectories : myJarDirectories);
|
||||
Set<VirtualFilePointer> list = new THashSet<>(myList);
|
||||
List<VirtualFilePointer> toAddJars = new ArrayList<>(directoryUrls.size());
|
||||
List<VirtualFilePointer> toAddList = new ArrayList<>(directoryUrls.size());
|
||||
directoryUrls.forEach(url -> {
|
||||
VirtualFilePointer pointer = myVirtualFilePointerManager.createDirectoryPointer(url, recursively, myParent, myListener);
|
||||
if (!jars.contains(pointer)) toAddJars.add(pointer);
|
||||
if (!list.contains(pointer)) toAddList.add(pointer);
|
||||
});
|
||||
(recursively ? myJarRecursiveDirectories : myJarDirectories).addAll(toAddJars);
|
||||
myList.addAll(toAddList); // hack. jar directories need to be contained in class roots too (for externalization compatibility) but be ignored in getFiles()
|
||||
dropCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeJarDirectory(@NotNull String directoryUrl) {
|
||||
dropCaches();
|
||||
|
||||
+21
-11
@@ -27,6 +27,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.openapi.vfs.ex.VirtualFileManagerAdapter;
|
||||
import com.intellij.openapi.vfs.impl.VirtualFilePointerContainerImpl;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
|
||||
import com.intellij.openapi.vfs.pointers.VirtualFilePointerContainer;
|
||||
@@ -44,6 +45,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -184,26 +186,32 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (myProject.isDefault()) return null;
|
||||
|
||||
final Set<String> recursive = new THashSet<>(FileUtil.PATH_HASHING_STRATEGY);
|
||||
final Set<String> flat = new THashSet<>(FileUtil.PATH_HASHING_STRATEGY);
|
||||
final Set<String> dirUrls = new THashSet<>(FileUtil.PATH_HASHING_STRATEGY);
|
||||
final Set<String> recursiveDirs = new THashSet<>(FileUtil.PATH_HASHING_STRATEGY);
|
||||
final Set<String> recursiveDirUrls = new THashSet<>(FileUtil.PATH_HASHING_STRATEGY);
|
||||
final Set<String> files = new THashSet<>(FileUtil.PATH_HASHING_STRATEGY);
|
||||
|
||||
final String projectFilePath = myProject.getProjectFilePath();
|
||||
final File projectDirFile = projectFilePath == null ? null : new File(projectFilePath).getParentFile();
|
||||
if (projectDirFile != null && projectDirFile.getName().equals(Project.DIRECTORY_STORE_FOLDER)) {
|
||||
recursive.add(projectDirFile.getAbsolutePath());
|
||||
dirUrls.add(VfsUtilCore.pathToUrl(projectDirFile.getAbsolutePath()));
|
||||
}
|
||||
else {
|
||||
flat.add(projectFilePath);
|
||||
files.add(projectFilePath);
|
||||
// may be not existing yet
|
||||
ContainerUtil.addIfNotNull(flat, ProjectKt.getStateStore(myProject).getWorkspaceFilePath());
|
||||
ContainerUtil.addIfNotNull(files, ProjectKt.getStateStore(myProject).getWorkspaceFilePath());
|
||||
}
|
||||
|
||||
for (AdditionalLibraryRootsProvider extension : AdditionalLibraryRootsProvider.EP_NAME.getExtensions()) {
|
||||
recursive.addAll(ContainerUtil.map(extension.getRootsToWatch(myProject), VirtualFile::getPath));
|
||||
Collection<VirtualFile> toWatch = extension.getRootsToWatch(myProject);
|
||||
recursiveDirs.addAll(ContainerUtil.map(toWatch, VirtualFile::getPath));
|
||||
recursiveDirUrls.addAll(ContainerUtil.map(toWatch, VirtualFile::getUrl));
|
||||
}
|
||||
|
||||
for (WatchedRootsProvider extension : WatchedRootsProvider.EP_NAME.getExtensions(myProject)) {
|
||||
recursive.addAll(extension.getRootsToWatch());
|
||||
Set<String> toWatch = extension.getRootsToWatch();
|
||||
recursiveDirs.addAll(toWatch);
|
||||
recursiveDirUrls.addAll(ContainerUtil.map(toWatch, p->VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(p))));
|
||||
}
|
||||
|
||||
Disposable oldDisposable = myRootPointersDisposable;
|
||||
@@ -211,14 +219,16 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen
|
||||
Disposer.register(this, myRootPointersDisposable);
|
||||
// create container with these urls with the sole purpose to get events to getRootsValidityChangedListener() when these roots change
|
||||
VirtualFilePointerContainer container = VirtualFilePointerManager.getInstance().createContainer(myRootPointersDisposable, getRootsValidityChangedListener());
|
||||
recursive.forEach(path -> container.addJarDirectory(VfsUtilCore.pathToUrl(path), true));
|
||||
flat.forEach(path -> container.add(VfsUtilCore.pathToUrl(path)));
|
||||
|
||||
((VirtualFilePointerContainerImpl)container).addAllJarDirectories(recursiveDirUrls, true);
|
||||
((VirtualFilePointerContainerImpl)container).addAllJarDirectories(dirUrls, false);
|
||||
files.forEach(path -> container.add(VfsUtilCore.pathToUrl(path)));
|
||||
|
||||
Disposer.dispose(oldDisposable); // dispose after the re-creating container to keep virtual file pointers from disposing and re-creating back
|
||||
|
||||
// module roots already fire validity change events
|
||||
addRootsFromModulesTo(recursive, flat);
|
||||
return Pair.create(recursive, flat);
|
||||
addRootsFromModulesTo(recursiveDirs, files);
|
||||
return Pair.create(recursiveDirs, files);
|
||||
}
|
||||
|
||||
private void addRootsFromModulesTo(@NotNull Set<? super String> recursive, @NotNull Set<? super String> flat) {
|
||||
|
||||
Reference in New Issue
Block a user