/******************************************************************************* * Copyright (c) 2000, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.test.internal.performance.results.db; import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; import java.math.BigDecimal; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.eclipse.core.runtime.Assert; import org.eclipse.test.internal.performance.PerformanceTestPlugin; import org.eclipse.test.internal.performance.data.Dim; import org.eclipse.test.internal.performance.db.DB; import org.eclipse.test.internal.performance.results.utils.IPerformancesConstants; import org.eclipse.test.internal.performance.results.utils.Util; import org.eclipse.test.performance.Dimension; /** * Specific and private implementation of {@link org.eclipse.test.internal.performance.db.DB} class * to get massive results from performance results database. * TODO (frederic) Should be at least a subclass of {@link DB}... */ public class DB_Results { private static final String DEFAULT_DB_BASELINE_PREFIX = "R-"; private static final Dim[] NO_DIMENSION = new Dim[0]; private static final String[] EMPTY_LIST = new String[0]; static final boolean DEBUG = false; static final boolean LOG = false; // the two supported DB types private static final String DERBY= "derby"; //$NON-NLS-1$ private static final String CLOUDSCAPE= "cloudscape"; //$NON-NLS-1$ private static DB_Results fgDefault; private Connection fConnection; private SQL_Results fSQL; // private boolean fIsEmbedded; private String fDBType; // either "derby" or "cloudscape" // Preferences info public static boolean DB_CONNECTION = false; private static String DB_NAME; private static String DB_LOCATION; private static String DB_BASELINE_PREFIX = DEFAULT_DB_BASELINE_PREFIX; private static String DB_VERSION; private static String DB_VERSION_REF; /** * Get the name of the database. * * @return The name as a string. */ public static String getDbName() { if (DB_NAME == null) initDbContants(); return DB_NAME; } /** * Set the name of the database. * * @param dbName The name as a string. */ public static void setDbName(String dbName) { Assert.isNotNull(dbName); DB_NAME = dbName; } /** * Get the location of the database. * * @return The location as a string. */ public static String getDbLocation() { if (!DB_CONNECTION) return null; if (DB_LOCATION == null) initDbContants(); return DB_LOCATION; } /** * Set the location of the database. * * @param dbLocation The location as a string. */ public static void setDbLocation(String dbLocation) { Assert.isNotNull(dbLocation); DB_LOCATION = dbLocation; } /** * Get the default baseline prefix. * * @return The prefix as a string. */ public static String getDbBaselinePrefix() { return DB_BASELINE_PREFIX; } /** * Set the baseline prefix of the database. * * @param baselinePrefix The prefix as a string. */ public static void setDbDefaultBaselinePrefix(String baselinePrefix) { Assert.isNotNull(baselinePrefix); Assert.isTrue(baselinePrefix.startsWith(DEFAULT_DB_BASELINE_PREFIX)); DB_BASELINE_PREFIX = baselinePrefix; } /** * Get the baseline reference version of the database. * * @return The version as a string. */ public static String getDbBaselineRefVersion() { if (DB_VERSION_REF == null) initDbContants(); return DB_VERSION_REF; } /** * Get the version of the database. * * @return The version as a string. */ public static String getDbVersion() { if (DB_VERSION == null) initDbContants(); return DB_VERSION; } /** * Set the version of the database. * * @param version The version as a string. */ public static void setDbVersion(String version) { Assert.isNotNull(version); Assert.isTrue(version.startsWith("v3")); DB_VERSION = version; } /** * Update the database constants from a new database location. * @param connected Tells whether the database should be connected or not. * @param databaseLocation The database location. * May be a path to a local folder or a net address * (see {@link IPerformancesConstants#NETWORK_DATABASE_LOCATION}). */ public static boolean updateDbConstants(boolean connected, int eclipseVersion, String databaseLocation) { if (DB_CONNECTION != connected || DB_LOCATION == null || DB_NAME == null || ((databaseLocation == null && !DB_LOCATION.equals(IPerformancesConstants.NETWORK_DATABASE_LOCATION)) || !DB_LOCATION.equals(databaseLocation)) || !DB_NAME.equals(IPerformancesConstants.DATABASE_NAME_PREFIX + eclipseVersion)) { shutdown(); DB_CONNECTION = connected; DB_LOCATION = databaseLocation == null ? IPerformancesConstants.NETWORK_DATABASE_LOCATION : databaseLocation; DB_NAME = IPerformancesConstants.DATABASE_NAME_PREFIX + eclipseVersion; DB_VERSION = "v" + eclipseVersion; DB_VERSION_REF = "R-3." + (eclipseVersion % 10 - 1); if (connected) { return getDefault().fSQL != null; } } return true; } /** * Returns a title including DB version and name. * * @return A title as a string. */ public static String getDbTitle() { if (!DB_CONNECTION) return null; String title = "Eclipse " + DB_VERSION + " - "; if (DB_LOCATION.startsWith("net:")) { title += " Network DB"; } else { title += " Local DB"; } return title; } /** * The list of all the configurations (i.e. machine) stored in the database. */ private static String[] CONFIGS; /** * The list of all the components stored in the database. */ private static String[] COMPONENTS; /** * The list of all the builds stored in the database. */ private static String[] BUILDS; /** * The list of all the dimensions stored in the database. */ private static int[] DIMENSIONS; /** * The default dimension used to display results (typically in fingerprints). */ private static Dim DEFAULT_DIM; private static int DEFAULT_DIM_INDEX; /** * The list of all the dimensions displayed while generating results. */ private static Dim[] RESULTS_DIMENSIONS; /** * The list of all the VMs stored in the database. */ private static String[] VMS; /** * The list of possible test boxes. *

* Only used if no specific configurations are specified * (see {@link PerformanceResults#readAll(String, String[][], String, File, int, org.eclipse.core.runtime.IProgressMonitor)}. *

* Note that this is a copy of the the property "eclipse.perf.config.descriptors" * defined in org.eclipse.releng.eclipsebuilder/eclipse/helper.xml file */ private static String[] CONFIG_DESCRIPTIONS; /** * The list of known Eclipse components. */ private final static String[] ECLIPSE_COMPONENTS = { "org.eclipse.ant", //$NON-NLS-1$ "org.eclipse.compare", //$NON-NLS-1$ "org.eclipse.core", //$NON-NLS-1$ "org.eclipse.help", //$NON-NLS-1$ "org.eclipse.jdt.core", //$NON-NLS-1$ "org.eclipse.jdt.debug", //$NON-NLS-1$ "org.eclipse.jdt.text", //$NON-NLS-1$ "org.eclipse.jdt.ui", //$NON-NLS-1$ "org.eclipse.jface", //$NON-NLS-1$ "org.eclipse.osgi", //$NON-NLS-1$ "org.eclipse.pde.api.tools", //$NON-NLS-1$ "org.eclipse.pde.ui", //$NON-NLS-1$ "org.eclipse.swt", //$NON-NLS-1$ "org.eclipse.team", //$NON-NLS-1$ "org.eclipse.ua", //$NON-NLS-1$ "org.eclipse.ui" //$NON-NLS-1$ }; private static String[] KNOWN_COMPONENTS = ECLIPSE_COMPONENTS; // Store debug info final static StringWriter DEBUG_STR_WRITER; final static PrintWriter DEBUG_WRITER; static { if (DEBUG) { DEBUG_STR_WRITER= new StringWriter(); DEBUG_WRITER= new PrintWriter(DEBUG_STR_WRITER); } else { DEBUG_STR_WRITER= null; DEBUG_WRITER= null; } } // Store log info final static StringWriter LOG_STR_WRITER = new StringWriter(); final static LogWriter LOG_WRITER = new LogWriter(); static class LogWriter extends PrintWriter { long[] starts = new long[10]; long[] times = new long[10]; StringBuffer[] buffers = new StringBuffer[10]; int depth = -1, max = -1; public LogWriter() { super(LOG_STR_WRITER); } void starts(String log) { if (++this.depth >= this.buffers.length) { System.arraycopy(this.times, 0, this.times = new long[this.depth+10], 0, this.depth); System.arraycopy(this.buffers, 0, this.buffers= new StringBuffer[this.depth+10], 0, this.depth); } StringBuffer buffer = this.buffers[this.depth]; if (this.buffers[this.depth] == null) buffer = this.buffers[this.depth] = new StringBuffer(); buffer.append(log); this.starts[this.depth] = System.currentTimeMillis(); if (this.depth > this.max) this.max = this.depth; } void ends(String log) { if (this.depth < 0) throw new RuntimeException("Invalid call to ends (missing corresponding starts call)!"); //$NON-NLS-1$ this.buffers[this.depth].append(log); if (this.depth > 0) { this.times[this.depth] += System.currentTimeMillis() - this.starts[this.depth]; this.depth--; return; } for (int i=0; inull * return the last baseline build stored in the DB. * * @return the ID of the last baseline build before the given date or * null if none was run before it... */ public static String getLastBaselineBuild(String date) { if (BUILDS == null) { queryAllVariations("%"); //$NON-NLS-1$ } if (date == null) { if (LAST_BASELINE_BUILD == null) { return BUILDS[0]; } return LAST_BASELINE_BUILD; } String lastBaselineBuild = null; for (int i=0; i 0) { lastBaselineBuild = build; } } } } if (lastBaselineBuild == null) { return BUILDS[0]; } return lastBaselineBuild; } /** * Return the ID of the last baseline build. * * @return the ID of the last baseline build. */ public static String getLastCurrentBuild() { if (BUILDS == null) { queryAllVariations("%"); //$NON-NLS-1$ } return LAST_CURRENT_BUILD; } /** * Returns all the scenarios names read from the database. * * @return The list of all scenarios matching the pattern for a given build. * @see #internalQueryBuildScenarios(String, String) */ public static List getScenarios() { return Arrays.asList(SCENARII); } /** * Init the constants if necessary. */ public static void initDbContants() { if (DB_LOCATION == null) { DB_LOCATION = PerformanceTestPlugin.getDBLocation(); if (DB_LOCATION == null) { new RuntimeException("Cannot connect to the DB without a location!"); } } if (DB_NAME == null) { DB_NAME = PerformanceTestPlugin.getDBName(); if (DB_NAME == null) { new RuntimeException("Cannot connect to the DB without a name!"); } } if (DB_VERSION == null) { DB_VERSION = "v" + DB_NAME.substring(DB_NAME.length()-2); DB_VERSION_REF = "R-3."+(Character.digit(DB_NAME.charAt(DB_NAME.length()-1), 10)-1); } } /** * Get all scenarios read from database. * * @return A list of all scenario names matching the default pattern */ public static Map queryAllScenarios() { return getDefault().internalQueryBuildScenarios("%", null); //$NON-NLS-1$ } /** * Get all scenarios read from database matching a given pattern. * Note that all scenarios are returned if the pattern is null. * * @param scenarioPattern The pattern of the requested scenarios * @return A map of all scenarios matching the given pattern. * The map keys are component names and values are the scenarios list for * each component. */ static Map queryAllScenarios(String scenarioPattern) { String pattern = scenarioPattern==null ? "%" : scenarioPattern; //$NON-NLS-1$ return getDefault().internalQueryBuildScenarios(pattern, null); } /** * Get all scenarios read from database matching a given pattern. * Note that all scenarios are returned if the pattern is null. * * @param scenarioPattern The pattern of the requested scenarios * @param buildName The build name * @return A list of scenario names matching the given pattern */ static Map queryAllScenarios(String scenarioPattern, String buildName) { return getDefault().internalQueryBuildScenarios(scenarioPattern, buildName); } /** * Get all variations read from database matching a given configuration pattern. * * @param configPattern The pattern of the requested configurations */ static void queryAllVariations(String configPattern) { getDefault().internalQueryAllVariations(configPattern); } /** * Get all summaries from DB for a given scenario and configuration pattern * * @param scenarioResults The scenario results where to store data * @param configPattern The configuration pattern concerned by the query * @param builds All builds to get summaries, if null, then all DB * builds will be concerned. */ static void queryScenarioSummaries(ScenarioResults scenarioResults, String configPattern, String[] builds) { getDefault().internalQueryScenarioSummaries(scenarioResults, configPattern, builds); } /** * Query and store all values for given scenario results * * @param scenarioResults The scenario results where the values has to be put * @param configPattern The pattern of the configuration concerned by the query * @param buildName Name of the last build on which data were stored locally * */ static void queryScenarioValues(ScenarioResults scenarioResults, String configPattern, String buildName) { getDefault().internalQueryScenarioValues(scenarioResults, configPattern, buildName); } /** * dbloc= embed in home directory * dbloc=/tmp/performance embed given location * dbloc=net://localhost connect to local server * dbloc=net://www.eclipse.org connect to remove server */ private void connect() { if (this.fConnection != null || !DB_CONNECTION) return; if (DEBUG) DriverManager.setLogWriter(new PrintWriter(System.out)); // Init DB location and name if not already done if (DB_LOCATION == null) { initDbContants(); } String url = null; java.util.Properties info = new java.util.Properties(); if (DEBUG) { DEBUG_WRITER.println(); DEBUG_WRITER.println("==========================================================="); //$NON-NLS-1$ DEBUG_WRITER.println("Database debug information stored while processing"); //$NON-NLS-1$ } if (LOG) { LOG_WRITER.println(); LOG_WRITER.println("==========================================================="); //$NON-NLS-1$ LOG_WRITER.println("Database log information stored while processing"); //$NON-NLS-1$ } this.fDBType = DERBY; // assume we are using Derby try { if (DB_LOCATION.startsWith("net://")) { //$NON-NLS-1$ // remote // fIsEmbedded = false; // connect over network if (DEBUG) DEBUG_WRITER.println("Trying to connect over network..."); //$NON-NLS-1$ Class.forName("com.ibm.db2.jcc.DB2Driver"); //$NON-NLS-1$ info.put("user", PerformanceTestPlugin.getDBUser()); //$NON-NLS-1$ info.put("password", PerformanceTestPlugin.getDBPassword()); //$NON-NLS-1$ info.put("retrieveMessagesFromServerOnGetMessage", "true"); //$NON-NLS-1$ //$NON-NLS-2$ info.put("create", "true"); //$NON-NLS-1$ //$NON-NLS-2$ url = DB_LOCATION + '/' + DB_NAME; } else if (DB_LOCATION.startsWith("//")) { //$NON-NLS-1$ // remote // fIsEmbedded = false; // connect over network if (DEBUG) DEBUG_WRITER.println("Trying to connect over network..."); //$NON-NLS-1$ Class.forName("org.apache.derby.jdbc.ClientDriver"); //$NON-NLS-1$ info.put("user", PerformanceTestPlugin.getDBUser()); //$NON-NLS-1$ info.put("password", PerformanceTestPlugin.getDBPassword()); //$NON-NLS-1$ info.put("create", "true"); //$NON-NLS-1$ //$NON-NLS-2$ url = DB_LOCATION + '/' + DB_NAME; } else { // workaround for Derby issue: // http://nagoya.apache.org/jira/browse/DERBY-1 if ("Mac OS X".equals(System.getProperty("os.name"))) //$NON-NLS-1$//$NON-NLS-2$ System.setProperty("derby.storage.fileSyncTransactionLog", "true"); //$NON-NLS-1$ //$NON-NLS-2$ // embedded try { Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); //$NON-NLS-1$ // fIsEmbedded = true; } catch (ClassNotFoundException e) { Class.forName("com.ihost.cs.jdbc.CloudscapeDriver"); //$NON-NLS-1$ this.fDBType = CLOUDSCAPE; } if (DEBUG) DEBUG_WRITER.println("Loaded embedded " + this.fDBType); //$NON-NLS-1$ File f; if (DB_LOCATION.length() == 0) { String user_home = System.getProperty("user.home"); //$NON-NLS-1$ if (user_home == null) return; f = new File(user_home, this.fDBType); } else f = new File(DB_LOCATION); url = new File(f, DB_NAME).getAbsolutePath(); info.put("user", PerformanceTestPlugin.getDBUser()); //$NON-NLS-1$ info.put("password", PerformanceTestPlugin.getDBPassword()); //$NON-NLS-1$ info.put("create", "true"); //$NON-NLS-1$ //$NON-NLS-2$ } try { this.fConnection = DriverManager.getConnection("jdbc:" + this.fDBType + ":" + url, info); //$NON-NLS-1$ //$NON-NLS-2$ } catch (SQLException e) { if ("08001".equals(e.getSQLState()) && DERBY.equals(this.fDBType)) { //$NON-NLS-1$ if (DEBUG) DEBUG_WRITER.println("DriverManager.getConnection failed; retrying for cloudscape"); //$NON-NLS-1$ // try Cloudscape this.fDBType = CLOUDSCAPE; this.fConnection = DriverManager.getConnection("jdbc:" + this.fDBType + ":" + url, info); //$NON-NLS-1$ //$NON-NLS-2$ } else throw e; } if (DEBUG) DEBUG_WRITER.println("connect succeeded!"); //$NON-NLS-1$ this.fConnection.setAutoCommit(false); this.fSQL = new SQL_Results(this.fConnection); this.fConnection.commit(); } catch (SQLException ex) { PerformanceTestPlugin.logError(ex.getMessage()); } catch (ClassNotFoundException e) { PerformanceTestPlugin.log(e); } } private void disconnect() { if (DEBUG) DEBUG_WRITER.println("disconnecting from DB"); //$NON-NLS-1$ if (this.fSQL != null) { try { this.fSQL.dispose(); } catch (SQLException e1) { PerformanceTestPlugin.log(e1); } this.fSQL = null; } if (this.fConnection != null) { try { this.fConnection.commit(); } catch (SQLException e) { PerformanceTestPlugin.log(e); } try { this.fConnection.close(); } catch (SQLException e) { PerformanceTestPlugin.log(e); } this.fConnection = null; } /* if (fIsEmbedded) { try { DriverManager.getConnection("jdbc:" + fDBType + ":;shutdown=true"); //$NON-NLS-1$ //$NON-NLS-2$ } catch (SQLException e) { String message = e.getMessage(); if (message.indexOf("system shutdown.") < 0) //$NON-NLS-1$ e.printStackTrace(); } } */ } /* * Return the index of the given configuration in the stored list. */ private int getConfigId(String config) { if (CONFIGS == null) return -1; return Arrays.binarySearch(CONFIGS, config); } SQL_Results getSQL() { return this.fSQL; } /* * Query all comments from database */ private void internalQueryAllComments() { if (this.fSQL == null) return; if (COMMENTS != null) return; long start = System.currentTimeMillis(); if (DEBUG) DEBUG_WRITER.print(" [DB query all comments..."); //$NON-NLS-1$ ResultSet result = null; try { String[] comments = null; result = this.fSQL.queryAllComments(); while (result.next()) { int commentID = result.getInt(1); // Ignore kind as there's only one // int commentKind = result.getInt(2); String comment = result.getString(3); if (comments == null) { comments = new String[commentID+10]; } else if (commentID >= comments.length) { int length = comments.length; System.arraycopy(comments, 0, comments = new String[commentID+10], 0, length); } comments[commentID] = comment; } COMMENTS = comments; } catch (SQLException e) { PerformanceTestPlugin.log(e); } finally { if (result != null) { try { result.close(); } catch (SQLException e1) { // ignored } } if (DEBUG) DEBUG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$ } } /* * Query all variations. This method stores all config and build names. */ private void internalQueryAllVariations(String configPattern) { if (this.fSQL == null) return; if (BUILDS != null) return; long start = System.currentTimeMillis(); if (DEBUG) { DEBUG_WRITER.print(" - DB query all variations for configuration pattern: "+configPattern); //$NON-NLS-1$ DEBUG_WRITER.print("..."); //$NON-NLS-1$ } ResultSet result = null; try { CONFIGS = null; BUILDS = null; BUILDS_LENGTH = 0; result = this.fSQL.queryAllVariations(configPattern); while (result.next()) { String variation = result.getString(1); // something like "||build=I20070615-1200||config=eclipseperfwin2_R3.3||jvm=sun|" StringTokenizer tokenizer = new StringTokenizer(variation, "=|"); //$NON-NLS-1$ tokenizer.nextToken(); // 'build' storeBuildName(tokenizer.nextToken()); // 'I20070615-1200' tokenizer.nextToken(); // 'config' storeConfig(tokenizer.nextToken()); // 'eclipseperfwin2_R3.3' tokenizer.nextToken(); // 'jvm' storeVm(tokenizer.nextToken()); // 'sun' } if (BUILDS_LENGTH == 0) { BUILDS = EMPTY_LIST; } } catch (SQLException e) { PerformanceTestPlugin.log(e); } finally { if (result != null) { try { result.close(); } catch (SQLException e1) { // ignored } } if (DEBUG) DEBUG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$ } } private Map internalQueryBuildScenarios(String scenarioPattern, String buildName) { if (this.fSQL == null) return null; long start = System.currentTimeMillis(); if (DEBUG) { DEBUG_WRITER.print(" - DB query all scenarios"); //$NON-NLS-1$ if (scenarioPattern != null) DEBUG_WRITER.print(" with pattern "+scenarioPattern); //$NON-NLS-1$ if (buildName != null) DEBUG_WRITER.print(" for build: "+buildName); //$NON-NLS-1$ } ResultSet result = null; Map allScenarios = new HashMap(); try { if (buildName == null) { result = this.fSQL.queryBuildAllScenarios(scenarioPattern); } else { result = this.fSQL.queryBuildScenarios(scenarioPattern, buildName); } int previousId = -1; List scenarios = null; List scenariosNames = new ArrayList(); for (int i = 0; result.next(); i++) { int id = result.getInt(1); String name = result.getString(2); scenariosNames.add(name); String shortName = result.getString(3); int component_id = storeComponent(getComponentNameFromScenario(name)); if (component_id != previousId) { allScenarios.put(COMPONENTS[component_id], scenarios = new ArrayList()); previousId = component_id; } scenarios.add(new ScenarioResults(id, name, shortName)); } SCENARII = new String[scenariosNames.size()]; scenariosNames.toArray(SCENARII); } catch (SQLException e) { PerformanceTestPlugin.log(e); } finally { if (result != null) { try { result.close(); } catch (SQLException e1) { // ignored } } if (DEBUG) DEBUG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$ } return allScenarios; } private void internalQueryScenarioValues(ScenarioResults scenarioResults, String configPattern, String buildName) { if (this.fSQL == null) return; if (DEBUG) { DEBUG_WRITER.print(" - DB query all data points for config pattern: "+configPattern+" for scenario: " + scenarioResults.getShortName()); //$NON-NLS-1$ //$NON-NLS-2$ if (buildName != null) DEBUG_WRITER.print(" for build: "+buildName); //$NON-NLS-1$ } internalQueryAllVariations(configPattern); // need to read all variations to have all build names ResultSet result = null; try { int count = 0; result = buildName == null ? this.fSQL.queryScenarioDataPoints(configPattern, scenarioResults.getId()) : this.fSQL.queryScenarioBuildDataPoints(configPattern, scenarioResults.getId(), buildName); while (result.next()) { int dp_id = result.getInt(1); int step = result.getInt(2); String variation = result.getString(3); // something like "|build=I20070615-1200||config=eclipseperfwin2_R3.3||jvm=sun|" StringTokenizer tokenizer = new StringTokenizer(variation, "=|"); //$NON-NLS-1$ tokenizer.nextToken(); // 'build' int build_id = getBuildId(tokenizer.nextToken()); // 'I20070615-1200' tokenizer.nextToken(); // 'config' int config_id = getConfigId(tokenizer.nextToken()); // 'eclipseperflnx3' ResultSet rs2 = this.fSQL.queryDimScalars(dp_id); while (rs2.next()) { int dim_id = rs2.getInt(1); storeDimension(dim_id); BigDecimal decimalValue = rs2.getBigDecimal(2); long value = decimalValue.longValue(); if (build_id >= 0) { // build id may be negative (i.e. not stored in the array) if new run starts while we're getting results scenarioResults.setValue(build_id, dim_id, config_id, step, value); } count++; } } if (LOG) LOG_WRITER.ends(" -> " + count + " values read"); //$NON-NLS-1$ //$NON-NLS-2$ } catch (SQLException e) { PerformanceTestPlugin.log(e); } finally { if (result != null) { try { result.close(); } catch (SQLException e1) { // ignored } } } } private void internalQueryScenarioSummaries(ScenarioResults scenarioResults, String config, String[] builds) { if (this.fSQL == null) return; long start = System.currentTimeMillis(); if (DEBUG) { DEBUG_WRITER.print(" - DB query all summaries for scenario '"+scenarioResults.getShortName()+"' of '"+config+"' config"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } internalQueryAllComments(); ResultSet result = null; try { int scenarioID = scenarioResults.getId(); // First try to get summaries of elapsed process dimension result = this.fSQL.queryScenarioSummaries(scenarioID, config, builds); while (result.next()) { String variation = result.getString(1); // something like "|build=I20070615-1200||config=eclipseperfwin2_R3.3||jvm=sun|" int summaryKind = result.getShort(2); int comment_id = result.getInt(3); int dim_id = result.getInt(4); if (dim_id != 0) storeDimension(dim_id); StringTokenizer tokenizer = new StringTokenizer(variation, "=|"); //$NON-NLS-1$ tokenizer.nextToken(); // 'build' String buildName = tokenizer.nextToken(); // 'I20070615-1200' tokenizer.nextToken(); // 'config' int config_id = getConfigId(tokenizer.nextToken()); // 'eclipseperflnx3' int build_id = getBuildId(buildName); if (build_id >= 0) { scenarioResults.setInfos(config_id, build_id, dim_id==0?-1:summaryKind, COMMENTS[comment_id]); } } } catch (SQLException e) { PerformanceTestPlugin.log(e); } finally { if (result != null) { try { result.close(); } catch (SQLException e1) { // ignored } } if (DEBUG) DEBUG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$ } } /* * Store a build name in the dynamic list. * The list is sorted alphabetically. */ private int storeBuildName(String build) { boolean isVersion = build.startsWith(DB_BASELINE_PREFIX); if (BUILDS == null) { BUILDS = new String[1]; BUILDS[BUILDS_LENGTH++] = build; if (isVersion) { LAST_BASELINE_BUILD = build; } else { LAST_CURRENT_BUILD = build; } return 0; } int idx = Arrays.binarySearch(BUILDS, build, Util.BUILD_DATE_COMPARATOR); if (idx >= 0) return idx; int index = -idx-1; int length = BUILDS.length; if (BUILDS_LENGTH == length) { String[] array = new String[length+1]; if (index > 0) System.arraycopy(BUILDS, 0, array, 0, index); array[index] = build; if (index < length) { System.arraycopy(BUILDS, index, array, index+1, length-index); } BUILDS = array; } BUILDS_LENGTH++; if (isVersion) { if (LAST_BASELINE_BUILD == null || LAST_CURRENT_BUILD == null) { LAST_BASELINE_BUILD = build; } else { String buildDate = LAST_CURRENT_BUILD.substring(1, 9)+LAST_CURRENT_BUILD.substring(10, LAST_CURRENT_BUILD.length()); String baselineDate = LAST_BASELINE_BUILD.substring(LAST_BASELINE_BUILD.indexOf('_')+1); if (build.compareTo(LAST_BASELINE_BUILD) > 0 && baselineDate.compareTo(buildDate) < 0) { LAST_BASELINE_BUILD = build; } } } else { if (LAST_CURRENT_BUILD == null || build.substring(1).compareTo(LAST_CURRENT_BUILD.substring(1)) >= 0) { LAST_CURRENT_BUILD = build; } } return index; } /* * Store a configuration in the dynamic list. * The list is sorted alphabetically. */ private int storeConfig(String config) { if (CONFIGS== null) { CONFIGS= new String[1]; CONFIGS[0] = config; return 0; } int idx = Arrays.binarySearch(CONFIGS, config); if (idx >= 0) return idx; int length = CONFIGS.length; System.arraycopy(CONFIGS, 0, CONFIGS = new String[length+1], 0, length); CONFIGS[length] = config; Arrays.sort(CONFIGS); return length; } /* * Store a component in the dynamic list. The list is sorted alphabetically. * Note that the array is rebuilt each time a new component is discovered * as this does not happen so often (e.g. eclipse only has 10 components). */ private int storeComponent(String component) { if (COMPONENTS== null) { COMPONENTS= new String[1]; COMPONENTS[0] = component; return 0; } int idx = Arrays.binarySearch(COMPONENTS, component); if (idx >= 0) return idx; int length = COMPONENTS.length; System.arraycopy(COMPONENTS, 0, COMPONENTS = new String[length+1], 0, length); COMPONENTS[length] = component; Arrays.sort(COMPONENTS); return length; } /* * Store a dimension in the dynamic list. The list is sorted in ascending order. * Note that the array is rebuilt each time a new dimension is discovered * as this does not happen so often (e.g. eclipse only stores two dimensions). */ public static int storeDimension(int id) { if (DIMENSIONS == null) { DIMENSIONS = new int[1]; DIMENSIONS[0] = id; return 0; } int idx = Arrays.binarySearch(DIMENSIONS, id); if (idx >= 0) return idx; int length = DIMENSIONS.length; System.arraycopy(DIMENSIONS, 0, DIMENSIONS = new int[length+1], 0, length); DIMENSIONS[length] = id; Arrays.sort(DIMENSIONS); return length; } /* * Store a dimension in the dynamic list. The list is sorted alphabetically. * Note that the array is rebuilt each time a new dimension is discovered * as this does not happen so often (e.g. eclipse only stores two dimensions). */ private int storeVm(String vm) { if (VMS == null) { VMS = new String[1]; VMS[0] = vm; return 0; } int idx = Arrays.binarySearch(VMS, vm); if (idx >= 0) return idx; int length = VMS.length; System.arraycopy(VMS, 0, VMS = new String[length+1], 0, length); VMS[length] = vm; Arrays.sort(VMS); return length; } }