blob: 05788c403d1ea8a03e38212c04633d1cba1c7232 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation 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:
* IBM Corporation - initial API and implementation
* James Blackburn (Broadcom Corp.) - ongoing development
*******************************************************************************/
package org.eclipse.core.tests.resources.perf;
import java.util.Vector;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.internal.watson.ElementTree;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.tests.harness.PerformanceTestRunner;
import org.eclipse.core.tests.resources.OldCorePerformanceTest;
/**
* Benchmarks for <code>ElementTree</code>.
*/
public class BenchElementTree extends OldCorePerformanceTest {
static String[] javaLangUnits = {"AbstractMethodError.java", "ArithmeticException.java", "ArrayIndexOutOfBoundsException.java", "ArrayStoreException.java", "Boolean.java", //
"Byte.java", "Character.java", "Class.java", "ClassCastException.java", "ClassCircularityError.java", "ClassFormatError.java", "ClassLoader.java", "ClassNotFoundException.java", //
"Cloneable.java", "CloneNotSupportedException.java", "Compiler.java", "Double.java", "Error.java", "Exception.java", "ExceptionInInitializerError.java", "Float.java", "FloatingDecimal.java", //
"IllegalAccessError.java", "IllegalAccessException.java", "IllegalArgumentException.java", "IllegalMonitorStateException.java", "IllegalStateException.java", "IllegalThreadStateException.java", //
"IncompatibleClassChangeError.java", "IndexOutOfBoundsException.java", "InstantiationError.java", "InstantiationException.java", "Integer.java", "InternalError.java", "InterruptedException.java", //
"LinkageError.java", "Long.java", "Math.java", "NegativeArraySizeException.java", "NoClassDefFoundError.java", "NoSuchFieldError.java", "NoSuchFieldException.java", "NoSuchMethodError.java", //
"NoSuchMethodException.java", "NullPointerException.java", "Number.java", "NumberFormatException.java", "Object.java", "OutOfMemoryError.java", "Process.java", "Runnable.java", //
"Runtime.java", "RuntimeException.java", "SecurityException.java", "SecurityManager.java", "Short.java", "StackOverflowError.java", "String.java", "StringBuffer.java", //
"StringIndexOutOfBoundsException.java", "System.java", "Thread.java", "ThreadDeath.java", "ThreadGroup.java", "Throwable.java", "UnknownError.java", "UnsatisfiedLinkError.java", //
"VerifyError.java", "VirtualMachineError.java", "Void.java"};
static final IPath solution = Path.ROOT.append("solution");
static final IPath project = solution.append("project");
static final IPath folder = project.append("folder");
static final IPath[] files = getFilePaths();
public BenchElementTree() {
super();
}
public BenchElementTree(String name) {
super(name);
}
/**
* Tests the performance of the createElement operation.
*/
public void testCreateElement() {
new PerformanceTestRunner() {
@Override
protected void test() {
createTestTree(false);
}
}.run(this, 10, 400);
}
/**
* Tests the performance of the deleteElement operation.
*/
public void benchDeleteElement() {
final int repeat = 400;
/* create copies of the original tree */
ElementTree[] trees = new ElementTree[repeat];
for (int i = 0; i < repeat; i++) {
trees[i] = createTestTree(false);
}
startBench();
for (int rep = repeat; --rep >= 0;) {
for (IPath file : files) {
trees[rep].deleteElement(file);
}
}
stopBench("benchDeleteElement", repeat * files.length);
}
/**
* Tests the performance of the getElementData operation.
*/
public void benchGetElementData() {
final int repeat = 500;
ElementTree tree = createTestTree(false);
startBench();
for (int rep = repeat; --rep >= 0;) {
for (IPath file : files) {
tree.getElementData(file);
}
}
stopBench("benchGetElementData", repeat * files.length);
}
/**
* Tests the performance of the mergeDeltaChain operation.
*/
public void benchMergeDeltaChain() {
final int repeat = 50;
/* create all the test trees */
ElementTree[] bases = new ElementTree[repeat];
ElementTree[][] chains = new ElementTree[repeat][];
for (int i = 0; i < repeat; i++) {
bases[i] = createTestTree(true);
chains[i] = buildDeltaChain(createTestTree(false));
}
startBench();
for (int i = repeat; --i >= 0;) {
bases[i].mergeDeltaChain(folder, chains[i]);
}
stopBench("benchMergeDeltaChain", repeat);
}
/**
* Tests a typical series of ElementTree operations, where
* a new delta is generated for each operation.
*/
public void benchRoutineOperations() {
final int repeat = 75;
int opCount = 0;
startBench();
for (int i = 0; i < repeat; i++) {
opCount += doRoutineOperations();
}
stopBench("benchRoutineOperations", opCount);
}
/**
* Tests the performance of the setElementData operation.
*/
public void benchSetElementData() {
ElementTree tree = createTestTree(false);
Object data = new Object();
startBench();
for (int rep = 500; --rep >= 0;) {
for (IPath file : files) {
tree.setElementData(file, data);
}
}
stopBench("benchSetElementData", 500 * files.length);
}
/**
* Does several routine operations on the given tree.
* Returns an array of all the intermediary element trees.
*/
private ElementTree[] buildDeltaChain(ElementTree tree) {
Vector<ElementTree> trees = new Vector<>();
trees.addElement(tree);
int repeat = 1;
/* create file elements */
tree = tree.newEmptyDelta();
IPath[] filePaths = getFilePaths();
for (IPath filePath : filePaths) {
Object data = filePath.toString();
tree.createElement(filePath, data);
tree.immutable();
trees.addElement(tree);
tree = tree.newEmptyDelta();
}
/* modify the data of all file elements a few times */
for (int i = 0; i < repeat; i++) {
Object data = "data" + i;
for (IPath filePath : filePaths) {
tree.setElementData(filePath, data);
tree.immutable();
trees.addElement(tree);
tree = tree.newEmptyDelta();
}
}
/* delete all file elements */
for (IPath filePath : filePaths) {
tree.deleteElement(filePath);
tree.immutable();
trees.addElement(tree);
tree = tree.newEmptyDelta();
}
ElementTree[] results = new ElementTree[trees.size()];
trees.copyInto(results);
return results;
}
/**
* Creates a test element tree. If withDeltas is true,
* a new delta is created after each operation.
*/
ElementTree createTestTree(boolean withDeltas) {
ElementTree tree = new ElementTree();
Object data = new Object();
tree.createElement(solution, data);
if (withDeltas) {
tree.immutable();
tree = tree.newEmptyDelta();
}
tree.createElement(project, data);
if (withDeltas) {
tree.immutable();
tree = tree.newEmptyDelta();
}
tree.createElement(folder, data);
for (String javaLangUnit : javaLangUnits) {
if (withDeltas) {
tree.immutable();
tree = tree.newEmptyDelta();
}
IPath file = folder.append(javaLangUnit);
tree.createElement(file, data);
}
return tree;
}
/**
* Tests a typical series of ElementTree operations, where
* a new delta is generated for each operation.
* Returns the number of basic ElementTree operations performed.
*/
private int doRoutineOperations() {
ElementTree tree = createTestTree(true);
int repeat = 1;
/* modify the data of all file elements a few times */
for (int i = 0; i < repeat; i++) {
Object data = "data" + i;
for (IPath file : files) {
tree = tree.newEmptyDelta();
tree.setElementData(file, data);
tree.immutable();
}
}
/* delete all file elements */
for (IPath file : files) {
tree = tree.newEmptyDelta();
tree.deleteElement(file);
tree.immutable();
}
return (repeat + 2) * files.length;
}
static IPath[] getFilePaths() {
IPath[] jcuIDs = new IPath[javaLangUnits.length];
for (int i = 0, len = javaLangUnits.length; i < len; ++i) {
jcuIDs[i] = folder.append(javaLangUnits[i]);
}
return jcuIDs;
}
/**
* The environment should be set-up in the main method.
*/
@Override
protected void setUp() throws Exception {
//benchmarks don't use the core testing infrastructure
}
public static Test suite() {
TestSuite suite = new TestSuite(BenchElementTree.class.getName());
suite.addTest(new BenchElementTree("benchCreateElement"));
suite.addTest(new BenchElementTree("benchDeleteElement"));
suite.addTest(new BenchElementTree("benchDeltaLargeTreeFewChanges"));
suite.addTest(new BenchElementTree("benchDeltaLargeTreeManyChangesInOneLayer"));
suite.addTest(new BenchElementTree("benchDeltaSmallTreeManyChangesInSeperateLayers"));
suite.addTest(new BenchElementTree("benchGetElementData"));
// suite.addTest(new BenchElementTree("benchMergeDeltaChain"));
suite.addTest(new BenchElementTree("benchReverseDeltaLargeTreeFewChanges"));
suite.addTest(new BenchElementTree("benchReverseDeltaLargeTreeManyChangesInOneLayer"));
suite.addTest(new BenchElementTree("benchReverseDeltaSmallTreeManyChangesInSeperateLayers"));
suite.addTest(new BenchElementTree("benchRoutineOperations"));
suite.addTest(new BenchElementTree("benchSetElementData"));
return suite;
}
/**
*
*/
@Override
protected void tearDown() throws Exception {
//ElementTree tests don't use the CoreTest infrastructure
}
}