Package org.eclipse.test.internal.performance.results.db

Source Code of org.eclipse.test.internal.performance.results.db.DB_Results$LogWriter

/*******************************************************************************
* 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 ||
      ((databaseLocation == null && DB_LOCATION != 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.
   * <p>
   * Only used if no specific configurations are specified
   * (see {@link PerformanceResults#readAll(String, String[][], String, File, int, org.eclipse.core.runtime.IProgressMonitor)}.
   * </p>
   * 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.php.core", //$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; i<this.max; i++) {
          print(this.buffers[i].toString());
          print(" ( in "); //$NON-NLS-1$
          print(this.times[this.depth]);
          println("ms)"); //$NON-NLS-1$
        }
        this.depth = this.max = -1;
      this.starts = new long[10];
      this.times = new long[10];
        this.buffers = new StringBuffer[10];
      }
    public String toString() {
          return LOG_STR_WRITER.toString();
        }
    }

  // Data storage from queries
  static String LAST_CURRENT_BUILD, LAST_BASELINE_BUILD;
  private static int BUILDS_LENGTH;
  private static String[] SCENARII;
  private static String[] COMMENTS;

    //---- private implementation

  /**
     * Private constructor to block instance creation.
     */
    private DB_Results() {
      // empty implementation
    }

    synchronized static DB_Results getDefault() {
        if (fgDefault == null) {
            fgDefault= new DB_Results();
            fgDefault.connect();
            if (PerformanceTestPlugin.getDefault() == null) {
              // not started as plugin
              Runtime.getRuntime().addShutdownHook(
                  new Thread() {
                      public void run() {
                        shutdown();
                      }
                  }
              );
            }
        } else if (fgDefault.fSQL == null) {
          fgDefault.connect();
        }
        return fgDefault;
    }

    public static void shutdown() {
        if (fgDefault != null) {
            fgDefault.disconnect();
            fgDefault= null;
            BUILDS = null;
            LAST_BASELINE_BUILD = null;
            LAST_CURRENT_BUILD = null;
            DIMENSIONS = null;
            CONFIGS = null;
            COMPONENTS = null;
            SCENARII = null;
            COMMENTS = null;
            DB_VERSION = null;
            DB_VERSION_REF = null;
            DEFAULT_DIM =null;
            DEFAULT_DIM_INDEX = -1;
            RESULTS_DIMENSIONS = null;
            VMS = null;
            CONFIG_DESCRIPTIONS = null;
            KNOWN_COMPONENTS = ECLIPSE_COMPONENTS;
        }
        if (DEBUG) {
          DEBUG_WRITER.println("DB.shutdown"); //$NON-NLS-1$
          System.out.println(DEBUG_STR_WRITER.toString());
        }
        if (LOG) {
          System.out.println(LOG_STR_WRITER.toString());
        }
    }

/**
* Return the build id from a given name.
*
* @param name The build name (eg. I20070615-1200)
* @return The id of the build (ie. the index in the {@link #BUILDS} list)
*/
static int getBuildId(String name) {
  if (BUILDS == null) return -1;
  return Arrays.binarySearch(BUILDS, name, Util.BUILD_DATE_COMPARATOR);
}

/**
* Return the build name from a given id.
*
* @param id The build id
* @return The name of the build (eg. I20070615-1200)
*/
static String getBuildName(int id) {
  if (BUILDS == null) return null;
  return BUILDS[id];
}

/**
* Returns all the builds names read from the database.
*
* @return The list of all builds names matching the scenario pattern used while reading data
*/
public static String[] getBuilds() {
  if (BUILDS == null) {
    queryAllVariations("%"); //$NON-NLS-1$
  }
  if (BUILDS_LENGTH == 0) return EMPTY_LIST;
  String[] builds = new String[BUILDS_LENGTH];
  System.arraycopy(BUILDS, 0, builds, 0, BUILDS_LENGTH);
  return builds;
}

/**
* Get component name from a scenario.
*
* @param scenarioName The name of the scenario
* @return The component name
*/
static String getComponentNameFromScenario(String scenarioName) {
  int length = KNOWN_COMPONENTS.length;
  for (int i=0; i<length; i++) {
    if (scenarioName.startsWith(KNOWN_COMPONENTS[i])) {
      return KNOWN_COMPONENTS[i];
    }
  }
  StringTokenizer tokenizer = new StringTokenizer(scenarioName, ".");
  StringBuffer buffer = new StringBuffer(tokenizer.nextToken());
  if (tokenizer.hasMoreTokens()) {
    buffer.append('.');
    buffer.append(tokenizer.nextToken());
    if (tokenizer.hasMoreTokens()) {
      buffer.append('.');
      buffer.append(tokenizer.nextToken());
    }
  }
  String componentName = buffer.toString();
  System.err.println(scenarioName+" does not belongs to a known Eclipse component. So use scenario prefix "+componentName+" as component name by default and add it to the know components"); //$NON-NLS-1$
  System.arraycopy(KNOWN_COMPONENTS, 0, KNOWN_COMPONENTS = new String[length+1], 0, length);
  KNOWN_COMPONENTS[length] = componentName;
  return componentName;
}

/**
* Get all components read from database.
*
* @return A list of component names matching the given pattern
*/
public static String[] getComponents() {
  if (COMPONENTS == null) return EMPTY_LIST;
  int length = COMPONENTS.length;
  String[] components = new String[length];
  System.arraycopy(COMPONENTS, 0, components, 0, length);
  return components;
}

/**
* Return the name of the configuration from the given id.
*
* @param id The index of the configuration in the stored list.
* @return The name of the configuration (eg. eclipseperflnx1_R3.3)
*/
static String getConfig(int id) {
  return CONFIGS[id];
}

/**
* Get all configurations read from the database.
*
* @return A list of configuration names
*/
public static String[] getConfigs() {
  if (CONFIGS == null) return EMPTY_LIST;
  int length = CONFIGS.length;
  String[] configs = new String[length];
  System.arraycopy(CONFIGS, 0, configs, 0, length);
  return configs;
}

/**
* Set the default dimension used for performance results.
*/
public static void setConfigs(String[] configs) {
  CONFIGS = configs;
}

/**
* Get all configurations read from the database.
*
* @return A list of configuration names
*/
public static String[] getConfigDescriptions() {
  if (CONFIG_DESCRIPTIONS == null) {
    if (CONFIGS == null) return null;
    int length = CONFIGS.length;
    CONFIG_DESCRIPTIONS = new String[length];
    String[][] configDescriptors = PerformanceTestPlugin.getConfigDescriptors();
    int cdLength = configDescriptors.length;
    for (int i = 0; i < length; i++) {
      boolean found = false;
      for (int j = 0; j < cdLength; j++) {
        if (configDescriptors[j][0].equals(CONFIGS[i])) {
              CONFIG_DESCRIPTIONS[i] = configDescriptors[j][1];
              found = true;
              break;
        }
      }
      if (!found) {
        String kind = CONFIGS[i].indexOf("epwin") < 0 ? "Linux" : "Win XP";
        CONFIG_DESCRIPTIONS[i] = kind+" perf test box "+CONFIGS[i].substring(5);
      }
        }
  }
  int length = CONFIG_DESCRIPTIONS.length;
  String[] descriptions = new String[length];
  System.arraycopy(CONFIG_DESCRIPTIONS, 0, descriptions, 0, length);
  return descriptions;
}

/**
* Set the default dimension used for performance results.
*/
public static void setConfigDescriptions(String[] descriptions) {
  CONFIG_DESCRIPTIONS = descriptions;
}

/**
* Get all dimensions read from the database.
*
* @return A list of dimensions.
*/
public static Dim[] getDimensions() {
  if (DIMENSIONS == null) return NO_DIMENSION;
  int length = DIMENSIONS.length;
  Dim[] dimensions = new Dim[length];
  for (int i = 0; i < length; i++) {
    Dimension dimension = PerformanceTestPlugin.getDimension(DIMENSIONS[i]);
    if (dimension == null) {
      throw new RuntimeException("There is an unsupported dimension stored in the database: " +DIMENSIONS[i]);
    }
    dimensions[i] = (Dim) dimension;
    }
  return dimensions;
}

/**
* Return the default dimension used for performance results.
*
* @return The {@link Dim default dimension}.
*/
public static Dim getDefaultDimension() {
  if (DEFAULT_DIM == null) {
    DEFAULT_DIM = (Dim) PerformanceTestPlugin.getDefaultDimension();
  }
  return DEFAULT_DIM;
}

/**
* Set the default dimension used for performance results.
*/
public static void setDefaultDimension(String dim) {
  DEFAULT_DIM = (Dim) PerformanceTestPlugin.getDimension(dim);
  if (DIMENSIONS != null) {
    DEFAULT_DIM_INDEX = Arrays.binarySearch(DIMENSIONS, DEFAULT_DIM.getId());
  }
}

public static Dim[] getResultsDimensions() {
  if (RESULTS_DIMENSIONS == null) {
    Dimension[] resultsDimensions = PerformanceTestPlugin.getResultsDimensions();
    int length = resultsDimensions.length;
    RESULTS_DIMENSIONS = new Dim[length];
    for (int i = 0; i < length; i++) {
      RESULTS_DIMENSIONS[i] = (Dim) resultsDimensions[i];
    }
  }
  return RESULTS_DIMENSIONS;
}

/**
* Set the default dimension used for performance results.
*/
public static void setResultsDimensions(String[] dimensions) {
  int length = dimensions.length;
  RESULTS_DIMENSIONS = new Dim[length];
  for (int i = 0; i < length; i++) {
    RESULTS_DIMENSIONS[i] = (Dim) PerformanceTestPlugin.getDimension(dimensions[i]);
  }
}

/**
* Return the default dimension used for performance results.
*
* @return The {@link Dim default dimension}.
*/
public static int getDefaultDimensionIndex() {
  if (DEFAULT_DIM == null || DEFAULT_DIM_INDEX == -1) {
    getDefaultDimension(); // init default dimension
    getDimensions(); // init dimensions
    DEFAULT_DIM_INDEX = Arrays.binarySearch(DIMENSIONS, DEFAULT_DIM.getId());
  }
  return DEFAULT_DIM_INDEX;
}

/**
* Return the ID of the last baseline build before the given date.
*
* @param date The date the baseline must be run before. If <code>null</code>
*   return the last baseline build stored in the DB.
*
* @return the ID of the last baseline build before the given date or
*   <code>null</code> 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<BUILDS_LENGTH; i++) {
    String build = BUILDS[i];
    if (build.startsWith(DB_BASELINE_PREFIX)) {
      String buildDate = build.substring(build.indexOf('_')+1);
      if (buildDate.compareTo(date) < 0) {
        if (lastBaselineBuild == null || build.compareTo(lastBaselineBuild) > 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 <code>null</code>.
*
* @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 <code>null</code>.
*
* @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 <code>null</code>, 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;
}

}
TOP

Related Classes of org.eclipse.test.internal.performance.results.db.DB_Results$LogWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.