1402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*******************************************************************************
2402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Copyright (c) 2000, 2009 IBM Corporation and others.
3402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * All rights reserved. This program and the accompanying materials
4402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * are made available under the terms of the Eclipse Public License v1.0
5402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * which accompanies this distribution, and is available at
6402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * http://www.eclipse.org/legal/epl-v10.html
7402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
8402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Contributors:
9402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *     IBM Corporation - initial API and implementation
10402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *******************************************************************************/
11402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpackage org.eclipse.test.internal.performance.results.db;
12402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
13402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.BufferedInputStream;
14402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.BufferedOutputStream;
15402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.DataInputStream;
16402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.DataOutputStream;
17402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.File;
18402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.FileInputStream;
19402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.FileNotFoundException;
20402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.FileOutputStream;
21402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.IOException;
22402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.PrintStream;
23402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.util.*;
24402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
25402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.core.runtime.IProgressMonitor;
26402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.core.runtime.OperationCanceledException;
27402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.core.runtime.SubMonitor;
28402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.test.internal.performance.results.utils.Util;
29402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
30402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
31402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
32402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Root class to handle performance results.
33402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
34402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Usually performance results are built for a current build vs. a baseline build.
35402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
36402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * This class allow to read all data from releng performance database for given
37402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * configurations and scenario pattern.
38402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
39402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Then it provides easy and speedy access to all stored results.
40402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
41402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic class PerformanceResults extends AbstractResults {
42402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
43402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String[] allBuildNames = null;
44402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	Map allScenarios;
45402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String lastBuildName; // Name of the last used build
46402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String baselineName; // Name of the baseline build used for comparison
47402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String baselinePrefix;
48402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String scenarioPattern = "%"; //$NON-NLS-1$
49402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String[] components;
50402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String[] configNames, sortedConfigNames;
51402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String[] configDescriptions, sortedConfigDescriptions;
52402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	private String configPattern;
53402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
54402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	boolean dbRequired;
55402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	boolean needToUpdateLocalFile;
56402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
57402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	/*
58402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	 * Local class helping to guess remaining time while reading results from DB
59402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	 */
60402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	class RemainingTimeGuess {
61402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int all, count;
62402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		long start;
63402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		double remaining;
64402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		RemainingTimeGuess(int all, long start) {
65402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.all = all;
66402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.start = start;
67402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
68402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String display() {
69402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			StringBuffer buffer = new StringBuffer(" [elapsed: "); //$NON-NLS-1$
70402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			long elapsed = getElapsed();
71402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			buffer.append(Util.timeChrono(elapsed));
72402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (this.count > 0) {
73402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				buffer.append(" | left: "); //$NON-NLS-1$
74402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				long remainingTime = getRemainingTime(elapsed);
75402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				buffer.append(Util.timeChrono(remainingTime));
76402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				buffer.append(" | end: "); //$NON-NLS-1$
77402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				buffer.append(Util.timeEnd(remainingTime));
78402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
79402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			buffer.append(']');
80402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			return buffer.toString();
81402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
82402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		private long getRemainingTime(long elapsed) {
83402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			return (long) ((((double)elapsed) / this.count) * (this.all - this.count));
84402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	    }
85402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		private long getElapsed() {
86402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			return System.currentTimeMillis() - this.start;
87402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	    }
88402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
89402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
90402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
91402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Failure threshold
92402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	public static final int DEFAULT_FAILURE_THRESHOLD = 10;
93402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int failure_threshold = DEFAULT_FAILURE_THRESHOLD;
94402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
95402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic PerformanceResults(PrintStream stream) {
96402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	super(null, null);
97402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.printStream = stream;
98402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.dbRequired = false;
99402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	setDefaults();
100402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
101402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
102402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic PerformanceResults(String name, String baseline, String baselinePrefix, PrintStream stream) {
103402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	super(null, name);
104402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.baselineName = baseline;
105402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.baselinePrefix = baselinePrefix;
106402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.printStream = stream;
107402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.dbRequired = true;
108402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	setDefaults();
109402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
110402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
111402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
112402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Returns the list of all builds currently read.
113402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
114402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return The names list of all currently known builds
115402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
116402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String[] getAllBuildNames() {
117402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.allBuildNames == null) {
118402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		setAllBuildNames();
119402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
120402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.allBuildNames;
121402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
122402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
123402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
124402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Returns the name of the baseline used for extracted results
125402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
126402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return The build name of the baseline of <code>null</code>
127402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	if no specific baseline is used for the extracted results.
128402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
129402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String getBaselineName() {
130402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.baselineName;
131402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
132402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
133402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*
134402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Get the baseline prefix (computed from #baselineName).
135402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
136402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael MollString getBaselinePrefix() {
137402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.baselinePrefix;
138402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
139402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
140402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*
141402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Get the build date (see #getBuildDate(String, String)).
142402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
143402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String getBuildDate() {
144402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String buildName = getName();
145402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (buildName == null) return ""; //$NON-NLS-1$
146402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return Util.getBuildDate(getName(), getBaselinePrefix());
147402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
148402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
149402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
150402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Return the list of components concerned by performance results.
151402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
152402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return The list of the components
153402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
154402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String[] getComponents() {
155402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.components;
156402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
157402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
158402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
159402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Get the scenarios of a given component.
160402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
161402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param componentName The component name. Should not be <code>null</code>
162402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return A list of {@link ScenarioResults scenario results}
163402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
164402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic List getComponentScenarios(String componentName) {
165402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	ComponentResults componentResults = (ComponentResults) getResults(componentName);
166402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (componentResults == null) return null;
167402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return Collections.unmodifiableList(componentResults.children);
168402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
169402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
170402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
171402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Get the scenarios which have a summary for a given component.
172402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
173402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param componentName The component name
174402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param config Configuration name
175402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return A list of {@link ScenarioResults scenario results} which have a summary
176402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
177402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic List getComponentSummaryScenarios(String componentName, String config) {
178402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (componentName == null) {
179402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int size = size();
180402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		List scenarios = new ArrayList();
181402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int i=0; i< size; i++) {
182402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			ComponentResults componentResults = (ComponentResults) this.children.get(i);
183402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			scenarios.addAll(componentResults.getSummaryScenarios(true, config));
184402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
185402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		return scenarios;
186402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
187402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	ComponentResults componentResults = (ComponentResults) getResults(componentName);
188402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return componentResults.getSummaryScenarios(false, config);
189402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
190402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
191402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
192402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Return the configuration boxes considered for this performance results
193402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * sorted or not depending on the given flag.
194402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
195402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param sort Indicates whether the list must be sorted or not.
196402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	The order is defined by the configuration names, not by the box names
197402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return The list of configuration boxes sorted by configuration names
198402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
199402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String[] getConfigBoxes(boolean sort) {
200402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return sort ? this.sortedConfigDescriptions : this.configDescriptions;
201402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
202402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
203402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
204402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Return the configuration names considered for this performance results
205402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * sorted or not depending on the given flag.
206402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
207402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param sort Indicates whether the list must be sorted or not
208402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return The list of configuration names
209402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
210402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String[] getConfigNames(boolean sort) {
211402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return sort ?this.sortedConfigNames : this.configNames;
212402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
213402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
214402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*
215402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Compute a SQL pattern from all stored configuration names.
216402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * For example 'eclipseperflnx1', 'eclipseperflnx2' and 'eclipseperflnx3'
217402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * will return 'eclipseperflnx_'.
218402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
219402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael MollString getConfigurationsPattern() {
220402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.configPattern == null) {
221402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int length = this.sortedConfigNames == null ? 0 : this.sortedConfigNames.length;
222402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (length == 0) return null;
223402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.configPattern = this.sortedConfigNames[0];
224402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int refLength = this.configPattern.length();
225402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int i=1; i<length; i++) {
226402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			String config = this.sortedConfigNames[i];
227402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			StringBuffer newConfig = null;
228402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (refLength != config.length()) return null; // strings have not the same length => cannot find a pattern
229402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			for (int j=0; j<refLength; j++) {
230402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				char c = this.configPattern.charAt(j);
231402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				if (config.charAt(j) != c) {
232402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					if (newConfig == null) {
233402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						newConfig = new StringBuffer(refLength);
234402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						if (j == 0) return null; // first char is already different => cannot find a pattern
235402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						newConfig.append(this.configPattern.substring(0, j));
236402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					}
237402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					newConfig.append('_');
238402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				} else if (newConfig != null) {
239402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					newConfig.append(c);
240402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				}
241402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
242402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (newConfig != null) {
243402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				this.configPattern = newConfig.toString();
244402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
245402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
246402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
247402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.configPattern;
248402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
249402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
250402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
251402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Return the name of the last build name except baselines.
252402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
253402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return the name of the last build
254402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
255402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String getLastBuildName() {
256402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return getLastBuildName(1/*all except baselines*/);
257402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
258402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
259402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Return the name of the last build name
260402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
261402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param kind Decide what kind of build is taken into account
262402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	0: all kind of build
263402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	1: all except baseline builds
264402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	2: all except baseline and nightly builds
265402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	3: only integration builds
266402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return the name of the last build of the selected kind
267402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
268402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String getLastBuildName(int kind) {
269402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.name == null) {
270402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		getAllBuildNames(); // init build names if necessary
271402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int idx = this.allBuildNames.length-1;
272402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.name = this.allBuildNames[idx];
273402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (kind > 0) {
274402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			loop: while (idx-- >= 0) {
275402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				switch (this.name.charAt(0)) {
276402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					case 'N':
277402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						if (kind < 2) break loop;
278402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						break;
279402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					case 'M':
280402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						if (kind < 3) break loop;
281402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						break;
282402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					case 'I':
283402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						if (kind < 4) break loop;
284402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll						break;
285402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				}
286402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				this.name = this.allBuildNames[idx];
287402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
288402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
289402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
290402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.name;
291402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
292402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
293402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String getName() {
294402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.name == null) {
295402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		setAllBuildNames();
296402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
297402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.name;
298402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
299402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
300402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*
301402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * (non-Javadoc)
302402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @see org.eclipse.test.internal.performance.results.AbstractResults#getPerformance()
303402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
304402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael MollPerformanceResults getPerformance() {
305402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this;
306402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
307402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
308402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
309402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Get the results of a given scenario.
310402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
311402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param scenarioName The scenario name
312402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return The {@link ScenarioResults scenario results}
313402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
314402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic ScenarioResults getScenarioResults(String scenarioName) {
315402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	ComponentResults componentResults = (ComponentResults) getResults(DB_Results.getComponentNameFromScenario(scenarioName));
316402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return componentResults == null ? null : (ScenarioResults) componentResults.getResults(scenarioName);
317402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
318402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
319402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*
320402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Init configurations from performance results database.
321402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
322402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollprivate void initConfigs() {
323402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// create config names
324402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.configNames = DB_Results.getConfigs();
325402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.configDescriptions = DB_Results.getConfigDescriptions();
326402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int length = this.configNames.length;
327402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.sortedConfigNames = new String[length];
328402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	for (int i = 0; i < length; i++) {
329402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	    this.sortedConfigNames[i] = this.configNames[i];
330402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
331402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
332402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Sort the config names
333402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	Arrays.sort(this.sortedConfigNames);
334402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.sortedConfigDescriptions = new String[length];
335402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	for (int i=0; i<length; i++) {
336402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int j=0; j<length; j++) {
337402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (this.sortedConfigNames[i] == this.configNames[j]) { // == is intentional!
338402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				this.sortedConfigDescriptions[i] = this.configDescriptions[j];
339402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				break;
340402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
341402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
342402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
343402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
344402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
345402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*
346402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Read or update data for a build from a directory supposed to have local files.
347402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
348402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollprivate String[] read(boolean local, String buildName, String[][] configs, boolean force, File dataDir, String taskName, SubMonitor subMonitor) {
349402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (local && dataDir == null) {
350402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		throw new IllegalArgumentException("Must specify a directory to read local files!"); //$NON-NLS-1$
351402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
352402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	subMonitor.setWorkRemaining(100);
353402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
354402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Update info
355402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	long start = System.currentTimeMillis();
356402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int allScenariosSize;
357402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (DB_Results.DB_CONNECTION) {
358402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		try {
359402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			// Read all scenarios
360402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			allScenariosSize = readScenarios(buildName, subMonitor.newChild(10)) ;
361402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (allScenariosSize < 0) {
362402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				return null;
363402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
364402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
365402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			// Read all builds
366402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			DB_Results.queryAllVariations(getConfigurationsPattern());
367402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
368402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			// Refresh configs
369402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (configs == null) {
370402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				initConfigs();
371402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			} else {
372402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				setConfigInfo(configs);
373402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
374402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		} catch (OperationCanceledException e) {
375402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			return null;
376402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
377402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	} else {
378402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (this.allScenarios == null) return null;
379402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		allScenariosSize = this.allScenarios.size();
380402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (configs != null) {
381402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			setConfigInfo(configs);
382402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
383402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
384402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
385402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Create corresponding children
386402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int componentsLength = this.components.length;
387402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	subMonitor.setWorkRemaining(componentsLength);
388402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	RemainingTimeGuess timeGuess = null;
389402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	for (int i=0; i<componentsLength; i++) {
390402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String componentName = this.components[i];
391402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		List scenarios = this.allScenarios == null ? null : (List) this.allScenarios.get(componentName);
392402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
393402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Manage monitor
394402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int percentage = (int) ((((double)(i+1)) / (componentsLength+1)) * 100);
395402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		StringBuffer tnBuffer= taskName==null ? new StringBuffer() : new StringBuffer(taskName);
396402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		tnBuffer.append(" ("); //$NON-NLS-1$
397402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (buildName != null) {
398402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			tnBuffer.append(buildName).append(": "); //$NON-NLS-1$
399402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
400402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		tnBuffer.append(percentage).append("%)"); //$NON-NLS-1$
401402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		subMonitor.setTaskName(tnBuffer.toString());
402402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		StringBuffer subTaskBuffer = new StringBuffer("Component "); //$NON-NLS-1$
403402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		subTaskBuffer.append(componentName);
404402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		subTaskBuffer.append("..."); //$NON-NLS-1$
405402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		subMonitor.subTask(subTaskBuffer.toString());
406402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
407402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Get component results
408402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (scenarios == null && !local) continue;
409402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		ComponentResults componentResults;
410402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (local || (buildName == null && force)) {
411402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			componentResults = new ComponentResults(this, componentName);
412402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			addChild(componentResults, true);
413402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		} else {
414402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			componentResults = (ComponentResults) getResults(componentName);
415402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (componentResults == null) {
416402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				componentResults = new ComponentResults(this, componentName);
417402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				addChild(componentResults, true);
418402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
419402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
420402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
421402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Read the component results
422402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (local) {
423402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			try {
424402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				componentResults.readLocalFile(dataDir, scenarios);
425402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
426402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			catch (FileNotFoundException ex) {
427402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				return null;
428402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
429402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			subMonitor.worked(1);
430402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		} else {
431402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (timeGuess == null) {
432402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				timeGuess = new RemainingTimeGuess(1+componentsLength+allScenariosSize, start);
433402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
434402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			componentResults.updateBuild(buildName, scenarios, force, dataDir, subMonitor.newChild(1), timeGuess);
435402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
436402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (subMonitor.isCanceled()) return null;
437402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
438402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
439402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Update names
440402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	setAllBuildNames();
441402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	writeData(dataDir);
442402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
443402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Print time
444402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	printGlobalTime(start);
445402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
446402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.allBuildNames;
447402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
448402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
449402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
450402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Read all data from performance database for the given configurations
451402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * and scenario pattern.
452402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
453402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * This method is typically called when generated performance results
454402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * from a non-UI application.
455402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
456402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param buildName The name of the build
457402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param configs All configurations to extract results. If <code>null</code>,
458402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	then all known configurations ({@link DB_Results#getConfigs()})  are read.
459402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param pattern The pattern of the concerned scenarios
460402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param dataDir The directory where data will be read/stored locally.
461402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	If <code>null</code>, then database will be read instead and no storage
462402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	will be performed
463402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param threshold The failure percentage threshold over which a build result
464402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	value compared to the baseline is considered as failing.
465402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param monitor The progress monitor
466402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
467402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return All known build names
468402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
469402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String[] readAll(String buildName, String[][] configs, String pattern, File dataDir, int threshold, IProgressMonitor monitor) {
470402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
471402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Init
472402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.scenarioPattern = pattern == null ? "%" : pattern; //$NON-NLS-1$
473402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.failure_threshold = threshold;
474402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	SubMonitor subMonitor = SubMonitor.convert(monitor, 1000);
475402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
476402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Set default names
477402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	setDefaults();
478402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
479402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Read local data files first
480402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	reset(dataDir);
481402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String[] names = read(true, null, configs, true, dataDir, null, subMonitor.newChild(100));
482402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (names==null) {
483402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// if one local files is missing then force a full DB read!
484402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// TODO moderate this to force the DB read only for the missing file...
485402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		return read(false, null, configs, true, dataDir, null, subMonitor.newChild(900));
486402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
487402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
488402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Search build name in read data
489402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	boolean buildMissing = true;
490402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (buildName != null) {
491402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.name = buildName;
492402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		buildMissing = Arrays.binarySearch(names, buildName, Util.BUILD_DATE_COMPARATOR) < 0;
493402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
494402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
495402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Look for missing builds
496402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (buildMissing) {
497402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String[] builds = DB_Results.getBuilds();
498402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		Arrays.sort(builds, Util.BUILD_DATE_COMPARATOR);
499402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int i=builds.length-1; i>=0; i--) {
500402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (Arrays.binarySearch(names, builds[i], Util.BUILD_DATE_COMPARATOR) >= 0) {
501402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				break;
502402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
503402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			read(false, builds[i], configs, true, dataDir, null, subMonitor.newChild(900));
504402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
505402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
506402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.allBuildNames;
507402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
508402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
509402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
510402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Read all data from performance database for the given configurations
511402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * and scenario pattern.
512402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
513402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Note that calling this method flush all previous read data.
514402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
515402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param dataDir The directory where local files are located
516402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param monitor  The progress monitor
517402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
518402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic void readLocal(File dataDir, IProgressMonitor monitor) {
519402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
520402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Print title
521402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String taskName = "Read local performance results"; //$NON-NLS-1$
522402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	println(taskName);
523402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
524402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Create monitor
525402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	SubMonitor subMonitor = SubMonitor.convert(monitor, 1000);
526402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	subMonitor.setTaskName(taskName);
527402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
528402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Read
529402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	reset(dataDir);
530402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	read(true, null, null, true, dataDir, taskName, subMonitor);
531402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
532402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
533402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid readLocalFile(File dir) {
534402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (!dir.exists()) return;
535402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	File dataFile = new File(dir, "performances.dat");	//$NON-NLS-1$
536402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (!dataFile.exists()) return;
537402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	DataInputStream stream = null;
538402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	try {
539402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Read local file info
540402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		stream = new DataInputStream(new BufferedInputStream(new FileInputStream(dataFile)));
541402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
542402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Read build info
543402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String str = stream.readUTF();
544402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.needToUpdateLocalFile = this.name == null || Util.getBuildDate(this.name).compareTo(Util.getBuildDate(str)) > 0;
545402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (this.name != null && Util.getBuildDate(this.name).compareTo(Util.getBuildDate(str)) >= 0) {
546402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			return;
547402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
548402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println(" - read performance results local files info: "); //$NON-NLS-1$
549402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println("		+ name : "+str);
550402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.name = str == ""  ? null : str;
551402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		str = stream.readUTF();
552402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println("		+ baseline : "+str);
553402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (this.baselineName == null) {
554402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.baselineName = str == "" ? null : str;
555402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
556402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		str = stream.readUTF();
557402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println("		+ baseline prefix: "+str);
558402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.baselinePrefix = str == "" ? null : str;
559402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
560402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Write configs info
561402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int length = stream.readInt();
562402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println("		+ "+length+" configs");
563402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.configNames = new String[length];
564402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.sortedConfigNames = new String[length];
565402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.configDescriptions = new String[length];
566402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.sortedConfigDescriptions = new String[length];
567402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int i = 0; i < length; i++) {
568402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.configNames[i] = stream.readUTF();
569402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.sortedConfigNames[i] = this.configNames[i];
570402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.configDescriptions[i] = stream.readUTF();
571402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.sortedConfigDescriptions[i] = this.configDescriptions[i];
572402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
573402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		DB_Results.setConfigs(this.configNames);
574402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		DB_Results.setConfigDescriptions(this.configDescriptions);
575402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
576402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Write builds info
577402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		length = stream.readInt();
578402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println("		+ "+length+" builds");
579402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.allBuildNames = new String[length];
580402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int i = 0; i < length; i++) {
581402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.allBuildNames[i] = stream.readUTF();
582402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
583402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
584402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Write scenarios info
585402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		length = stream.readInt();
586402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println("		+ "+length+" components");
587402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.components = new String[length];
588402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.allScenarios = new HashMap();
589402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int i = 0; i < length; i++) {
590402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.components[i] = stream.readUTF();
591402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			int size = stream.readInt();
592402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			List scenarios = new ArrayList(size);
593402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			for (int j=0; j<size; j++) {
594402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				scenarios.add(new ScenarioResults(stream.readInt(), stream.readUTF(), stream.readUTF()));
595402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
596402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.allScenarios.put(this.components[i], scenarios);
597402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
598402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println("	=> read from file "+dataFile); //$NON-NLS-1$
599402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	} catch (IOException ioe) {
600402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println("	!!! "+dataFile+" should be deleted as it contained invalid data !!!"); //$NON-NLS-1$ //$NON-NLS-2$
601402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	} finally {
602402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		try {
603402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	        stream.close();
604402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll        } catch (IOException e) {
605402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	        // nothing else to do!
606402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll        }
607402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
608402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
609402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
610402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollprivate int readScenarios(String buildName, SubMonitor subMonitor) throws OperationCanceledException {
611402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	subMonitor.setWorkRemaining(10);
612402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	long start = System.currentTimeMillis();
613402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String titleSuffix;
614402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (buildName == null) {
615402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		titleSuffix = "all database scenarios..."; //$NON-NLS-1$
616402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	} else {
617402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		titleSuffix = "all database scenarios for "+buildName+" build..."; //$NON-NLS-1$ //$NON-NLS-2$
618402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
619402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	print("	+ get "+titleSuffix); //$NON-NLS-1$
620402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	subMonitor.subTask("Get "+titleSuffix); //$NON-NLS-1$
621402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.allScenarios = DB_Results.queryAllScenarios(this.scenarioPattern, buildName);
622402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.allScenarios == null) return -1;
623402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int allScenariosSize = 0;
624402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	List componentsSet = new ArrayList(this.allScenarios.keySet());
625402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	Collections.sort(componentsSet);
626402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int componentsSize = componentsSet.size();
627402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	componentsSet.toArray(this.components = new String[componentsSize]);
628402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	for (int i=0; i<componentsSize; i++) {
629402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String componentName = this.components[i];
630402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		List scenarios = (List) this.allScenarios.get(componentName);
631402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		allScenariosSize += scenarios.size();
632402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
633402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	println(" -> "+allScenariosSize+" found in "+(System.currentTimeMillis()-start)+"ms"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
634402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	subMonitor.worked(10);
635402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (subMonitor.isCanceled()) throw new OperationCanceledException();
636402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return allScenariosSize;
637402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
638402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
639402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid reset(File dataDir) {
640402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.allBuildNames = null;
641402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.children = new ArrayList();
642402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//	this.name = null;
643402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.components = null;
644402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.allScenarios = null;
645402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	readLocalFile(dataDir);
646402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
647402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
648402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollprivate void setAllBuildNames() {
649402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	SortedSet builds = new TreeSet(Util.BUILD_DATE_COMPARATOR);
650402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int size = size();
651402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (size == 0) return;
652402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	for (int i=0; i<size; i++) {
653402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		ComponentResults componentResults = (ComponentResults) this.children.get(i);
654402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		Set names = componentResults.getAllBuildNames();
655402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		builds.addAll(names);
656402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
657402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int buildsSize = builds.size();
658402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.allBuildNames = new String[buildsSize];
659402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (buildsSize > 0) {
660402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int n = 0;
661402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		Iterator buildNames = builds.iterator();
662402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		while (buildNames.hasNext()) {
663402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			String buildName = (String) buildNames.next();
664402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (this.lastBuildName == null || Util.getBuildDate(buildName).compareTo(Util.getBuildDate(this.lastBuildName)) <= 0) {
665402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				this.allBuildNames[n++] = buildName;
666402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
667402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
668402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (n < buildsSize) {
669402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			System.arraycopy(this.allBuildNames, 0, this.allBuildNames = new String[n], 0, n);
670402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
671402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int idx = n-1;
672402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String lastBuild = this.allBuildNames[idx--];
673402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		while (lastBuild.startsWith(DB_Results.getDbBaselinePrefix())) {
674402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			lastBuild = this.allBuildNames[idx--];
675402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
676402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.needToUpdateLocalFile = this.name == null || Util.getBuildDate(lastBuild).compareTo(Util.getBuildDate(this.name)) > 0;
677402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.name = lastBuild;
678402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (this.baselineName != null) {
679402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			String lastBuildDate = Util.getBuildDate(lastBuild);
680402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (Util.getBuildDate(this.baselineName).compareTo(lastBuildDate) > 0) {
681402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				this.baselineName = DB_Results.getLastBaselineBuild(lastBuildDate);
682402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
683402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
684402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
685402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
686402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
687402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollprivate void setConfigInfo(String[][] configs) {
688402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (configs == null) return;
689402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
690402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Store config information
691402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int length = configs.length;
692402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.configNames = new String[length];
693402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.sortedConfigNames = new String[length];
694402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.configDescriptions = new String[length];
695402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	for (int i=0; i<length; i++) {
696402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.configNames[i] = this.sortedConfigNames[i] = configs[i][0];
697402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.configDescriptions[i] = configs[i][1];
698402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
699402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
700402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Sort the config names
701402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	Arrays.sort(this.sortedConfigNames);
702402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	length = this.sortedConfigNames.length;
703402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.sortedConfigDescriptions = new String[length];
704402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	for (int i=0; i<length; i++) {
705402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int j=0; j<length; j++) {
706402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (this.sortedConfigNames[i] == this.configNames[j]) { // == is intentional!
707402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				this.sortedConfigDescriptions[i] = this.configDescriptions[j];
708402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				break;
709402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
710402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
711402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
712402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
713402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
714402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
715402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
716402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Set the name of the baseline used for extracted results
717402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
718402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param buildName The name of the baseline build
719402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
720402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic void setBaselineName(String buildName) {
721402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.baselineName = buildName;
722402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
723402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
724402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollprivate void setDefaults() {
725402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
726402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Set builds if none
727402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (size() == 0 && DB_Results.DB_CONNECTION) {
728402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.allBuildNames = DB_Results.getBuilds();
729402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.components = DB_Results.getComponents();
730402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		initConfigs();
731402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
732402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
733402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Set name if null
734402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.name == null) {
735402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		setAllBuildNames();
736402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (this.name == null) { // does not know any build
737402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.name = DB_Results.getLastCurrentBuild();
738402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (this.dbRequired) {
739402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				if (this.name == null) {
740402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll					throw new RuntimeException("Cannot find any current build!"); //$NON-NLS-1$
741402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				}
742402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				this.allBuildNames = DB_Results.getBuilds();
743402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				this.components = DB_Results.getComponents();
744402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				initConfigs();
745402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
746402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			if (this.printStream != null) {
747402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				this.printStream.println("	+ no build specified => use last one: "+this.name); //$NON-NLS-1$
748402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
749402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
750402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
751402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
752402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Init baseline name if not set
753402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.baselineName == null && getName() != null) {
754402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String buildDate = Util.getBuildDate(getName());
755402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.baselineName = DB_Results.getLastBaselineBuild(buildDate);
756402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (this.baselineName == null && this.dbRequired) {
757402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			throw new RuntimeException("Cannot find any baseline to refer!"); //$NON-NLS-1$
758402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
759402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (this.printStream != null) {
760402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.printStream.println("	+ no baseline specified => use last one: "+this.baselineName); //$NON-NLS-1$
761402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
762402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
763402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
764402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Init baseline prefix if not set
765402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.baselinePrefix == null && this.baselineName != null) {
766402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Assume that baseline name format is *always* x.y_yyyyMMddhhmm_yyyyMMddhhmm
767402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int index = this.baselineName.lastIndexOf('_');
768402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (index > 0) {
769402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.baselinePrefix = this.baselineName.substring(0, index);
770402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		} else {
771402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			this.baselinePrefix = DB_Results.getDbBaselinePrefix();
772402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
773402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
774402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
775402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Set scenario pattern default
776402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.scenarioPattern == null) {
777402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.scenarioPattern = "%"; //$NON-NLS-1$
778402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
779402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
780402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Flush print stream
781402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (this.printStream != null) {
782402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.printStream.println();
783402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.printStream.flush();
784402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
785402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
786402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
787402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic void setLastBuildName(String lastBuildName) {
788402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	this.lastBuildName = lastBuildName;
789402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//	if (lastBuildName == null) {
790402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//		int idx = this.allBuildNames.length-1;
791402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//		String lastBuild = this.allBuildNames[idx--];
792402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//		while (this.name.startsWith(DB_Results.getDbBaselinePrefix())) {
793402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//			lastBuild = this.allBuildNames[idx--];
794402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//		}
795402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//		this.name = lastBuild;
796402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//	} else {
797402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//		this.name = lastBuildName;
798402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll//	}
799402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
800402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
801402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
802402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Update a given build information with database contents.
803402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
804402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param builds The builds to read new data
805402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param force Force the update from the database, even if the build is
806402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	already known.
807402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param dataDir The directory where data should be stored locally if necessary.
808402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	If <code>null</code>, then information changes won't be persisted.
809402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param monitor The progress monitor
810402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return All known builds
811402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
812402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String[] updateBuilds(String[] builds, boolean force, File dataDir, IProgressMonitor monitor) {
813402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
814402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Print title
815402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	StringBuffer buffer = new StringBuffer("Update data for "); //$NON-NLS-1$
816402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	int length = builds == null ? 0 : builds.length;
817402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	switch (length) {
818402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		case 0:
819402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			buffer.append("all builds"); //$NON-NLS-1$
820402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			reset(dataDir);
821402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			break;
822402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		case 1:
823402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			buffer.append("one build"); //$NON-NLS-1$
824402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			break;
825402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		default:
826402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			buffer.append("several builds"); //$NON-NLS-1$
827402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			break;
828402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
829402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String taskName = buffer.toString();
830402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	println(buffer);
831402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
832402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Create sub-monitor
833402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	SubMonitor subMonitor = SubMonitor.convert(monitor, 1000*length);
834402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	subMonitor.setTaskName(taskName);
835402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
836402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Read
837402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	for (int i=0; i<length;  i++) {
838402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		read(false, builds[i], null, force, dataDir, taskName, subMonitor.newChild(1000));
839402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
840402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
841402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Return new builds list
842402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.allBuildNames;
843402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
844402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
845402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/**
846402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Update a given build information with database contents.
847402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *
848402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param buildName The build name to read new data
849402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param force Force the update from the database, even if the build is
850402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	already known.
851402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param dataDir The directory where data should be stored locally if necessary.
852402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 	If <code>null</code>, then information changes won't be persisted.
853402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param monitor The progress monitor
854402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return All known builds
855402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
856402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic String[] updateBuild(String buildName, boolean force, File dataDir, IProgressMonitor monitor) {
857402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
858402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Print title
859402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	StringBuffer buffer = new StringBuffer("Update data for "); //$NON-NLS-1$
860402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (buildName == null) {
861402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		buffer.append("all builds"); //$NON-NLS-1$
862402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		reset(dataDir);
863402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	} else {
864402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		buffer.append("one build"); //$NON-NLS-1$
865402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
866402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	String taskName = buffer.toString();
867402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	println(buffer);
868402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
869402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Create sub-monitor
870402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	SubMonitor subMonitor = SubMonitor.convert(monitor, 1000);
871402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	subMonitor.setTaskName(taskName);
872402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
873402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Read
874402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	read(false, buildName, null, force, dataDir, taskName, subMonitor);
875402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
876402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Refresh name
877402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (buildName != null && !buildName.startsWith(DB_Results.getDbBaselinePrefix())) {
878402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		this.name = buildName;
879402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
880402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
881402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	// Return new list all build names
882402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	return this.allBuildNames;
883402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
884402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
885402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/*
886402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Write general information.
887402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */
888402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollvoid writeData(File dir) {
889402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (!DB_Results.DB_CONNECTION) {
890402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Only write new local file if there's a database connection
891402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// otherwise contents may not be complete...
892402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		return;
893402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
894402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (dir ==null || (!dir.exists() && !dir.mkdirs())) {
895402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		System.err.println("can't create directory " + dir); //$NON-NLS-1$
896402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		return;
897402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
898402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	File dataFile = new File(dir, "performances.dat"); //$NON-NLS-1$
899402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	if (dataFile.exists()) {
900402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		if (!this.needToUpdateLocalFile) {
901402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			return;
902402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
903402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		dataFile.delete();
904402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
905402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	try {
906402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		DataOutputStream stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile)));
907402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
908402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Write build info
909402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		stream.writeUTF(this.name == null ? DB_Results.getLastCurrentBuild() : this.name);
910402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		stream.writeUTF(this.baselineName == null ? DB_Results.getLastBaselineBuild(null) : this.baselineName);
911402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		stream.writeUTF(this.baselinePrefix == null ? "" : this.baselinePrefix);
912402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
913402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Write configs info
914402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		int length = this.sortedConfigNames.length;
915402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		stream.writeInt(length);
916402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int i = 0; i < length; i++) {
917402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			stream.writeUTF(this.sortedConfigNames[i]);
918402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			stream.writeUTF(this.sortedConfigDescriptions[i]);
919402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
920402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
921402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Write builds info
922402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		String[] builds = this.allBuildNames == null ? DB_Results.getBuilds() : this.allBuildNames;
923402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		length = builds.length;
924402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		stream.writeInt(length);
925402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int i = 0; i < length; i++) {
926402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			stream.writeUTF(builds[i]);
927402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
928402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
929402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Write scenarios info
930402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		length = this.components.length;
931402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		stream.writeInt(length);
932402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		for (int i = 0; i < length; i++) {
933402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			stream.writeUTF(this.components[i]);
934402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			List scenarios = (List) this.allScenarios.get(this.components[i]);
935402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			int size = scenarios.size();
936402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			stream.writeInt(size);
937402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			for (int j=0; j<size; j++) {
938402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				final ScenarioResults scenarioResults = (ScenarioResults)scenarios.get(j);
939402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				stream.writeInt(scenarioResults.getId());
940402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				stream.writeUTF(scenarioResults.getName());
941402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll				stream.writeUTF(scenarioResults.getLabel());
942402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll			}
943402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		}
944402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
945402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		// Close
946402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		stream.close();
947402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		println("	=> performance results general data  written in file " + dataFile); //$NON-NLS-1$
948402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	} catch (FileNotFoundException e) {
949402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		System.err.println("can't create output file" + dataFile); //$NON-NLS-1$
950402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	} catch (IOException e) {
951402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll		e.printStackTrace();
952402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll	}
953402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
954402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll
955402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}
956