use IntObjectMap in DirectoryIndex to avoid holding VirtualFile objects

This commit is contained in:
peter
2014-05-23 14:30:11 +02:00
parent e41dedcebe
commit 4af130dbd2
2 changed files with 26 additions and 6 deletions
@@ -35,6 +35,8 @@ import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.Query;
import com.intellij.util.containers.ConcurrentIntObjectMap;
import com.intellij.util.containers.StripedLockIntObjectConcurrentHashMap;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -122,7 +124,19 @@ public class DirectoryIndexImpl extends DirectoryIndex {
private RootIndex getRootIndex() {
RootIndex rootIndex = myRootIndex;
if (rootIndex == null) {
myRootIndex = rootIndex = new RootIndex(myProject);
myRootIndex = rootIndex = new RootIndex(myProject, new RootIndex.InfoCache() {
// Upsource can't use int-mapping because different files may have the same id there
private final ConcurrentIntObjectMap<DirectoryInfo> myInfoCache = new StripedLockIntObjectConcurrentHashMap<DirectoryInfo>();
@Override
public void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info) {
myInfoCache.put(((NewVirtualFile)dir).getId(), info);
}
@Override
public DirectoryInfo getCachedInfo(@NotNull VirtualFile dir) {
return myInfoCache.get(((NewVirtualFile)dir).getId());
}
});
}
return rootIndex;
}
@@ -61,15 +61,16 @@ public class RootIndex extends DirectoryIndex {
};
private final Map<String, List<VirtualFile>> myDirectoriesByPackageNameCache = ContainerUtil.newConcurrentMap();
private final Map<VirtualFile, DirectoryInfo> myInfoCache = ContainerUtil.newConcurrentMap();
private final InfoCache myInfoCache;
private final List<JpsModuleSourceRootType<?>> myRootTypes = ContainerUtil.newArrayList();
private final TObjectIntHashMap<JpsModuleSourceRootType<?>> myRootTypeId = new TObjectIntHashMap<JpsModuleSourceRootType<?>>();
@NotNull private final Project myProject;
private volatile Map<VirtualFile, OrderEntry[]> myOrderEntries;
// made public for Upsource
public RootIndex(@NotNull Project project) {
public RootIndex(@NotNull Project project, InfoCache cache) {
myProject = project;
myInfoCache = cache;
final RootInfo info = buildRootInfo(project);
Set<VirtualFile> allRoots = info.getAllRoots();
@@ -265,7 +266,7 @@ public class RootIndex extends DirectoryIndex {
return null;
}
if (!dir.isDirectory()) {
DirectoryInfo info = myInfoCache.get(dir);
DirectoryInfo info = myInfoCache.getCachedInfo(dir);
return info == NULL_INFO ? null : info;
}
@@ -274,7 +275,7 @@ public class RootIndex extends DirectoryIndex {
if (++count > 1000) {
throw new IllegalStateException("Possible loop in tree, started at " + dir.getName());
}
DirectoryInfo info = myInfoCache.get(root);
DirectoryInfo info = myInfoCache.getCachedInfo(root);
if (info != null) {
if (!dir.equals(root)) {
cacheInfos(dir, root, info);
@@ -293,7 +294,7 @@ public class RootIndex extends DirectoryIndex {
@Nullable
private DirectoryInfo cacheInfos(VirtualFile dir, @Nullable VirtualFile stopAt, @Nullable DirectoryInfo info) {
while (dir != null) {
myInfoCache.put(dir, info == null ? NULL_INFO : info);
myInfoCache.cacheInfo(dir, info == null ? NULL_INFO : info);
if (dir.equals(stopAt)) {
break;
}
@@ -590,4 +591,9 @@ public class RootIndex extends DirectoryIndex {
return Pair.create(directoryInfo, packagePrefix);
}
public interface InfoCache {
@Nullable DirectoryInfo getCachedInfo(@NotNull VirtualFile dir);
void cacheInfo(@NotNull VirtualFile dir, @NotNull DirectoryInfo info);
}
}