1 11 package org.eclipse.test.internal.performance.db; 12 13 import java.io.File ; 14 import java.sql.Connection ; 15 import java.sql.DriverManager ; 16 import java.sql.ResultSet ; 17 import java.sql.SQLException ; 18 import java.sql.Timestamp ; 19 import java.util.ArrayList ; 20 import java.util.Arrays ; 21 import java.util.Comparator ; 22 import java.util.HashMap ; 23 import java.util.HashSet ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.Set ; 27 import java.util.regex.Matcher ; 28 import java.util.regex.Pattern ; 29 30 import junit.framework.Assert; 31 32 import org.eclipse.test.internal.performance.InternalPerformanceMeter; 33 import org.eclipse.test.internal.performance.PerformanceTestPlugin; 34 import org.eclipse.test.internal.performance.data.DataPoint; 35 import org.eclipse.test.internal.performance.data.Dim; 36 import org.eclipse.test.internal.performance.data.Sample; 37 import org.eclipse.test.internal.performance.data.Scalar; 38 import org.eclipse.test.performance.Dimension; 39 import org.eclipse.test.performance.Performance; 40 41 public class DB { 42 43 private static final boolean DEBUG= false; 44 private static final boolean AGGREGATE= true; 45 46 private static final String DERBY= "derby"; private static final String CLOUDSCAPE= "cloudscape"; 50 private static DB fgDefault; 51 52 private Connection fConnection; 53 private SQL fSQL; 54 private int fStoredSamples; 55 private boolean fStoreCalled; 56 private boolean fIsEmbedded; 57 private String fDBType; 59 60 public static DataPoint[] queryDataPoints(Variations variations, String scenarioName, Set dims) { 62 return getDefault().internalQueryDataPoints(variations, scenarioName, dims); 63 } 64 65 74 public static Scenario[] queryScenarios(String configName, String buildPattern, String scenarioPattern) { 75 Variations variations= new Variations(); 76 variations.put(PerformanceTestPlugin.CONFIG, configName); 77 variations.put(PerformanceTestPlugin.BUILD, buildPattern); 78 return queryScenarios(variations, scenarioPattern, PerformanceTestPlugin.BUILD, null); 79 } 80 81 89 public static Scenario[] queryScenarios(String configName, String [] buildPatterns, String scenarioPattern, Dim[] dimensions) { 90 Variations variations= new Variations(); 91 variations.put(PerformanceTestPlugin.CONFIG, configName); 92 variations.put(PerformanceTestPlugin.BUILD, buildPatterns); 93 return queryScenarios(variations, scenarioPattern, PerformanceTestPlugin.BUILD, dimensions); 94 } 95 96 103 public static Scenario queryScenario(String configName, String [] buildPatterns, String scenarioName) { 104 Variations variations= new Variations(); 105 variations.put(PerformanceTestPlugin.CONFIG, configName); 106 variations.put(PerformanceTestPlugin.BUILD, buildPatterns); 107 return new Scenario(scenarioName, variations, PerformanceTestPlugin.BUILD, null); 108 } 109 110 122 public static Scenario[] queryScenarios(Variations variations, String scenarioPattern, String seriesKey, Dim[] dimensions) { 123 String [] scenarioNames= getDefault().internalQueryScenarioNames(variations, scenarioPattern); if (scenarioNames == null) 125 return new Scenario[0]; 126 Scenario.SharedState ss= new Scenario.SharedState(variations, scenarioPattern, seriesKey, dimensions); 127 Scenario[] tables= new Scenario[scenarioNames.length]; 128 for (int i= 0; i < scenarioNames.length; i++) 129 tables[i]= new Scenario(scenarioNames[i], ss); 130 return tables; 131 } 132 133 141 public static SummaryEntry[] querySummaries(Variations variationPatterns, String scenarioPattern) { 142 return getDefault().internalQuerySummaries(variationPatterns, scenarioPattern); 143 } 144 145 151 public static void queryBuildNames(List names, Variations variationPatterns, String scenarioPattern) { 152 getDefault().internalQueryDistinctValues(names, PerformanceTestPlugin.BUILD, variationPatterns, scenarioPattern); 153 } 154 155 public static void queryDistinctValues(List values, String key, Variations variationPatterns, String scenarioPattern) { 156 getDefault().internalQueryDistinctValues(values, key, variationPatterns, scenarioPattern); 157 } 158 159 public static String [] querySeriesValues(String scenarioName, Variations v, String seriesKey) { 160 return getDefault().internalQuerySeriesValues(v, scenarioName, seriesKey); 161 } 162 163 public static Scenario getScenarioSeries(String scenarioName, Variations v, String seriesKey, String startBuild, String endBuild, Dim[] dims) { 164 v= (Variations) v.clone(); 165 v.put(seriesKey, new String [] { startBuild, endBuild }); 166 Scenario.SharedState ss= new Scenario.SharedState(v, scenarioName, seriesKey, dims); 167 Scenario scenario= new Scenario(scenarioName, ss); 168 TimeSeries ts= scenario.getTimeSeries(dims[0]); 169 if (ts.getLength() < 2) { 170 v.put(seriesKey, "%"); String [] names= DB.querySeriesValues(scenarioName, v, seriesKey); 172 if (names.length >= 2) { 173 String start= findClosest(names, startBuild); 174 String end= findClosest(names, endBuild); 175 v.put(seriesKey, new String [] { start, end }); 176 scenario= new Scenario(scenarioName, ss); 177 } 178 } 179 return scenario; 180 } 181 182 public static Map queryFailure(String scenarioPattern, Variations variations) { 183 return getDefault().internalQueryFailure(scenarioPattern, variations); 184 } 185 186 private static String findClosest(String [] names, String name) { 187 for (int i= 0; i < names.length; i++) 188 if (names[i].equals(name)) 189 return name; 190 191 Pattern pattern= Pattern.compile("200[3-9][01][0-9][0-3][0-9]"); Matcher matcher= pattern.matcher(name); 194 if (!matcher.find()) 195 return name; 196 197 int x= Integer.parseInt(name.substring(matcher.start(), matcher.end())); 198 int ix= -1; 199 int mind= 0; 200 201 for (int i= 0; i < names.length; i++) { 202 matcher.reset(names[i]); 203 if (matcher.find()) { 204 int y= Integer.parseInt(names[i].substring(matcher.start(), matcher.end())); 205 int d= Math.abs(y-x); 206 if (ix < 0 || d < mind) { 207 mind= d; 208 ix= i; 209 } 210 } 211 } 212 213 if (ix >= 0) 214 return names[ix]; 215 return name; 216 } 217 218 225 public static boolean store(Variations variations, Sample sample) { 226 return getDefault().internalStore(variations, sample); 227 } 228 229 234 public static void markAsFailed(Variations variations, Sample sample, String failMesg) { 235 getDefault().internalMarkAsFailed(variations, sample, failMesg); 236 } 237 238 public static Connection getConnection() { 239 return getDefault().fConnection; 240 } 241 242 public static boolean isActive() { 243 return fgDefault != null && fgDefault.getSQL() != null; 244 } 245 246 248 251 private DB() { 252 } 254 255 synchronized static DB getDefault() { 256 if (fgDefault == null) { 257 fgDefault= new DB(); 258 fgDefault.connect(); 259 if (PerformanceTestPlugin.getDefault() == null) { 260 Runtime.getRuntime().addShutdownHook( 262 new Thread () { 263 public void run() { 264 shutdown(); 265 } 266 } 267 ); 268 } 269 } 270 return fgDefault; 271 } 272 273 public static void shutdown() { 274 if (DEBUG) System.out.println("DB.shutdown"); if (fgDefault != null) { 276 fgDefault.disconnect(); 277 fgDefault= null; 278 } 279 } 280 281 SQL getSQL() { 282 return fSQL; 283 } 284 285 private void internalMarkAsFailed(Variations variations, Sample sample, String failMesg) { 286 287 if (fSQL == null) 288 return; 289 290 try { 291 int variation_id= fSQL.getVariations(variations); 292 int scenario_id= fSQL.getScenario(sample.getScenarioID()); 293 294 fSQL.insertFailure(variation_id, scenario_id, failMesg); 295 296 fConnection.commit(); 297 298 } catch (SQLException e) { 299 PerformanceTestPlugin.log(e); 300 try { 301 fConnection.rollback(); 302 } catch (SQLException e1) { 303 PerformanceTestPlugin.log(e1); 304 } 305 } 306 } 307 308 private boolean internalStore(Variations variations, Sample sample) { 309 310 if (fSQL == null || sample == null) 311 return false; 312 313 DataPoint[] dataPoints= sample.getDataPoints(); 314 int n= dataPoints.length; 315 if (n <= 0) 316 return false; 317 318 Scalar[] sc= null; 319 long[] averages= null; 320 if (AGGREGATE) { 321 322 sc= dataPoints[0].getScalars(); 323 averages= new long[sc.length]; 324 325 Set set= new HashSet (); 326 for (int j= 0; j < dataPoints.length; j++) { 327 DataPoint dp= dataPoints[j]; 328 set.add(new Integer (dp.getStep())); 329 } 330 switch (set.size()) { 331 case 2: for (int i= 0; i < dataPoints.length-1; i+= 2) { 333 Scalar[] s1= dataPoints[i].getScalars(); 334 Scalar[] s2= dataPoints[i+1].getScalars(); 335 for (int j= 0; j < sc.length; j++) 336 averages[j] += s2[j].getMagnitude() - s1[j].getMagnitude(); 337 } 338 n= n/2; 339 break; 340 341 case 1: for (int i= 0; i < dataPoints.length; i++) { 343 Scalar[] s= dataPoints[i].getScalars(); 344 for (int j= 0; j < sc.length; j++) 345 averages[j] += s[j].getMagnitude(); 346 } 347 break; 348 349 default: PerformanceTestPlugin.logError("DB.internalStore: too many steps in DataPoint"); return false; 352 } 353 } 354 355 try { 357 int variation_id= fSQL.getVariations(variations); 359 int scenario_id= fSQL.getScenario(sample.getScenarioID()); 360 if (sample.isSummary()) { 361 boolean isGlobal= sample.isGlobal(); 362 363 int commentId= 0; 364 int commentKind= sample.getCommentType(); 365 String comment= sample.getComment(); 366 if (commentKind == Performance.EXPLAINS_DEGRADATION_COMMENT && comment != null) 367 commentId= fSQL.getCommentId(commentKind, comment); 368 369 Dimension[] summaryDimensions= sample.getSummaryDimensions(); 370 for (int i= 0; i < summaryDimensions.length; i++) { 371 Dimension dimension= summaryDimensions[i]; 372 if (dimension instanceof Dim) 373 fSQL.createSummaryEntry(variation_id, scenario_id, ((Dim)dimension).getId(), isGlobal, commentId); 374 } 375 String shortName= sample.getShortname(); 376 if (shortName != null) 377 fSQL.setScenarioShortName(scenario_id, shortName); 378 } 379 int sample_id= fSQL.createSample(variation_id, scenario_id, new Timestamp (sample.getStartTime())); 380 381 if (sc != null) { 382 int datapoint_id= fSQL.createDataPoint(sample_id, 0, InternalPerformanceMeter.AVERAGE); 383 for (int k= 0; k < sc.length; k++) { 384 int dim_id= sc[k].getDimension().getId(); 385 fSQL.insertScalar(datapoint_id, dim_id, averages[k] / n); 386 } 387 } else { 388 for (int i= 0; i < dataPoints.length; i++) { 389 DataPoint dp= dataPoints[i]; 390 int datapoint_id= fSQL.createDataPoint(sample_id, i, dp.getStep()); 391 Scalar[] scalars= dp.getScalars(); 392 for (int j= 0; j < scalars.length; j++) { 393 Scalar scalar= scalars[j]; 394 int dim_id= scalar.getDimension().getId(); 395 long value= scalar.getMagnitude(); 396 fSQL.insertScalar(datapoint_id, dim_id, value); 397 } 398 } 399 } 400 401 fConnection.commit(); 402 fStoredSamples++; 403 fStoreCalled= true; 404 405 407 } catch (SQLException e) { 408 PerformanceTestPlugin.log(e); 409 try { 410 fConnection.rollback(); 411 } catch (SQLException e1) { 412 PerformanceTestPlugin.log(e1); 413 } 414 } 415 return true; 416 } 417 418 private DataPoint[] internalQueryDataPoints(Variations variations, String scenarioName, Set dimSet) { 419 if (fSQL == null) 420 return null; 421 422 ResultSet rs= null; 423 try { 424 ArrayList dataPoints= new ArrayList (); 425 rs= fSQL.queryDataPoints(variations, scenarioName); 426 while (rs.next()) { 427 int datapoint_id= rs.getInt(1); 428 int step= rs.getInt(2); 429 430 HashMap map= new HashMap (); 431 ResultSet rs2= fSQL.queryScalars(datapoint_id); 432 while (rs2.next()) { 433 int dim_id= rs2.getInt(1); 434 long value= rs2.getBigDecimal(2).longValue(); 435 Dim dim= Dim.getDimension(dim_id); 436 if (dim != null) { 437 if (dimSet == null || dimSet.contains(dim)) 438 map.put(dim, new Scalar(dim, value)); 439 } 440 } 441 if (map.size() > 0) 442 dataPoints.add(new DataPoint(step, map)); 443 444 rs2.close(); 445 } 446 rs.close(); 447 448 int n= dataPoints.size(); 449 if (DEBUG) System.out.println("query resulted in " + n + " datapoints from DB"); return (DataPoint[])dataPoints.toArray(new DataPoint[n]); 451 452 } catch (SQLException e) { 453 PerformanceTestPlugin.log(e); 454 455 } finally { 456 if (rs != null) 457 try { 458 rs.close(); 459 } catch (SQLException e1) { 460 } 462 } 463 return null; 464 } 465 466 469 private String [] internalQueryScenarioNames(Variations variations, String scenarioPattern) { 470 if (fSQL == null) 471 return null; 472 ResultSet result= null; 473 try { 474 result= fSQL.queryScenarios(variations, scenarioPattern); 475 ArrayList scenarios= new ArrayList (); 476 for (int i= 0; result.next(); i++) 477 scenarios.add(result.getString(1)); 478 return (String [])scenarios.toArray(new String [scenarios.size()]); 479 480 } catch (SQLException e) { 481 PerformanceTestPlugin.log(e); 482 483 } finally { 484 if (result != null) 485 try { 486 result.close(); 487 } catch (SQLException e1) { 488 } 490 } 491 return null; 492 } 493 494 497 private void internalQueryDistinctValues(List values, String seriesKey, Variations variations, String scenarioPattern) { 498 if (fSQL == null) 499 return; 500 ResultSet result= null; 501 try { 502 result= fSQL.queryVariations(variations.toExactMatchString(), scenarioPattern); 503 for (int i= 0; result.next(); i++) { 504 Variations v= new Variations(); 505 v.parseDB(result.getString(1)); 506 String build= v.getProperty(seriesKey); 507 if (build != null && !values.contains(build)) 508 values.add(build); 509 } 510 } catch (SQLException e) { 511 PerformanceTestPlugin.log(e); 512 513 } finally { 514 if (result != null) 515 try { 516 result.close(); 517 } catch (SQLException e1) { 518 } 520 } 521 } 522 523 private SummaryEntry[] internalQuerySummaries(Variations variationPatterns, String scenarioPattern) { 524 if (fSQL == null) 525 return null; 526 ResultSet result= null; 527 try { 528 List fingerprints= new ArrayList (); 529 ResultSet rs; 530 if (scenarioPattern != null) 531 rs= fSQL.querySummaryEntries(variationPatterns, scenarioPattern); 532 else 533 rs= fSQL.queryGlobalSummaryEntries(variationPatterns); 534 while (rs.next()) { 535 String scenarioName= rs.getString(1); 536 String shortName= rs.getString(2); 537 int dim_id= rs.getInt(3); 538 boolean isGlobal= rs.getShort(4) == 1; 539 int comment_id= rs.getInt(5); 540 int commentKind= 0; 541 String comment= null; 542 if (comment_id != 0) { 543 ResultSet rs2= fSQL.getComment(comment_id); 544 if (rs2.next()) { 545 commentKind= rs2.getInt(1); 546 comment= rs2.getString(2); 547 } 548 } 549 fingerprints.add(new SummaryEntry(scenarioName, shortName, Dim.getDimension(dim_id), isGlobal, commentKind, comment)); 550 } 551 return (SummaryEntry[])fingerprints.toArray(new SummaryEntry[fingerprints.size()]); 552 } catch (SQLException e) { 553 PerformanceTestPlugin.log(e); 554 555 } finally { 556 if (result != null) 557 try { 558 result.close(); 559 } catch (SQLException e1) { 560 } 562 } 563 return null; 564 } 565 566 private String [] internalQuerySeriesValues(Variations v, String scenarioName, String seriesKey) { 567 568 boolean isCloned= false; 569 570 String [] seriesPatterns= null; 571 Object object= v.get(seriesKey); 572 if (object instanceof String []) 573 seriesPatterns= (String []) object; 574 else if (object instanceof String ) 575 seriesPatterns= new String [] { (String ) object }; 576 else 577 Assert.assertTrue(false); 578 579 ArrayList values= new ArrayList (); 580 for (int i= 0; i < seriesPatterns.length; i++) { 581 if (seriesPatterns[i].indexOf('%') >= 0) { 582 if (! isCloned) { 583 v= (Variations) v.clone(); 584 isCloned= true; 585 } 586 v.put(seriesKey, seriesPatterns[i]); 587 internalQueryDistinctValues(values, seriesKey, v, scenarioName); 588 } else 589 values.add(seriesPatterns[i]); 590 } 591 592 String [] names= (String [])values.toArray(new String [values.size()]); 593 594 boolean sort= true; 595 Pattern pattern= Pattern.compile("200[3-9][01][0-9][0-3][0-9]"); final Matcher matcher= pattern.matcher(""); for (int i= 0; i < names.length; i++) { 598 matcher.reset(names[i]); 599 if (! matcher.find()) { 600 sort= false; 601 break; 602 } 603 } 604 if (sort) { 605 Arrays.sort(names, 606 new Comparator () { 607 public int compare(Object o1, Object o2) { 608 String s1= (String )o1; 609 String s2= (String )o2; 610 611 matcher.reset(s1); 612 if (matcher.find()) 613 s1= s1.substring(matcher.start()); 614 615 matcher.reset(s2); 616 if (matcher.find()) 617 s2= s2.substring(matcher.start()); 618 619 return s1.compareTo(s2); 620 } 621 } 622 ); 623 } 624 return names; 625 } 626 627 private Map internalQueryFailure(String scenarioPattern, Variations variations) { 628 if (fSQL == null) 629 return null; 630 ResultSet result= null; 631 try { 632 Map map= new HashMap (); 633 result= fSQL.queryFailure(variations, scenarioPattern); 634 while (result.next()) { 635 String scenario= result.getString(1); 636 String message= result.getString(2); 637 map.put(scenario, message); 638 } 639 return map; 640 } catch (SQLException e) { 641 PerformanceTestPlugin.log(e); 642 643 } finally { 644 if (result != null) 645 try { 646 result.close(); 647 } catch (SQLException e1) { 648 } 650 } 651 return null; 652 } 653 654 660 private void connect() { 661 662 if (fConnection != null) 663 return; 664 665 String dbloc= PerformanceTestPlugin.getDBLocation(); 666 if (dbloc == null) 667 return; 668 669 String dbname= PerformanceTestPlugin.getDBName(); 670 String url= null; 671 java.util.Properties info= new java.util.Properties (); 672 673 fDBType= DERBY; try { 675 if (dbloc.startsWith("net://")) { fIsEmbedded= false; 678 if (DEBUG) System.out.println("Trying to connect over network..."); Class.forName("com.ibm.db2.jcc.DB2Driver"); info.put("user", PerformanceTestPlugin.getDBUser()); info.put("password", PerformanceTestPlugin.getDBPassword()); info.put("retrieveMessagesFromServerOnGetMessage", "true"); url= dbloc + "/" + dbname + ";create=true"; } else { 686 687 if ("Mac OS X".equals(System.getProperty("os.name"))) System.setProperty("derby.storage.fileSyncTransactionLog", "true"); 691 fIsEmbedded= true; 693 try { 694 Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); } catch (ClassNotFoundException e) { 696 Class.forName("com.ihost.cs.jdbc.CloudscapeDriver"); fDBType= CLOUDSCAPE; 698 } 699 if (DEBUG) System.out.println("Loaded embedded " + fDBType); File f; 701 if (dbloc.length() == 0) { 702 String user_home= System.getProperty("user.home"); if (user_home == null) 704 return; 705 f= new File (user_home, fDBType); 706 } else 707 f= new File (dbloc); 708 url= new File (f, dbname).getAbsolutePath(); 709 info.put("create", "true"); } 711 try { 712 fConnection= DriverManager.getConnection("jdbc:" + fDBType + ":" + url, info); } catch (SQLException e) { 714 if ("08001".equals(e.getSQLState()) && DERBY.equals(fDBType)) { if (DEBUG) System.out.println("DriverManager.getConnection failed; retrying for cloudscape"); fDBType= CLOUDSCAPE; 718 fConnection= DriverManager.getConnection("jdbc:" + fDBType + ":" + url, info); } else 720 throw e; 721 } 722 if (DEBUG) System.out.println("connect succeeded!"); 724 fConnection.setAutoCommit(false); 725 fSQL= new SQL(fConnection); 726 fConnection.commit(); 727 728 } catch (SQLException ex) { 729 PerformanceTestPlugin.logError(ex.getMessage()); 730 731 } catch (ClassNotFoundException e) { 732 PerformanceTestPlugin.log(e); 733 } 734 } 735 736 private void disconnect() { 737 if (DEBUG && fStoreCalled) 738 System.out.println("stored " + fStoredSamples + " new datapoints in DB"); if (DEBUG) System.out.println("disconnecting from DB"); if (fSQL != null) { 741 try { 742 fSQL.dispose(); 743 } catch (SQLException e1) { 744 PerformanceTestPlugin.log(e1); 745 } 746 fSQL= null; 747 } 748 if (fConnection != null) { 749 try { 750 fConnection.commit(); 751 } catch (SQLException e) { 752 PerformanceTestPlugin.log(e); 753 } 754 try { 755 fConnection.close(); 756 } catch (SQLException e) { 757 PerformanceTestPlugin.log(e); 758 } 759 fConnection= null; 760 } 761 762 if (fIsEmbedded) { 763 try { 764 DriverManager.getConnection("jdbc:" + fDBType + ":;shutdown=true"); } catch (SQLException e) { 766 String message= e.getMessage(); 767 if (message.indexOf("system shutdown.") < 0) e.printStackTrace(); 769 } 770 } 771 } 772 } 773 | Popular Tags |