reduce number of DelegateDisposables

faster dispose
This commit is contained in:
Alexey Kudravtsev
2009-11-24 18:26:19 +03:00
parent 1051931237
commit 8576d00151
4 changed files with 73 additions and 4 deletions
@@ -146,6 +146,7 @@ public class FileStatusMap implements Disposable {
return true;
}
});
s.append(")");
return s.toString();
}
}
@@ -37,7 +37,7 @@ public class VirtualFilePointerImpl extends UserDataHolderBase implements Virtua
private final VirtualFileManager myVirtualFileManager;
private final VirtualFilePointerListener myListener;
private boolean disposed = false;
private int useCount;
int useCount;
private long myLastUpdated = -1;
private static final Key<Throwable> CREATE_TRACE = Key.create("CREATION_TRACE");
@@ -18,10 +18,12 @@ package com.intellij.openapi.vfs.impl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.objectTree.ObjectNode;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.ex.VirtualFileManagerEx;
@@ -38,6 +40,8 @@ import org.jetbrains.annotations.TestOnly;
import java.util.*;
public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager implements ApplicationComponent{
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl");
// guarded by this
private final Map<VirtualFilePointerListener, TreeMap<String, VirtualFilePointerImpl>> myUrlToPointerMaps = new LinkedHashMap<VirtualFilePointerListener, TreeMap<String, VirtualFilePointerImpl>>();
@@ -211,12 +215,23 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
else {
//already registered
Disposer.register(parentDisposable, new DelegatingDisposable(pointer));
register(parentDisposable, pointer);
}
return pointer;
}
private static void register(Disposable parentDisposable, VirtualFilePointerImpl pointer) {
DelegatingDisposable delegating = new DelegatingDisposable(pointer);
DelegatingDisposable registered = Disposer.findRegisteredObject(parentDisposable, delegating);
if (registered == null) {
Disposer.register(parentDisposable, delegating);
}
else {
registered.disposeCount++;
}
}
private static String cleanupPath(String path, String protocol) {
path = FileUtil.toSystemIndependentName(path);
@@ -495,12 +510,15 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
private static class DelegatingDisposable implements Disposable {
private final VirtualFilePointerImpl myPointer;
private int disposeCount = 1;
private DelegatingDisposable(VirtualFilePointerImpl pointer) {
private DelegatingDisposable(@NotNull VirtualFilePointerImpl pointer) {
myPointer = pointer;
}
public void dispose() {
myPointer.useCount -= disposeCount-1;
LOG.assertTrue(myPointer.useCount > 0);
myPointer.dispose();
}
@@ -508,6 +526,17 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
public String toString() {
return "D:" + myPointer.toString();
}
@Override
public boolean equals(Object o) {
DelegatingDisposable that = (DelegatingDisposable)o;
return myPointer == that.myPointer;
}
@Override
public int hashCode() {
return myPointer.hashCode();
}
}
@TestOnly
@@ -520,7 +549,7 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
@TestOnly
public int coundDupContainers() {
public int countDupContainers() {
Map<VirtualFilePointerContainer,Integer> c = new THashMap<VirtualFilePointerContainer,Integer>();
for (VirtualFilePointerContainerImpl container : myContainers) {
Integer count = c.get(container);
@@ -536,4 +565,26 @@ public class VirtualFilePointerManagerImpl extends VirtualFilePointerManager imp
}
return i;
}
@TestOnly
public static int countMaxRefCount() {
int result = 0;
for (Disposable disposable : Disposer.getTree().getRootObjects()) {
result = calcMaxRefCount(disposable, result);
}
return result;
}
private static int calcMaxRefCount(Disposable disposable, int result) {
if (disposable instanceof DelegatingDisposable) {
result = Math.max(((DelegatingDisposable)disposable).disposeCount, result);
}
for (ObjectNode<Disposable> node : Disposer.getTree().getNode(disposable).getChildren()) {
result = calcMaxRefCount(node.getObject(), result);
}
return result;
}
}
@@ -16,6 +16,7 @@
package com.intellij.openapi.util;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.objectTree.ObjectNode;
import com.intellij.openapi.util.objectTree.ObjectTree;
import com.intellij.openapi.util.objectTree.ObjectTreeAction;
import com.intellij.util.ReflectionUtil;
@@ -127,4 +128,20 @@ public class Disposer {
ReflectionUtil.resetField(object, each);
}
}
/**
* @return object registered on parentDisposable which is equal to object, or null
*/
@Nullable
public static <T extends Disposable> T findRegisteredObject(@NotNull Disposable parentDisposable, @NotNull T object) {
ObjectNode<Disposable> parentNode = getTree().getNode(parentDisposable);
if (parentNode == null) return null;
for (ObjectNode<Disposable> node : parentNode.getChildren()) {
Disposable nodeObject = node.getObject();
if (nodeObject.equals(object)) {
return (T)nodeObject;
}
}
return null;
}
}