Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/dsf
diff options
context:
space:
mode:
authorPawel Piech2010-03-24 18:43:58 +0000
committerPawel Piech2010-03-24 18:43:58 +0000
commit04709d28763d09409474ce654fab8db9a1ab09d9 (patch)
tree6f0ac4961bba009712aa03488e0fdde26b63ea90 /dsf
parent79c61294f9f19b0e931465d940a8fd4ba71fcca3 (diff)
downloadorg.eclipse.cdt-04709d28763d09409474ce654fab8db9a1ab09d9.tar.gz
org.eclipse.cdt-04709d28763d09409474ce654fab8db9a1ab09d9.tar.xz
org.eclipse.cdt-04709d28763d09409474ce654fab8db9a1ab09d9.zip
[306982] - [concurrent] DsfRunnable.finalize() method increases the cost of garbage collecting 10x
Diffstat (limited to 'dsf')
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs10
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF5
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/RmPerformanceTests.java96
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/ITestModelUpdatesListenerConstants.java40
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/JFaceViewerPerformanceTests.java38
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/PerformanceTests.java222
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestDsfVMPlugin.java52
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementVMContext.java42
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModel.java669
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelUpdatesListener.java568
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMAdapter.java30
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMNode.java131
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMProvider.java42
-rw-r--r--dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/VirtualViewerPerformanceTests.java37
14 files changed, 1978 insertions, 4 deletions
diff --git a/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs b/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs
index 8f1321e3841..cc70a3b2f7c 100644
--- a/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs
+++ b/dsf/org.eclipse.cdt.tests.dsf/.settings/org.eclipse.jdt.core.prefs
@@ -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
diff --git a/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF
index 2f93d176480..75a63b8abfe 100644
--- a/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF
+++ b/dsf/org.eclipse.cdt.tests.dsf/META-INF/MANIFEST.MF
@@ -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
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/RmPerformanceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/RmPerformanceTests.java
new file mode 100644
index 00000000000..ca91c3c9f61
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/concurrent/RmPerformanceTests.java
@@ -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();
+ }
+ }
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/ITestModelUpdatesListenerConstants.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/ITestModelUpdatesListenerConstants.java
new file mode 100644
index 00000000000..c1b1893e9cf
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/ITestModelUpdatesListenerConstants.java
@@ -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;
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/JFaceViewerPerformanceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/JFaceViewerPerformanceTests.java
new file mode 100644
index 00000000000..854b1683bc8
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/JFaceViewerPerformanceTests.java
@@ -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;
+ }
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/PerformanceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/PerformanceTests.java
new file mode 100644
index 00000000000..9c4eb4141a1
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/PerformanceTests.java
@@ -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;
+ }
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestDsfVMPlugin.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestDsfVMPlugin.java
new file mode 100644
index 00000000000..6c3d3e09751
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestDsfVMPlugin.java
@@ -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;
+ }
+
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementVMContext.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementVMContext.java
new file mode 100644
index 00000000000..86a99768dc3
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestElementVMContext.java
@@ -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;
+ }
+
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModel.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModel.java
new file mode 100644
index 00000000000..4875f378e1f
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModel.java
@@ -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;
+ }
+
+
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelUpdatesListener.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelUpdatesListener.java
new file mode 100644
index 00000000000..090c264f78c
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelUpdatesListener.java
@@ -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);
+ }
+}
+
+
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMAdapter.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMAdapter.java
new file mode 100644
index 00000000000..97e83b37a23
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMAdapter.java
@@ -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);
+ }
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMNode.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMNode.java
new file mode 100644
index 00000000000..52dc0dcced2
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMNode.java
@@ -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();
+ }
+
+
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMProvider.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMProvider.java
new file mode 100644
index 00000000000..42cbe47bf88
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/TestModelVMProvider.java
@@ -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);
+ }
+ }
+}
diff --git a/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/VirtualViewerPerformanceTests.java b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/VirtualViewerPerformanceTests.java
new file mode 100644
index 00000000000..4dbdc8bd6fc
--- /dev/null
+++ b/dsf/org.eclipse.cdt.tests.dsf/src/org/eclipse/cdt/tests/dsf/vm/VirtualViewerPerformanceTests.java
@@ -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;
+ }
+}

Back to the top