1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00

[306982] - [concurrent] DsfRunnable.finalize() method increases the cost of garbage collecting 10x

This commit is contained in:
Pawel Piech 2010-03-24 18:43:58 +00:00
parent 79c61294f9
commit 04709d2876
14 changed files with 1978 additions and 4 deletions

View file

@ -1,4 +1,4 @@
#Thu Sep 25 17:12:53 PDT 2008
#Wed Mar 10 12:16:35 PST 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
@ -10,10 +10,12 @@ org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
org.eclipse.jdt.core.compiler.problem.deadCode=warning
org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
@ -29,8 +31,11 @@ org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
@ -60,6 +65,7 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverridin
org.eclipse.jdt.core.compiler.problem.unusedImport=error
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled

View file

@ -11,9 +11,10 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.debug.core,
org.eclipse.debug.ui,
org.eclipse.cdt.dsf,
org.junit4,
org.eclipse.ui,
org.eclipse.cdt.dsf.ui,
org.eclipse.cdt.examples.dsf.pda;bundle-version="2.0.0",
org.eclipse.cdt.core;bundle-version="5.2.0"
org.eclipse.cdt.core;bundle-version="5.2.0",
org.eclipse.test.performance;bundle-version="3.6.0",
org.junit;bundle-version="3.8.2"
Bundle-RequiredExecutionEnvironment: J2SE-1.5

View file

@ -0,0 +1,96 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.concurrent;
import junit.framework.TestCase;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.test.performance.Performance;
import org.eclipse.test.performance.PerformanceMeter;
/**
* Tests to measure the performance of the viewer updates.
*/
public class RmPerformanceTests extends TestCase {
public RmPerformanceTests(String name) {
super(name);
}
public void testCreateAndGcObject() {
Performance perf = Performance.getDefault();
PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this));
try {
for (int x = 0; x < 100; x++) {
System.gc();
meter.start();
for (int i = 0; i < 10000; i++) {
new Object();
}
meter.stop();
System.gc();
}
meter.commit();
perf.assertPerformance(meter);
} finally {
meter.dispose();
}
}
public void testCreateAndGcRm() {
Performance perf = Performance.getDefault();
PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this));
try {
for (int x = 0; x < 100; x++) {
System.gc();
meter.start();
for (int i = 0; i < 10000; i++) {
RequestMonitor rm = new RequestMonitor(ImmediateExecutor.getInstance(), null);
rm.done();
}
meter.stop();
System.gc();
}
meter.commit();
perf.assertPerformance(meter);
} finally {
meter.dispose();
}
}
public void testCreateAndGcRmWithParent() {
Performance perf = Performance.getDefault();
PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this));
RequestMonitor parentRm = new RequestMonitor(ImmediateExecutor.getInstance(), null);
try {
for (int x = 0; x < 100; x++) {
System.gc();
meter.start();
for (int i = 0; i < 10000; i++) {
RequestMonitor rm = new RequestMonitor(ImmediateExecutor.getInstance(), parentRm) {
@Override
protected void handleCompleted() {
// do not call parent so it can be reused
};
};
rm.done();
}
meter.stop();
System.gc();
}
meter.commit();
perf.assertPerformance(meter);
} finally {
meter.dispose();
}
}
}

View file

@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
/**
* Convenience interface with constants used by the test model update listener.
*
* @since 3.6
*/
public interface ITestModelUpdatesListenerConstants {
public static final int LABEL_UPDATES_COMPLETE = 0X0001;
public static final int CONTENT_UPDATES_COMPLETE = 0X0002;
public static final int LABEL_UPDATES = 0X0004;
public static final int HAS_CHILDREN_UPDATES = 0X0008;
public static final int CHILDREN_COUNT_UPDATES = 0X0010;
public static final int CHILDREN_UPDATES = 0X0020;
public static final int MODEL_CHANGED_COMPLETE = 0X0040;
public static final int MODEL_PROXIES_INSTALLED = 0X0080;
public static final int STATE_SAVE_COMPLETE = 0X0100;
public static final int STATE_RESTORE_COMPLETE = 0X0200;
public static final int STATE_UPDATES = 0X0400;
public static final int VIEWER_UPDATES_RUNNING = 0X0800;
public static final int LABEL_UPDATES_RUNNING = 0X1000;
public static final int LABEL_COMPLETE = LABEL_UPDATES_COMPLETE | LABEL_UPDATES;
public static final int CONTENT_COMPLETE =
CONTENT_UPDATES_COMPLETE | HAS_CHILDREN_UPDATES | CHILDREN_COUNT_UPDATES | CHILDREN_UPDATES;
public static final int ALL_UPDATES_COMPLETE = LABEL_COMPLETE | CONTENT_COMPLETE | LABEL_UPDATES_RUNNING | VIEWER_UPDATES_RUNNING;
}

View file

@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget;
import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* @since 3.6
*/
public class JFaceViewerPerformanceTests extends PerformanceTests {
public JFaceViewerPerformanceTests(String name) {
super(name);
}
@Override
protected ITreeModelContentProviderTarget createViewer(Display display, Shell shell) {
return new TreeModelViewer(fShell, SWT.VIRTUAL, new PresentationContext("TestViewer"));
}
@Override
protected int getTestModelDepth() {
return 5;
}
}

View file

@ -0,0 +1,222 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import junit.framework.TestCase;
import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.test.performance.Performance;
import org.eclipse.test.performance.PerformanceMeter;
import org.eclipse.ui.PlatformUI;
/**
* Tests to measure the performance of the viewer updates.
*/
abstract public class PerformanceTests extends TestCase implements ITestModelUpdatesListenerConstants {
Display fDisplay;
Shell fShell;
ITreeModelViewer fViewer;
TestModelUpdatesListener fListener;
TestModel fModel;
TestModelVMAdapter fVMAdapter;
TestModelVMProvider fVMProvider;
public PerformanceTests(String name) {
super(name);
}
/**
* @throws java.lang.Exception
*/
@Override
protected void setUp() throws Exception {
fDisplay = PlatformUI.getWorkbench().getDisplay();
fShell = new Shell(fDisplay/*, SWT.ON_TOP | SWT.SHELL_TRIM*/);
fShell.setMaximized(true);
fShell.setLayout(new FillLayout());
fViewer = createViewer(fDisplay, fShell);
fListener = new TestModelUpdatesListener(false, false);
fViewer.addViewerUpdateListener(fListener);
fViewer.addLabelUpdateListener(fListener);
fViewer.addModelChangedListener(fListener);
fModel = new TestModel();
fModel.setRoot( new TestElement(fModel, "root", new TestElement[0] ) );
fModel.setElementChildren(TreePath.EMPTY, makeModelElements(fModel, getTestModelDepth(), "model"));
fVMAdapter = new TestModelVMAdapter();
fVMProvider = fVMAdapter.getTestModelProvider(fViewer.getPresentationContext());
fShell.open ();
}
abstract protected ITreeModelContentProviderTarget createViewer(Display display, Shell shell);
/**
* @throws java.lang.Exception
*/
@Override
protected void tearDown() throws Exception {
fVMAdapter.dispose();
fViewer.removeLabelUpdateListener(fListener);
fViewer.removeViewerUpdateListener(fListener);
fViewer.removeModelChangedListener(fListener);
fViewer.getPresentationContext().dispose();
// Close the shell and exit.
fShell.close();
while (!fShell.isDisposed()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
}
/**
* Depth (size) of the test model to be used in the tests. This number allows
* the jface based tests to use a small enough model to fit on the screen, and
* for the virtual viewer to exercise the content provider to a greater extent.
*/
abstract protected int getTestModelDepth();
public void testRefreshStruct() {
fViewer.setAutoExpandLevel(-1);
TestElementVMContext rootVMC = fVMProvider.getElementVMContext(fViewer.getPresentationContext(), fModel.getRootElement());
// Create the listener
fListener.reset(TreePath.EMPTY, rootVMC.getElement(), -1, true, false);
// Set the input into the view and update the view.
fViewer.setInput(rootVMC);
while (!fListener.isFinished(ALL_UPDATES_COMPLETE))
if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
//fModel.validateData(fViewer, TreePath.EMPTY);
Performance perf = Performance.getDefault();
PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this));
try {
for (int i = 0; i < 100; i++) {
// Update the model
fModel.setAllAppendix(" - pass " + i);
fListener.reset(TreePath.EMPTY, rootVMC.getElement(), -1, false, false);
System.gc();
meter.start();
fVMProvider.postDelta(new ModelDelta(rootVMC.getElement(), IModelDelta.CONTENT));
while (!fListener.isFinished(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE))
if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
meter.stop();
System.gc();
}
meter.commit();
perf.assertPerformance(meter);
} finally {
meter.dispose();
}
}
public void _x_testRefreshStructOnePass() {
fViewer.setAutoExpandLevel(-1);
TestElementVMContext rootVMC = fVMProvider.getElementVMContext(fViewer.getPresentationContext(), fModel.getRootElement());
// Create the listener
fListener.reset(TreePath.EMPTY, rootVMC.getElement(), -1, true, false);
// Set the input into the view and update the view.
fViewer.setInput(rootVMC);
while (!fListener.isFinished(ALL_UPDATES_COMPLETE))
if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
//fModel.validateData(fViewer, TreePath.EMPTY);
Performance perf = Performance.getDefault();
PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this));
try {
System.gc();
meter.start();
for (int i = 0; i < 1000; i++) {
// Update the model
fModel.setAllAppendix(" - pass " + i);
fListener.reset(TreePath.EMPTY, rootVMC.getElement(), -1, false, false);
fVMProvider.postDelta(new ModelDelta(rootVMC.getElement(), IModelDelta.CONTENT));
while (!fListener.isFinished(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE))
if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
}
System.gc();
meter.stop();
meter.commit();
perf.assertPerformance(meter);
} finally {
meter.dispose();
}
}
public void _x_testRefreshStructReplaceElements() {
TestModel model = new TestModel();
model.setRoot( new TestElement(model, "root", new TestElement[0] ) );
model.setElementChildren(TreePath.EMPTY, makeModelElements(model, getTestModelDepth(), "model"));
fViewer.setAutoExpandLevel(-1);
// Create the listener
fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, false);
// Set the input into the view and update the view.
fViewer.setInput(model.getRootElement());
while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
model.validateData(fViewer, TreePath.EMPTY);
Performance perf = Performance.getDefault();
PerformanceMeter meter = perf.createPerformanceMeter(perf.getDefaultScenarioId(this));
try {
for (int i = 0; i < 2000; i++) {
// Update the model
model.setElementChildren(TreePath.EMPTY, makeModelElements(model, getTestModelDepth(), "pass " + i));
TestElement element = model.getRootElement();
fListener.reset(TreePath.EMPTY, element, -1, false, false);
meter.start();
model.postDelta(new ModelDelta(element, IModelDelta.CONTENT));
while (!fListener.isFinished(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE))
if (!fDisplay.readAndDispatch ()) fDisplay.sleep ();
//model.validateData(fViewer, TreePath.EMPTY);
meter.stop();
System.gc();
}
meter.commit();
perf.assertPerformance(meter);
} finally {
meter.dispose();
}
}
private TestElement[] makeModelElements(TestModel model, int depth, String prefix) {
TestElement[] elements = new TestElement[depth];
for (int i = 0; i < depth; i++) {
String name = prefix + "." + i;
elements[i] = new TestElement(model, name, makeModelElements(model, i, name));
}
return elements;
}
}

View file

@ -0,0 +1,52 @@
package org.eclipse.cdt.tests.dsf.vm;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class TestDsfVMPlugin extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.cdt.tests.dsf.vm"; //$NON-NLS-1$
// The shared instance
private static TestDsfVMPlugin plugin;
/**
* The constructor
*/
public TestDsfVMPlugin() {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
@Override
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static TestDsfVMPlugin getDefault() {
return plugin;
}
}

View file

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext;
import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement;
/**
*
*/
public class TestElementVMContext extends AbstractVMContext {
final private TestElement fElement;
public TestElementVMContext(TestModelVMNode node, TestElement element) {
super(node);
fElement = element;
}
@Override
public boolean equals(Object obj) {
return obj instanceof TestElementVMContext && ((TestElementVMContext)obj).fElement.equals(fElement);
}
@Override
public int hashCode() {
return fElement.hashCode();
}
public TestElement getElement() {
return fElement;
}
}

View file

@ -0,0 +1,669 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import java.util.Arrays;
import junit.framework.Assert;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelCheckProviderTarget;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ICheckUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.Viewer;
/**
* Test model for the use in unit tests. This test model contains a set of
* elements in a tree structure. It contains utility methods for modifying the
* model and for verifying that the viewer content matches the model.
*
* @since 3.6
*/
public class TestModel {
public static class TestElement extends PlatformObject {
private final TestModel fModel;
private final String fID;
TestElement[] fChildren;
String fLabelAppendix = "";
boolean fExpanded;
boolean fChecked;
boolean fGrayed;
public TestElement(TestModel model, String text, TestElement[] children) {
this (model, text, false, false, children);
}
public TestElement(TestModel model, String text, boolean checked, boolean grayed, TestElement[] children) {
fModel = model;
fID = text;
fChildren = children;
fChecked = checked;
fGrayed = grayed;
}
public TestModel getModel() {
return fModel;
}
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class adapter) {
if (adapter.isInstance(fModel)) {
return fModel;
}
return null;
}
public String getID() {
return fID;
}
public void setLabelAppendix(String appendix) {
fLabelAppendix = appendix;
}
public String getLabel() {
return fID + fLabelAppendix;
}
public TestElement[] getChildren() {
return fChildren;
}
public boolean isExpanded() {
return fExpanded;
}
public boolean getGrayed() {
return fGrayed;
}
public boolean getChecked() {
return fChecked;
}
public void setChecked(boolean checked, boolean grayed) {
fChecked = checked;
fGrayed = grayed;
}
@Override
public boolean equals(Object obj) {
return obj instanceof TestElement && fID.equals(((TestElement)obj).fID);
}
@Override
public int hashCode() {
return fID.hashCode();
}
@Override
public String toString() {
return getLabel();
}
public int indexOf(TestElement child) {
return Arrays.asList(fChildren).indexOf(child);
}
}
private class ModelProxy extends AbstractModelProxy {
@Override
public void installed(Viewer viewer) {
super.installed(viewer);
ModelDelta rootDelta = TestModel.this.getBaseDelta(new ModelDelta(fInput, IModelDelta.NO_CHANGE));
installSubModelProxies(fRootPath, rootDelta);
fireModelChanged(rootDelta);
}
private void installSubModelProxies(TreePath path, ModelDelta delta) {
TestElement element = getElement(path);
if (element.fModel != TestModel.this) {
// Found an element from a different model. Install its proxy and return.
delta.setFlags(delta.getFlags() | IModelDelta.INSTALL);
} else {
TestElement[] children = element.getChildren();
for (int i = 0; i < children.length; i++) {
installSubModelProxies(path.createChildPath(children[i]), delta.addNode(children[i], IModelDelta.NO_CHANGE));
}
}
}
}
private TestElement fRoot;
private Object fInput = null;
private TreePath fRootPath = TreePath.EMPTY;
private ModelProxy fModelProxy;
/**
* Constructor private. Use static factory methods instead.
*/
public TestModel() {}
public TestElement getRootElement() {
return fRoot;
}
public ModelDelta getBaseDelta(ModelDelta rootDelta) {
ModelDelta delta = rootDelta;
for (int i = 0; i < fRootPath.getSegmentCount(); i++) {
ModelDelta subDelta = delta.getChildDelta(fRootPath.getSegment(i));
if (subDelta == null) {
subDelta = delta.addNode(fRootPath.getSegment(i), IModelDelta.NO_CHANGE);
}
delta = subDelta;
}
delta.setChildCount(getRootElement().getChildren().length);
return delta;
}
public int getModelDepth() {
return getDepth(getRootElement(), 0);
}
private int getDepth(TestElement element, int atDepth) {
TestElement[] children = element.getChildren();
if (children.length == 0) {
return atDepth;
}
int depth = atDepth + 1;
for (int i = 0; i < children.length; i++) {
depth = Math.max(depth, getDepth(children[i], atDepth + 1));
}
return depth;
}
public void update(IHasChildrenUpdate[] updates) {
for (int i = 0; i < updates.length; i++) {
TestElement element = (TestElement)updates[i].getElement();
updates[i].setHasChilren(element.getChildren().length > 0);
updates[i].done();
}
}
public void update(IChildrenCountUpdate[] updates) {
for (int i = 0; i < updates.length; i++) {
TestElement element = (TestElement)updates[i].getElement();
updates[i].setChildCount(element.getChildren().length);
updates[i].done();
}
}
public void update(IChildrenUpdate[] updates) {
for (int i = 0; i < updates.length; i++) {
TestElement element = (TestElement)updates[i].getElement();
int endOffset = updates[i].getOffset() + updates[i].getLength();
for (int j = updates[i].getOffset(); j < endOffset; j++) {
if (j < element.getChildren().length) {
updates[i].setChild(element.getChildren()[j], j);
}
}
updates[i].done();
}
}
public void update(ILabelUpdate[] updates) {
for (int i = 0; i < updates.length; i++) {
TestElement element = (TestElement)updates[i].getElement();
updates[i].setLabel(element.fID, 0);
if (updates[i] instanceof ICheckUpdate &&
Boolean.TRUE.equals(updates[i].getPresentationContext().getProperty(ICheckUpdate.PROP_CHECK)))
{
((ICheckUpdate)updates[i]).setChecked(element.getChecked(), element.getGrayed());
}
updates[i].done();
}
}
public final static String ELEMENT_MEMENTO_ID = "id";
public void compareElements(IElementCompareRequest[] updates) {
for (int i = 0; i < updates.length; i++) {
String elementID = ((TestElement)updates[i].getElement()).getID();
String mementoID = updates[i].getMemento().getString(ELEMENT_MEMENTO_ID);
updates[i].setEqual( elementID.equals(mementoID) );
updates[i].done();
}
}
public void encodeElements(IElementMementoRequest[] updates) {
for (int i = 0; i < updates.length; i++) {
String elementID = ((TestElement)updates[i].getElement()).getID();
updates[i].getMemento().putString(ELEMENT_MEMENTO_ID, elementID);
updates[i].done();
}
}
public void elementChecked(IPresentationContext context, Object viewerInput, TreePath path, boolean checked) {
TestElement element = getElement(path);
Assert.assertFalse(element.getGrayed());
element.setChecked(checked, false);
}
public IModelProxy createTreeModelProxy(Object input, TreePath path, IPresentationContext context) {
fModelProxy = new ModelProxy();
fInput = input;
fRootPath = path;
return fModelProxy;
}
public IModelProxy getModelProxy() {
return fModelProxy;
}
public TestElement getElement(TreePath path) {
if (path.getSegmentCount() == 0) {
return getRootElement();
} else {
if (path.getLastSegment() instanceof TestElement) {
return (TestElement)path.getLastSegment();
} else if (path.getLastSegment() instanceof TestElementVMContext) {
return ((TestElementVMContext)path.getLastSegment()).getElement();
}
return null;
}
}
public void setAllExpanded() {
doSetExpanded(fRoot);
}
private void doSetExpanded(TestElement element) {
element.fExpanded = true;
for (int i = 0; i < element.fChildren.length; i++) {
doSetExpanded(element.fChildren[i]);
}
}
public void setAllAppendix(String appendix) {
doSetAllAppendix(fRoot, appendix);
}
private void doSetAllAppendix(TestElement element, String appendix) {
element.setLabelAppendix(appendix);
for (int i = 0; i < element.fChildren.length; i++) {
doSetAllAppendix(element.fChildren[i], appendix);
}
}
public void validateData(ITreeModelViewer viewer, TreePath path) {
validateData(viewer, path, false);
}
public void validateData(ITreeModelViewer _viewer, TreePath path, boolean expandedElementsOnly) {
ITreeModelContentProviderTarget viewer = (ITreeModelContentProviderTarget)_viewer;
TestElement element = getElement(path);
if ( Boolean.TRUE.equals(_viewer.getPresentationContext().getProperty(ICheckUpdate.PROP_CHECK)) ) {
ITreeModelCheckProviderTarget checkTarget = (ITreeModelCheckProviderTarget)_viewer;
Assert.assertEquals(element.getChecked(), checkTarget.getElementChecked(path));
Assert.assertEquals(element.getGrayed(), checkTarget.getElementGrayed(path));
}
if (!expandedElementsOnly || path.getSegmentCount() == 0 || viewer.getExpandedState(path) ) {
TestElement[] children = element.getChildren();
Assert.assertEquals(children.length, viewer.getChildCount(path));
for (int i = 0; i < children.length; i++) {
Assert.assertEquals(children[i], viewer.getChildElement(path, i));
validateData(viewer, path.createChildPath(children[i]), expandedElementsOnly);
}
} else if (!viewer.getExpandedState(path)) {
// If element not expanded, verify the plus sign.
Assert.assertEquals(viewer.getHasChildren(path), element.getChildren().length > 0);
}
}
public void setRoot(TestElement root) {
fRoot = root;
}
public void postDelta(IModelDelta delta) {
fModelProxy.fireModelChanged(delta);
}
/** Create or retrieve delta for given path
* @param combine if then new deltas for the given path are created. If false existing ones are reused.
*/
public ModelDelta getElementDelta(ModelDelta baseDelta, TreePath path, boolean combine) {
TestElement element = getRootElement();
ModelDelta delta = baseDelta;
for (int i = 0; i < path.getSegmentCount(); i++) {
TestElement[] children = element.getChildren();
delta.setChildCount(children.length);
Object segment = path.getSegment(i);
int j;
for (j = 0; j < children.length; j++) {
if (segment.equals(children[j])) {
element = children[j];
ModelDelta nextDelta = null;
if (combine) {
nextDelta = delta.getChildDelta(element);
}
if (nextDelta == null) {
nextDelta = delta.addNode(element, j, IModelDelta.NO_CHANGE, element.getChildren().length);
}
delta = nextDelta;
break;
}
}
if (j == children.length) {
throw new IllegalArgumentException("Invalid path");
}
}
return delta;
}
private TreePath getRelativePath(TreePath path) {
Object[] segments = new Object[path.getSegmentCount() - fRootPath.getSegmentCount()];
for (int i = fRootPath.getSegmentCount(), _i = 0; i < path.getSegmentCount(); i++, _i++) {
segments[_i] = path.getSegment(i);
}
return new TreePath(segments);
}
public ModelDelta appendElementLabel(TreePath path, String labelAppendix) {
Assert.assertTrue(path.startsWith(fRootPath, null));
ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
ModelDelta baseDelta = getBaseDelta(rootDelta);
TreePath relativePath = getRelativePath(path);
TestElement element = getElement(relativePath);
ModelDelta delta = getElementDelta(baseDelta, relativePath, false);
element.setLabelAppendix(labelAppendix);
delta.setFlags(delta.getFlags() | IModelDelta.STATE);
return rootDelta;
}
public ModelDelta setElementChecked(TreePath path, boolean checked, boolean grayed) {
Assert.assertTrue(path.startsWith(fRootPath, null));
ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
ModelDelta baseDelta = getBaseDelta(rootDelta);
TreePath relativePath = getRelativePath(path);
TestElement element = getElement(relativePath);
ModelDelta delta = getElementDelta(baseDelta, relativePath, false);
element.setChecked(checked, grayed);
delta.setFlags(delta.getFlags() | IModelDelta.STATE);
return rootDelta;
}
public ModelDelta setElementChildren(TreePath path, TestElement[] children) {
Assert.assertTrue(path.startsWith(fRootPath, null));
ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
ModelDelta baseDelta = getBaseDelta(rootDelta);
TreePath relativePath = getRelativePath(path);
// Find the parent element and generate the delta node for it.
TestElement element = getElement(relativePath);
ModelDelta delta = getElementDelta(baseDelta, relativePath, false);
// Set the new children array
element.fChildren = children;
// Add the delta flag and update the child count in the parent delta.
delta.setFlags(delta.getFlags() | IModelDelta.CONTENT);
delta.setChildCount(children.length);
return rootDelta;
}
public ModelDelta replaceElementChild(TreePath parentPath, int index, TestElement child) {
ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
ModelDelta baseDelta = getBaseDelta(rootDelta);
TreePath relativePath = getRelativePath(parentPath);
TestElement element = getElement(relativePath);
ModelDelta delta= getElementDelta(baseDelta, relativePath, false);
TestElement oldChild = element.fChildren[index];
element.fChildren[index] = child;
delta.addNode(oldChild, child, IModelDelta.REPLACED);
// TODO: set replacement index!?!
return rootDelta;
}
public ModelDelta addElementChild(TreePath parentPath, int index, TestElement newChild) {
ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
ModelDelta baseDelta = getBaseDelta(rootDelta);
TreePath relativePath = getRelativePath(parentPath);
// Find the parent element and generate the delta node for it.
TestElement element = getElement(relativePath);
ModelDelta delta= getElementDelta(baseDelta, relativePath, false);
// Add the new element
element.fChildren = doInsertElementInArray(element.fChildren, index, newChild);
// Add the delta flag and update the child count in the parent delta.
delta.setChildCount(element.getChildren().length);
delta.addNode(newChild, IModelDelta.ADDED);
return rootDelta;
}
public ModelDelta insertElementChild(TreePath parentPath, int index, TestElement newChild) {
return insertElementChild(null, parentPath, index, newChild);
}
public ModelDelta insertElementChild(ModelDelta rootDelta, TreePath parentPath, int index, TestElement newChild) {
if (rootDelta == null) {
rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
}
ModelDelta baseDelta = getBaseDelta(rootDelta);
TreePath relativePath = getRelativePath(parentPath);
// Find the parent element and generate the delta node for it.
TestElement element = getElement(relativePath);
ModelDelta delta= getElementDelta(baseDelta, relativePath, false);
// Add the new element
element.fChildren = doInsertElementInArray(element.fChildren, index, newChild);
// Add the delta flag and update the child count in the parent delta.
delta.setChildCount(element.getChildren().length);
delta.addNode(newChild, index, IModelDelta.INSERTED);
return rootDelta;
}
private TestElement[] doInsertElementInArray(TestElement[] children, int index, TestElement newChild) {
// Create the new children array add the element to it and set it to
// the parent.
TestElement[] newChildren = new TestElement[children.length + 1];
System.arraycopy(children, 0, newChildren, 0, index);
newChildren[index] = newChild;
System.arraycopy(children, index, newChildren, index + 1, children.length - index);
return newChildren;
}
public ModelDelta removeElementChild(TreePath parentPath, int index) {
ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
ModelDelta baseDelta = getBaseDelta(rootDelta);
// Find the parent element and generate the delta node for it.
TestElement element = getElement(parentPath);
ModelDelta delta= getElementDelta(baseDelta, parentPath, false);
// Create a new child array with the element removed
TestElement[] children = element.getChildren();
TestElement childToRemove = children[index];
TestElement[] newChildren = new TestElement[children.length - 1];
System.arraycopy(children, 0, newChildren, 0, index);
System.arraycopy(children, index + 1, newChildren, index, children.length - index - 1);
element.fChildren = newChildren;
// Add the delta flag and update the child count in the parent delta.
delta.setChildCount(element.getChildren().length);
delta.addNode(childToRemove, index, IModelDelta.REMOVED);
return rootDelta;
}
public ModelDelta makeElementDelta(TreePath path, int flags) {
ModelDelta rootDelta = new ModelDelta(fInput, IModelDelta.NO_CHANGE);
ModelDelta baseDelta = getBaseDelta(rootDelta);
// Find the element and generate the delta node for it.
ModelDelta delta= getElementDelta(baseDelta, path, false);
delta.setFlags(flags);
return rootDelta;
}
public TreePath findElement(String label) {
return findElement(TreePath.EMPTY, label);
}
public TreePath findElement(TreePath startPath, String label) {
TestElement element = getElement(startPath);
for (int i = 0; i < element.getChildren().length; i++) {
TestElement child = element.getChildren()[i];
TreePath path = startPath.createChildPath(child);
if ( label.equals(child.getLabel()) ) {
return path;
} else {
TreePath subPath = findElement(path, label);
if (subPath != null) {
return subPath;
}
}
}
return null;
}
@Override
public String toString() {
return getElementString(fRoot, "");
}
public String getElementString(TestElement element, String indent) {
StringBuffer builder = new StringBuffer();
builder.append(indent);
builder.append(element.toString());
builder.append('\n');
TestElement[] children = element.getChildren();
for (int i = 0; i < children.length; i++) {
builder.append(getElementString(children[i], indent + " "));
}
return builder.toString();
}
public static TestModel simpleSingleLevel() {
TestModel model = new TestModel();
model.setRoot( new TestElement(model, "root", new TestElement[] {
new TestElement(model, "1", true, true, new TestElement[0]),
new TestElement(model, "2", true, false, new TestElement[0]),
new TestElement(model, "3", false, true, new TestElement[0]),
new TestElement(model, "4", false, false, new TestElement[0]),
new TestElement(model, "5", new TestElement[0]),
new TestElement(model, "6", new TestElement[0])
}) );
return model;
}
public static TestModel simpleMultiLevel() {
TestModel model = new TestModel();
model.setRoot( new TestElement(model, "root", new TestElement[] {
new TestElement(model, "1", new TestElement[0]),
new TestElement(model, "2", true, false, new TestElement[] {
new TestElement(model, "2.1", true, true, new TestElement[0]),
new TestElement(model, "2.2", false, true, new TestElement[0]),
new TestElement(model, "2.3", true, false, new TestElement[0]),
}),
new TestElement(model, "3", new TestElement[] {
new TestElement(model, "3.1", new TestElement[] {
new TestElement(model, "3.1.1", new TestElement[0]),
new TestElement(model, "3.1.2", new TestElement[0]),
new TestElement(model, "3.1.3", new TestElement[0]),
}),
new TestElement(model, "3.2", new TestElement[] {
new TestElement(model, "3.2.1", new TestElement[0]),
new TestElement(model, "3.2.2", new TestElement[0]),
new TestElement(model, "3.2.3", new TestElement[0]),
}),
new TestElement(model, "3.3", new TestElement[] {
new TestElement(model, "3.3.1", new TestElement[0]),
new TestElement(model, "3.3.2", new TestElement[0]),
new TestElement(model, "3.3.3", new TestElement[0]),
}),
})
}) );
return model;
}
public static TestModel compositeMultiLevel() {
TestModel m2 = new TestModel();
m2.setRoot( new TestElement(m2, "m2.root", new TestElement[] {
new TestElement(m2, "m2.1", new TestElement[0]),
new TestElement(m2, "m2.2", true, false, new TestElement[] {
new TestElement(m2, "m2.2.1", true, true, new TestElement[0]),
new TestElement(m2, "m2.2.2", false, true, new TestElement[0]),
new TestElement(m2, "m2.2.3", true, false, new TestElement[0]),
}),
}) );
TestModel m3 = new TestModel();
m3.setRoot( new TestElement(m3, "m3.root", new TestElement[] {
new TestElement(m3, "m3.1", new TestElement[0]),
new TestElement(m3, "m3.2", true, false, new TestElement[] {
new TestElement(m3, "m3.2.1", true, true, new TestElement[0]),
new TestElement(m3, "m3.2.2", false, true, new TestElement[0]),
new TestElement(m3, "m3.2.3", true, false, new TestElement[0]),
}),
}) );
TestModel m4 = new TestModel();
m4.setRoot( new TestElement(m4, "m4.root", new TestElement[] {
new TestElement(m4, "m4.1", new TestElement[0]),
new TestElement(m4, "m4.2", true, false, new TestElement[] {
new TestElement(m4, "m4.2.1", true, true, new TestElement[0]),
new TestElement(m4, "m4.2.2", false, true, new TestElement[0]),
new TestElement(m4, "m4.2.3", true, false, new TestElement[0]),
}),
}) );
TestModel m1 = new TestModel();
m1.setRoot( new TestElement(m1, "m1.root", new TestElement[] {
new TestElement(m1, "m1.1", new TestElement[0]),
new TestElement(m1, "m1.2", true, false, new TestElement[] {
m2.fRoot,
m3.fRoot,
m4.fRoot,
}),
}) );
return m1;
}
}

View file

@ -0,0 +1,568 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import junit.framework.Assert;
import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement;
import org.eclipse.debug.internal.ui.viewers.model.ILabelUpdateListener;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IStateUpdateListener;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdateListener;
import org.eclipse.jface.viewers.TreePath;
public class TestModelUpdatesListener
implements IViewerUpdateListener, ILabelUpdateListener, IModelChangedListener, ITestModelUpdatesListenerConstants,
IStateUpdateListener
{
private final static Comparator<String> fStringComparator = new Comparator<String>() {
public int compare(String s1, String s2) {
int l1 = s1.length();
int l2 = s2.length();
int lmin = l1;
int result = 0;
if (l1 < l2) {
result = -1;
} else if (l1 > l2) {
result = 1;
lmin = l2;
}
char c1 = 0;
char c2 = 0;
int i = 0;
for (; i < lmin; i++) {
c1 = s1.charAt(i);
c2 = s2.charAt(i);
if (c1 != c2) {
break;
}
}
if (i == lmin) {
return result;
}
return c1 - c2;
};
};
private final static Comparator<TreePath> fTestElementVMCComparator = new Comparator<TreePath>() {
public int compare(TreePath p1, TreePath p2) {
int l1 = p1.getSegmentCount();
int l2 = p2.getSegmentCount();
int lmin = l1;
int result = 0;
if (l1 < l2) {
result = -1;
} else if (l1 > l2) {
result = 1;
lmin = l2;
}
TestElement e1 = null;
TestElement e2 = null;
int i = 0;
for (; i < lmin; i++) {
e1 = getTestElement(p1.getSegment(i));
e2 = getTestElement(p2.getSegment(i));
if ((e1 == null && e2 != null) || (e1 != null && !e1.equals(e2))) {
break;
}
}
if (i == lmin) {
return result;
}
String id1 = e1 == null ? "" : e1.getID();
String id2 = e2 == null ? "" : e2.getID();
return fStringComparator.compare(id1, id2);
}
private TestElement getTestElement(Object o) {
if (o instanceof TestElement) {
return (TestElement)o;
} else if (o instanceof TestElementVMContext) {
return ((TestElementVMContext)o).getElement();
}
return null;
}
};
private boolean fFailOnRedundantUpdates;
private boolean fFailOnMultipleModelUpdateSequences;
private boolean fFailOnMultipleLabelUpdateSequences;
private Set<TreePath> fHasChildrenUpdates = new TreeSet<TreePath>(fTestElementVMCComparator);
private Map<TreePath, Set<Integer>> fChildrenUpdates = new TreeMap<TreePath, Set<Integer>>(fTestElementVMCComparator);
private Set<TreePath> fChildCountUpdates = new TreeSet<TreePath>(fTestElementVMCComparator);
private Set<TreePath> fLabelUpdates = new TreeSet<TreePath>(fTestElementVMCComparator);
private Set<TestModel> fProxyModels = new HashSet<TestModel>();
private Set<TreePath> fStateUpdates = new TreeSet<TreePath>(fTestElementVMCComparator);
private boolean fViewerUpdatesComplete;
private boolean fLabelUpdatesComplete;
private boolean fModelChangedComplete;
private boolean fStateSaveComplete;
private boolean fStateRestoreComplete;
private int fViewerUpdatesRunning;
private int fLabelUpdatesRunning;
private int fTimeoutInterval = 60000;
private long fTimeoutTime;
public TestModelUpdatesListener(boolean failOnRedundantUpdates, boolean failOnMultipleModelUpdateSequences) {
setFailOnRedundantUpdates(failOnRedundantUpdates);
setFailOnMultipleModelUpdateSequences(failOnMultipleModelUpdateSequences);
}
public void setFailOnRedundantUpdates(boolean failOnRedundantUpdates) {
fFailOnRedundantUpdates = failOnRedundantUpdates;
}
public void setFailOnMultipleModelUpdateSequences(boolean failOnMultipleLabelUpdateSequences) {
fFailOnMultipleModelUpdateSequences = failOnMultipleLabelUpdateSequences;
}
public void setFailOnMultipleLabelUpdateSequences(boolean failOnMultipleLabelUpdateSequences) {
fFailOnMultipleLabelUpdateSequences = failOnMultipleLabelUpdateSequences;
}
/**
* Sets the the maximum amount of time (in milliseconds) that the update listener
* is going to wait. If set to -1, the listener will wait indefinitely.
*/
public void setTimeoutInterval(int milis) {
fTimeoutInterval = milis;
}
public void reset(TreePath path, TestElement element, int levels, boolean failOnRedundantUpdates, boolean failOnMultipleUpdateSequences) {
reset();
addUpdates(path, element, levels);
addProxies(element);
setFailOnRedundantUpdates(failOnRedundantUpdates);
setFailOnMultipleModelUpdateSequences(failOnMultipleUpdateSequences);
setFailOnMultipleLabelUpdateSequences(false);
}
public void reset(boolean failOnRedundantUpdates, boolean failOnMultipleUpdateSequences) {
reset();
setFailOnRedundantUpdates(failOnRedundantUpdates);
setFailOnMultipleModelUpdateSequences(failOnMultipleUpdateSequences);
setFailOnMultipleLabelUpdateSequences(false);
}
public void reset() {
fHasChildrenUpdates.clear();
fChildrenUpdates.clear();
fChildCountUpdates.clear();
fLabelUpdates.clear();
fProxyModels.clear();
fViewerUpdatesComplete = false;
fLabelUpdatesComplete = false;
fStateSaveComplete = false;
fStateRestoreComplete = false;
fTimeoutTime = System.currentTimeMillis() + fTimeoutInterval;
resetModelChanged();
}
public void resetModelChanged() {
fModelChangedComplete = false;
}
public void addHasChildrenUpdate(TreePath path) {
fHasChildrenUpdates.add(path);
}
public void removeHasChildrenUpdate(TreePath path) {
fHasChildrenUpdates.remove(path);
}
public void addChildreCountUpdate(TreePath path) {
fChildCountUpdates.add(path);
}
public void removeChildreCountUpdate(TreePath path) {
fChildCountUpdates.remove(path);
}
public void addChildreUpdate(TreePath path, int index) {
Set<Integer> childrenIndexes = fChildrenUpdates.get(path);
if (childrenIndexes == null) {
childrenIndexes = new TreeSet<Integer>();
fChildrenUpdates.put(path, childrenIndexes);
}
childrenIndexes.add(new Integer(index));
}
public void removeChildrenUpdate(TreePath path, int index) {
Set<Integer> childrenIndexes = fChildrenUpdates.get(path);
if (childrenIndexes != null) {
childrenIndexes.remove(new Integer(index));
if (childrenIndexes.isEmpty()) {
fChildrenUpdates.remove(path);
}
}
}
public void addLabelUpdate(TreePath path) {
fLabelUpdates.add(path);
}
public void removeLabelUpdate(TreePath path) {
fLabelUpdates.remove(path);
}
public void addUpdates(TreePath path, TestElement element, int levels) {
addUpdates(path, element, levels, ALL_UPDATES_COMPLETE);
}
public void addStateUpdates(ITreeModelContentProviderTarget viewer, TreePath path, TestElement element) {
addUpdates(viewer, path, element, -1, STATE_UPDATES);
}
public void addUpdates(TreePath path, TestElement element, int levels, int flags) {
addUpdates(null, path, element, levels, flags);
}
public void addUpdates(ITreeModelContentProviderTarget viewer, TreePath path, TestElement element, int levels, int flags) {
if (!path.equals(TreePath.EMPTY)) {
if ((flags & LABEL_UPDATES) != 0) {
fLabelUpdates.add(path);
}
if ((flags & HAS_CHILDREN_UPDATES) != 0) {
fHasChildrenUpdates.add(path);
}
}
if (levels-- != 0) {
TestElement[] children = element.getChildren();
if (children.length > 0 && (viewer == null || path.getSegmentCount() == 0 || viewer.getExpandedState(path))) {
if ((flags & CHILDREN_COUNT_UPDATES) != 0) {
fChildCountUpdates.add(path);
}
if ((flags & CHILDREN_UPDATES) != 0) {
Set<Integer> childrenIndexes = new HashSet<Integer>();
for (int i = 0; i < children.length; i++) {
childrenIndexes.add(new Integer(i));
}
fChildrenUpdates.put(path, childrenIndexes);
}
if ((flags & STATE_UPDATES) != 0 && viewer != null) {
fStateUpdates.add(path);
}
for (int i = 0; i < children.length; i++) {
addUpdates(viewer, path.createChildPath(children[i]), children[i], levels, flags);
}
}
}
}
private void addProxies(TestElement element) {
TestModel model = element.getModel();
if (model.getModelProxy() == null) {
fProxyModels.add(element.getModel());
}
TestElement[] children = element.getChildren();
for (int i = 0; i < children.length; i++) {
addProxies(children[i]);
}
}
public boolean isFinished() {
return isFinished(ALL_UPDATES_COMPLETE);
}
public boolean isFinished(int flags) {
if (fTimeoutInterval > 0 && fTimeoutTime < System.currentTimeMillis()) {
throw new RuntimeException("Timed Out: " + toString(flags));
}
if ( (flags & LABEL_UPDATES_COMPLETE) != 0) {
if (!fLabelUpdatesComplete) return false;
}
if ( (flags & LABEL_UPDATES) != 0) {
if (!fLabelUpdates.isEmpty()) return false;
}
if ( (flags & CONTENT_UPDATES_COMPLETE) != 0) {
if (!fViewerUpdatesComplete) return false;
}
if ( (flags & HAS_CHILDREN_UPDATES) != 0) {
if (!fHasChildrenUpdates.isEmpty()) return false;
}
if ( (flags & CHILDREN_COUNT_UPDATES) != 0) {
if (!fChildCountUpdates.isEmpty()) return false;
}
if ( (flags & CHILDREN_UPDATES) != 0) {
if (!fChildrenUpdates.isEmpty()) return false;
}
if ( (flags & MODEL_CHANGED_COMPLETE) != 0) {
if (!fModelChangedComplete) return false;
}
if ( (flags & STATE_SAVE_COMPLETE) != 0) {
if (!fStateSaveComplete) return false;
}
if ( (flags & STATE_RESTORE_COMPLETE) != 0) {
if (!fStateRestoreComplete) return false;
}
if ( (flags & MODEL_PROXIES_INSTALLED) != 0) {
if (fProxyModels.size() != 0) return false;
}
if ( (flags & VIEWER_UPDATES_RUNNING) != 0) {
if (fViewerUpdatesRunning != 0) {
return false;
}
}
if ( (flags & LABEL_UPDATES_RUNNING) != 0) {
if (fLabelUpdatesRunning != 0) {
return false;
}
}
return true;
}
public void updateStarted(IViewerUpdate update) {
synchronized (this) {
fViewerUpdatesRunning++;
}
}
public void updateComplete(IViewerUpdate update) {
synchronized (this) {
fViewerUpdatesRunning--;
}
if (!update.isCanceled()) {
if (update instanceof IHasChildrenUpdate) {
if (!fHasChildrenUpdates.remove(update.getElementPath()) && fFailOnRedundantUpdates) {
Assert.fail("Redundant update: " + update);
}
} if (update instanceof IChildrenCountUpdate) {
if (!fChildCountUpdates.remove(update.getElementPath()) && fFailOnRedundantUpdates) {
Assert.fail("Redundant update: " + update);
}
} else if (update instanceof IChildrenUpdate) {
int start = ((IChildrenUpdate)update).getOffset();
int end = start + ((IChildrenUpdate)update).getLength();
Set<Integer> childrenIndexes = fChildrenUpdates.get(update.getElementPath());
if (childrenIndexes != null) {
for (int i = start; i < end; i++) {
childrenIndexes.remove(new Integer(i));
}
if (childrenIndexes.isEmpty()) {
fChildrenUpdates.remove(update.getElementPath());
}
} else if (fFailOnRedundantUpdates) {
Assert.fail("Redundant update: " + update);
}
}
}
}
public void viewerUpdatesBegin() {
}
public void viewerUpdatesComplete() {
if (fFailOnMultipleModelUpdateSequences && fViewerUpdatesComplete) {
Assert.fail("Multiple viewer update sequences detected");
}
fViewerUpdatesComplete = true;
}
public void labelUpdateComplete(ILabelUpdate update) {
synchronized (this) {
fLabelUpdatesRunning--;
}
if (!fLabelUpdates.remove(update.getElementPath()) && fFailOnRedundantUpdates) {
Assert.fail("Redundant update: " + update);
}
}
public void labelUpdateStarted(ILabelUpdate update) {
synchronized (this) {
fLabelUpdatesRunning++;
}
}
public void labelUpdatesBegin() {
}
public void labelUpdatesComplete() {
if (fFailOnMultipleLabelUpdateSequences && fLabelUpdatesComplete) {
Assert.fail("Multiple label update sequences detected");
}
fLabelUpdatesComplete = true;
}
public void modelChanged(IModelDelta delta, IModelProxy proxy) {
fModelChangedComplete = true;
for (Iterator<TestModel> itr = fProxyModels.iterator(); itr.hasNext();) {
TestModel model = itr.next();
if (model.getModelProxy() == proxy) {
itr.remove();
break;
}
}
}
public void stateRestoreUpdatesBegin(Object input) {
}
public void stateRestoreUpdatesComplete(Object input) {
fStateRestoreComplete = true;
}
public void stateSaveUpdatesBegin(Object input) {
}
public void stateSaveUpdatesComplete(Object input) {
fStateSaveComplete = true;
}
public void stateUpdateComplete(Object input, IViewerUpdate update) {
}
public void stateUpdateStarted(Object input, IViewerUpdate update) {
}
private String toString(int flags) {
StringBuffer buf = new StringBuffer("Viewer Update Listener");
if ( (flags & LABEL_UPDATES_COMPLETE) != 0) {
buf.append("\n\t");
buf.append("fLabelUpdatesComplete = " + fLabelUpdatesComplete);
}
if ( (flags & LABEL_UPDATES_RUNNING) != 0) {
buf.append("\n\t");
buf.append("fLabelUpdatesRunning = " + fLabelUpdatesRunning);
}
if ( (flags & LABEL_UPDATES) != 0) {
buf.append("\n\t");
buf.append("fLabelUpdates = ");
buf.append( toString(fLabelUpdates) );
}
if ( (flags & CONTENT_UPDATES_COMPLETE) != 0) {
buf.append("\n\t");
buf.append("fViewerUpdatesComplete = " + fViewerUpdatesComplete);
}
if ( (flags & VIEWER_UPDATES_RUNNING) != 0) {
buf.append("\n\t");
buf.append("fViewerUpdatesRunning = " + fViewerUpdatesRunning);
}
if ( (flags & HAS_CHILDREN_UPDATES) != 0) {
buf.append("\n\t");
buf.append("fHasChildrenUpdates = ");
buf.append( toString(fHasChildrenUpdates) );
}
if ( (flags & CHILDREN_COUNT_UPDATES) != 0) {
buf.append("\n\t");
buf.append("fChildCountUpdates = ");
buf.append( toString(fChildCountUpdates) );
}
if ( (flags & CHILDREN_UPDATES) != 0) {
buf.append("\n\t");
buf.append("fChildrenUpdates = ");
buf.append( toString(fChildrenUpdates) );
}
if ( (flags & MODEL_CHANGED_COMPLETE) != 0) {
buf.append("\n\t");
buf.append("fModelChangedComplete = " + fModelChangedComplete);
}
if ( (flags & STATE_SAVE_COMPLETE) != 0) {
buf.append("\n\t");
buf.append("fStateSaveComplete = " + fStateSaveComplete);
}
if ( (flags & STATE_RESTORE_COMPLETE) != 0) {
buf.append("\n\t");
buf.append("fStateRestoreComplete = " + fStateRestoreComplete);
}
if ( (flags & MODEL_PROXIES_INSTALLED) != 0) {
buf.append("\n\t");
buf.append("fProxyModels = " + fProxyModels);
}
if (fTimeoutInterval > 0) {
buf.append("\n\t");
buf.append("fTimeoutInterval = " + fTimeoutInterval);
}
return buf.toString();
}
private String toString(Set<TreePath> set) {
if (set.isEmpty()) {
return "(EMPTY)";
}
StringBuffer buf = new StringBuffer();
for (Iterator<TreePath> itr = set.iterator(); itr.hasNext(); ) {
buf.append("\n\t\t");
buf.append(toString(itr.next()));
}
return buf.toString();
}
private String toString(Map<TreePath, Set<Integer>> map) {
if (map.isEmpty()) {
return "(EMPTY)";
}
StringBuffer buf = new StringBuffer();
for (Iterator<TreePath> itr = map.keySet().iterator(); itr.hasNext(); ) {
buf.append("\n\t\t");
TreePath path = itr.next();
buf.append(toString(path));
Set<?> updates = map.get(path);
buf.append(" = ");
buf.append(updates.toString());
}
return buf.toString();
}
private String toString(TreePath path) {
if (path.getSegmentCount() == 0) {
return "/";
}
StringBuffer buf = new StringBuffer();
for (int i = 0; i < path.getSegmentCount(); i++) {
buf.append("/");
buf.append(path.getSegment(i));
}
return buf.toString();
}
@Override
public String toString() {
return toString(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE | STATE_RESTORE_COMPLETE);
}
}

View file

@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
*
*/
public class TestModelVMAdapter extends AbstractVMAdapter {
@Override
protected IVMProvider createViewModelProvider(IPresentationContext context) {
return new TestModelVMProvider(this, context);
}
public TestModelVMProvider getTestModelProvider(IPresentationContext context) {
return (TestModelVMProvider)getVMProvider(context);
}
}

View file

@ -0,0 +1,131 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
/**
*
*/
public class TestModelVMNode extends AbstractVMNode implements IRootVMNode, IElementLabelProvider, IElementPropertiesProvider {
final private static String PROP_TEST_ELEMENT_LABEL = "PROP_TEST_ELEMENT_LABEL";
final private static PropertiesBasedLabelProvider fLabelProvider = new PropertiesBasedLabelProvider();
{
fLabelProvider.setColumnInfo(
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
new LabelColumnInfo(new LabelAttribute[] {
new LabelText("{0}", new String[] { PROP_TEST_ELEMENT_LABEL })
}));
}
public void update(final ILabelUpdate[] updates) {
fLabelProvider.update(updates);
}
public TestModelVMNode(IVMProvider provider) {
super(provider);
}
public void update(IHasChildrenUpdate[] updates) {
for (IHasChildrenUpdate update : updates) {
if (update.getElement() instanceof TestElementVMContext) {
TestElement element = ((TestElementVMContext)update.getElement()).getElement();
update.setHasChilren(element.getChildren().length != 0);
}
update.done();
}
}
public void update(IChildrenCountUpdate[] updates) {
for (IChildrenCountUpdate update : updates) {
if (update.getElement() instanceof TestElementVMContext) {
TestElement element = ((TestElementVMContext)update.getElement()).getElement();
update.setChildCount(element.getChildren().length);
}
update.done();
}
}
public void update(IChildrenUpdate[] updates) {
for (IChildrenUpdate update : updates) {
if (update.getElement() instanceof TestElementVMContext) {
TestElement element = ((TestElementVMContext)update.getElement()).getElement();
fillUpdateWithTestElements(update, element.getChildren());
}
update.done();
}
}
public void update(IPropertiesUpdate[] updates) {
for (IPropertiesUpdate update : updates) {
if (update.getElement() instanceof TestElementVMContext) {
TestElement element = ((TestElementVMContext)update.getElement()).getElement();
update.setProperty(PROP_TEST_ELEMENT_LABEL, element.getLabel());
}
update.done();
}
}
private void fillUpdateWithTestElements(IChildrenUpdate update, TestElement[] elements) {
int updateIdx = update.getOffset() != -1 ? update.getOffset() : 0;
int endIdx = updateIdx + (update.getLength() != -1 ? update.getLength() : elements.length);
while (updateIdx < endIdx && updateIdx < elements.length) {
update.setChild(createVMContext(elements[updateIdx]), updateIdx);
updateIdx++;
}
}
public TestElementVMContext createVMContext(TestElement element) {
return new TestElementVMContext(this, element);
}
public int getDeltaFlags(Object event) {
return 0;
}
public void buildDelta(Object event, VMDelta parent, int nodeOffset, RequestMonitor rm) {
rm.done();
}
public boolean isDeltaEvent(Object rootObject, Object event) {
return false;
}
public void createRootDelta(Object rootObject, Object event, DataRequestMonitor<VMDelta> rm) {
rm.setStatus(new Status(IStatus.ERROR, TestDsfVMPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, "Not implemented", null));
rm.done();
}
}

View file

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMModelProxy;
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
import org.eclipse.cdt.tests.dsf.vm.TestModel.TestElement;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
/**
*
*/
public class TestModelVMProvider extends AbstractVMProvider {
public TestModelVMProvider(AbstractVMAdapter adapter, IPresentationContext context) {
super(adapter, context);
setRootNode(new TestModelVMNode(this));
addChildNodes(getRootVMNode(), new IVMNode[] { getRootVMNode() });
}
public TestElementVMContext getElementVMContext(IPresentationContext context, TestElement element) {
return ((TestModelVMNode)getRootVMNode()).createVMContext(element);
}
public void postDelta(IModelDelta delta) {
for (IVMModelProxy proxy : getActiveModelProxies()) {
proxy.fireModelChanged(delta);
}
}
}

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.vm;
import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget;
import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.VirtualTreeModelViewer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* @since 3.6
*/
public class VirtualViewerPerformanceTests extends PerformanceTests {
public VirtualViewerPerformanceTests(String name) {
super(name);
}
@Override
protected ITreeModelContentProviderTarget createViewer(Display display, Shell shell) {
return new VirtualTreeModelViewer(fDisplay, 0, new PresentationContext("TestViewer"));
}
@Override
protected int getTestModelDepth() {
return 7;
}
}