Ongoing performance test suite work
diff --git a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CSVPerformanceTestResult.java b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CSVPerformanceTestResult.java
new file mode 100644
index 0000000..926e48d
--- /dev/null
+++ b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CSVPerformanceTestResult.java
@@ -0,0 +1,67 @@
+/**********************************************************************
+ * Copyright (c) 2003 IBM Corporation and others. All rights reserved.   This
+ * program and the accompanying materials are made available under the terms of
+ * the Common Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.core.tests.harness;
+
+import java.io.*;
+import java.io.File;
+import java.io.PrintWriter;
+import java.util.Iterator;
+
+/**
+ * Performance test result that appends timing results to a CSV (comma separated
+ * value) file suitable for use by spreadsheet applications.
+ */
+public class CSVPerformanceTestResult extends PerformanceTestResult {
+	private String timingFile;
+	private String memoryFile;
+
+	public CSVPerformanceTestResult(String timingFile, String memoryFile) {
+		this.timingFile = timingFile;
+		this.memoryFile = memoryFile;
+	}
+	protected void printTimings(PrintWriter out) {
+		super.printTimings(out);
+		// print out all timing results to the csv files
+		try {
+			boolean newFiles = !new File(timingFile).exists();
+			FileWriter timingOut = new FileWriter(timingFile, true);
+			FileWriter memoryOut = new FileWriter(memoryFile, true);
+			try {
+				if (newFiles)
+					writeHeaders(timingOut, memoryOut);
+				for (Iterator it = timerList.iterator(); it.hasNext();) {
+					PerformanceTimer timer = (PerformanceTimer) it.next();
+					timingOut.write(',');
+					timingOut.write(Long.toString(timer.getAverageElapsedTime()));
+					memoryOut.write(',');
+					memoryOut.write(Long.toString(timer.getAverageMemoryGrowth()));
+				}
+				timingOut.write("\n");
+				memoryOut.write("\n");
+			} finally {
+				timingOut.close();
+				memoryOut.close();
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	private void writeHeaders(FileWriter timingOut, FileWriter memoryOut) throws IOException {
+		for (Iterator it = timerList.iterator(); it.hasNext();) {
+			PerformanceTimer timer = (PerformanceTimer) it.next();
+			timingOut.write(',');
+			timingOut.write(timer.getName());
+			memoryOut.write(',');
+			memoryOut.write(timer.getName());
+		}		
+		timingOut.write("\n");
+		memoryOut.write("\n");
+	}
+}
\ No newline at end of file
diff --git a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CorePerformanceTest.java b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CorePerformanceTest.java
index 6a37c00..3849b99 100644
--- a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CorePerformanceTest.java
+++ b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/CorePerformanceTest.java
@@ -37,14 +37,14 @@
  *	</code>
  * Note that only one operation can be tested at a time with this mechanism.
  *
- * If an instance of this class is run using a LoggingPerformanceTestResult,
+ * If an instance of this class is run using a HTMLPerformanceTestResult,
  * an HTML log file will be maintained of all timing and garbage collecting,
  * in addition to any messages added using the log() method.  In the absence
  * of a logging test result, all log events are written to the standard output.
  */
 public abstract class CorePerformanceTest extends EclipseWorkspaceTest {
 	protected long benchStart;
-	protected LoggingPerformanceTestResult logger = null;
+	protected HTMLPerformanceTestResult logger = null;
 	protected PerformanceTestResult result = null;
 
 	public CorePerformanceTest() {
@@ -52,43 +52,30 @@
 	public CorePerformanceTest(String name) {
 		super(name);
 	}
-	protected PerformanceTestResult defaultTest() {
+	protected TestResult createResult() {
 		return new PerformanceTestResult();
 	}
 	/**
-	 * Logs or writes string to console.
-	 */
-	public void perfLog(String s) {
-		if (logger != null) {
-			logger.log(s);
-		} else {
-			System.out.println(s);
-		}
-	}
-	/**
 	 * A convenience method to run this test, collecting the results with a
 	 * default PerformanceTestResult object.
 	 *
 	 * @see PerformanceTestResult
 	 */
 	public TestResult run() {
-		PerformanceTestResult test = defaultTest();
-		run(test);
-		return test;
+		TestResult result = createResult();
+		run(result);
+		return result;
 	}
 	/**
 	 * Runs the test case and collects the results in a PerformanceTestResult.
 	 * This is the template method that defines the control flow
 	 * for running a test case.
 	 */
-	public void run(PerformanceTestResult test) {
-		result = test;
-
-		if (test instanceof LoggingPerformanceTestResult) {
-			logger = (LoggingPerformanceTestResult) test;
+	public void run(TestResult result) {
+		if (result instanceof PerformanceTestResult) {
+			this.result = (PerformanceTestResult)result;
 		}
-
-		super.run(test);
+		super.run(result);
 	}
 	protected void startBench() {
 		for (int i = 0; i < 20; ++i) {
@@ -102,7 +89,8 @@
 	 * and starts it running.
 	 */
 	protected void startTimer(String timerName) {
-		result.startTimer(timerName);
+		if (result != null)
+			result.startTimer(timerName);
 	}
 	protected void stopBench(String benchName, int numOperations) {
 		long duration = System.currentTimeMillis() - benchStart;
@@ -122,6 +110,7 @@
 	 * Tell the result to stop the timer with the given name.
 	 */
 	protected void stopTimer(String timerName) {
-		result.stopTimer(timerName);
+		if (result != null)
+			result.stopTimer(timerName);
 	}
 }
\ No newline at end of file
diff --git a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/LoggingPerformanceTestResult.java b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/HTMLPerformanceTestResult.java
similarity index 80%
rename from tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/LoggingPerformanceTestResult.java
rename to tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/HTMLPerformanceTestResult.java
index 301b091..cf9420c 100644
--- a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/LoggingPerformanceTestResult.java
+++ b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/HTMLPerformanceTestResult.java
@@ -16,11 +16,11 @@
 
 import junit.framework.TestFailure;
 /**
- * A LoggingPerformanceTestResult adds the ability to create an HTML or
+ * A HTMLPerformanceTestResult adds the ability to create an HTML or
  * other output file, and have test results written to that file instead
  * of the standard output.
  */
-public class LoggingPerformanceTestResult extends PerformanceTestResult {
+public class HTMLPerformanceTestResult extends PerformanceTestResult {
 	private static PrintWriter createWriter(File logFile) {
 		try {
 			PrintWriter writer = new PrintWriter(new FileOutputStream(logFile), true);
@@ -30,7 +30,7 @@
 			return new PrintWriter(System.out, true);
 		}
 	}
-	public LoggingPerformanceTestResult(File logFile) {
+	public HTMLPerformanceTestResult(File logFile) {
 		super(createWriter(logFile));
 		printHTMLHeader(output);
 	}
@@ -127,27 +127,8 @@
 		// print out all timing results to the console
 		for (Iterator it = timerList.iterator(); it.hasNext();) {
 			PerformanceTimer timer = (PerformanceTimer) it.next();
-			out.println("<li>" + timer.getName() + " : " + timer.getElapsedTime() + " ms</li>");
+			out.println("<li>" + timer.getName() + " : " + timer.getTotalElapsedTime() + " ms</li>");
 		}
 		out.println("</ul>");
 	}
-	/**
-	 * Start the timer with the given name.  If the timer has already
-	 * been created, send it a startTiming message.  If not, create it
-	 * and send the new timer the startTiming message.
-	 */
-
-	public synchronized void startTimer(String timerName) {
-		super.startTimer(timerName);
-		//log("Starting timer: " + timerName);
-	}
-	/**
-	 * Look up the timer with the given name and send it a stopTiming
-	 * message.  If the timer does not exist, report an error.
-	 */
-
-	public synchronized void stopTimer(String timerName) {
-		super.stopTimer(timerName);
-		//log("Stopping timer: " + timerName);
-	}
 }
diff --git a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTestResult.java b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTestResult.java
index a02a1bb..04e9491 100644
--- a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTestResult.java
+++ b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTestResult.java
@@ -34,13 +34,13 @@
 	 * Informs the result that a test was completed.
 	 */
 	public synchronized void endTest(Test test) {
+		stopTimers();
 		print();
 	}
 	/**
 	 * Prints the test result
 	 */
-	public synchronized void print() {
-		stopTimers();
+	protected synchronized void print() {
 		printHeader(output);
 		printErrors(output);
 		printFailures(output);
@@ -104,7 +104,7 @@
 		// print out all timing results to the console
 		for (Iterator it = timerList.iterator(); it.hasNext();) {
 			PerformanceTimer timer = (PerformanceTimer) it.next();
-			out.println("Timing " + timer.getName() + " : " + timer.getElapsedTime() + " ms ");
+			out.println("Timing " + timer.getName() + " : " + timer.getTotalElapsedTime() + " ms ");
 		}
 	}
 	/**
@@ -112,7 +112,6 @@
 	 */
 	public synchronized void startTest(Test test) {
 		super.startTest(test);
-		System.out.print(".");
 	}
 	/**
 	 * Start the timer with the given name.  If the timer has already
diff --git a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTimer.java b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTimer.java
index cebe7d3..dc56438 100644
--- a/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTimer.java
+++ b/tests/org.eclipse.core.tests.harness/src/org/eclipse/core/tests/harness/PerformanceTimer.java
@@ -1,9 +1,9 @@
 /**********************************************************************
- * Copyright (c) 2000, 2002 IBM Corporation and others.
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
  * All rights reserved.   This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
  * 
  * Contributors: 
  * IBM - Initial API and implementation
@@ -14,42 +14,83 @@
  * The timer class used by performance tests.
  */
 class PerformanceTimer {
-	private String fName;
-	private long fElapsedTime;
-	private long fStartTime;
-/**
- * 
- */
-public PerformanceTimer(String name) {
-	fName = name;
-	fElapsedTime = 0;
-	fStartTime = 0;
-}
-/**
- * Return the elapsed time.
- */
-public long getElapsedTime() {
-	return fElapsedTime;
-}
-/**
- * Return the timer name.
- */
-public String getName() {
-	return fName;
-}
-/**
- * Start the timer.
- */
-public void startTiming() {
-	fStartTime = System.currentTimeMillis();
-}
-/**
- * Stop the timer, add the elapsed time to the total.
- */
-public void stopTiming() {
-	if (fStartTime == 0) return;
-	long timeNow = System.currentTimeMillis();
-	fElapsedTime += (timeNow - fStartTime);
-	fStartTime = 0;
-}
-}
+	private long elapsedTime;
+	private long memoryGrowth;
+	private String name;
+	private long startMemory;
+	private long startTime;
+	private int repeats = 0;
+	/**
+	 * 
+	 */
+	public PerformanceTimer(String name) {
+		this.name = name;
+		elapsedTime = 0;
+		startTime = 0;
+		startMemory = 0;
+		memoryGrowth = 0;
+	}
+	public void gc() {
+		System.gc();
+		System.runFinalization();
+		System.gc();
+	}
+	/**
+	 * Return the total elapsed time for all runs.
+	 */
+	public long getTotalElapsedTime() {
+		return elapsedTime;
+	}
+	/**
+	 * Return the average elapsed time over all runs
+	 */
+	public long getAverageElapsedTime() {
+		if (repeats <= 0)
+			return 0l;
+		return elapsedTime / repeats;
+	}
+	/**
+	 * Return the timer name.
+	 */
+	public String getName() {
+		return name;
+	}
+	/**
+	 * Start the timer.
+	 */
+	public void startTiming() {
+		repeats++;
+		gc();
+		startTime = System.currentTimeMillis();
+		startMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+	}
+	/**
+	 * Stop the timer, add the elapsed time to the total.
+	 */
+	public void stopTiming() {
+		if (startTime == 0)
+			return;
+		long timeNow = System.currentTimeMillis();
+		elapsedTime += (timeNow - startTime);
+		startTime = 0;
+		
+		gc();
+		long endMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
+		memoryGrowth += (endMemory - startMemory);
+		startMemory = 0;
+	}
+	/**
+	 * Returns the overall memory growth for all runs
+	 */
+	public long getTotalMemoryGrowth() {
+		return memoryGrowth;
+	}
+	/**
+	 * Returns the average memory growth for all runs
+	 */
+	public long getAverageMemoryGrowth() {
+		if (repeats <= 0)
+			return 0l;
+		return memoryGrowth / repeats;
+	}
+}
\ No newline at end of file