0001: package org.apache.ojb.performance;
0002:
0003: /* Copyright 2002-2005 The Apache Software Foundation
0004: *
0005: * Licensed under the Apache License, Version 2.0 (the "License");
0006: * you may not use this file except in compliance with the License.
0007: * You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: import java.io.File;
0019: import java.io.FileNotFoundException;
0020: import java.io.FileOutputStream;
0021: import java.io.PrintStream;
0022: import java.util.ArrayList;
0023: import java.util.Collection;
0024: import java.util.Collections;
0025: import java.util.Comparator;
0026: import java.util.Date;
0027: import java.util.HashMap;
0028: import java.util.Iterator;
0029: import java.util.List;
0030: import java.util.Map;
0031: import java.util.StringTokenizer;
0032: import java.lang.reflect.Constructor;
0033:
0034: import org.apache.commons.lang.SystemUtils;
0035: import org.apache.commons.lang.exception.ExceptionUtils;
0036: import org.apache.commons.lang.math.NumberUtils;
0037:
0038: /**
0039: * The OJB stress/performance test - a simple performance test application to
0040: * run O/R mapper in a simulated single/multi-threaded environment.
0041: *
0042: * <p>
0043: * <b>You have two possibilities to run this test:</b>
0044: * </p>
0045: * <p>
0046: * - use the OJB build script and call
0047: * <br/>
0048: * <code>ant perf-test</code>
0049: * </p>
0050: * <p>
0051: * - or for standalone use perform the test class by yourself
0052: * <br/>
0053: * <code>
0054: * java -classpath CLASSPATH org.apache.ojb.performance.PerfMain
0055: * </code>
0056: * <br/>
0057: * <code>
0058: * [comma separated list of PerfTest implementation classes, no blanks!]
0059: * </code>
0060: * <br/>
0061: * <code>
0062: * [number of test loops, default '5']
0063: * </code>
0064: * <br/>
0065: * <code>
0066: * [number of threads, default '10']
0067: * </code>
0068: * <br/>
0069: * <code>
0070: * [number of insert/fetch/delete loops per thread, default '100']
0071: * </code>
0072: * <br/>
0073: * <code>
0074: * [boolean - run in stress mode if set true, run in performance mode if set false, default 'false']
0075: * </code>
0076: * <br/>
0077: * <code>
0078: * [boolean - if 'true' all log messages will be print, else only a test summary, default 'true']
0079: * </code>
0080: * </p>
0081: * <p>
0082: * For example:
0083: * </p>
0084: * <code>java -classpath CLASSPATH my.MyPerfTest,myMyPerfTest2 3 10 200 false true</code>
0085: *
0086: * @version $Id: PerfMain.java,v 1.9.2.7 2005/12/30 00:01:42 arminw Exp $
0087: */
0088: public class PerfMain {
0089: static final int TEST_INSERT = 0;
0090: static final int TEST_FETCH = 1;
0091: static final int TEST_FETCH_2 = 2;
0092: static final int TEST_BY_IDENTITY = 3;
0093: static final int TEST_UPDATE = 4;
0094: static final int TEST_DELETE = 5;
0095:
0096: static final short TIME_TOTAL = 0;
0097: static final short TIME_INSERT = 1;
0098: static final short TIME_FETCH = 2;
0099: static final short TIME_FETCH_2 = 3;
0100: static final short TIME_BY_IDENTITY = 4;
0101: static final short TIME_UPDATE = 5;
0102: static final short TIME_DELETE = 6;
0103:
0104: /**
0105: * The factor for get by Identity calls, e.g. 4 means handling 100 objects
0106: * result in 100/4 getByIdentity calls.
0107: */
0108: protected static final int BY_IDENTITY_FACTOR = 4;
0109: protected static final String EOL = SystemUtils.LINE_SEPARATOR;
0110:
0111: /** iterations per thread */
0112: private static int iterationsPerThread = 100;
0113: /** number of concurrent threads */
0114: private static int concurrentThreads = 10;
0115: /** if false we use performance optimized delete/insert method */
0116: private static boolean useStressMode = false;
0117: /** number of test loops */
0118: private static int testLoops = 5;
0119: /** if false only a test summary will be print*/
0120: private static boolean logAll = true;
0121:
0122: private HashMap resultMap;
0123: private HashMap exceptionMap;
0124: private static Printer printer;
0125:
0126: public static void main(String[] args) {
0127: PerfMain main = new PerfMain();
0128: try {
0129: long peroid = System.currentTimeMillis();
0130: // start the test
0131: main.startPerfTest(args);
0132: // print the test results
0133: main.printResult();
0134: peroid = System.currentTimeMillis() - peroid;
0135: if (logAll)
0136: printer().println();
0137: if (logAll)
0138: printer().println(
0139: "PerfTest takes " + peroid / 1000 + " [sec]");
0140: } catch (Exception e) {
0141: e.printStackTrace();
0142: }
0143: System.exit(0);
0144: }
0145:
0146: public PerfMain() {
0147: this .resultMap = new HashMap();
0148: this .exceptionMap = new HashMap();
0149: }
0150:
0151: public static Printer printer() {
0152: if (printer == null) {
0153: printer = new Printer();
0154: }
0155: return printer;
0156: }
0157:
0158: /** Call this to begin the performance test. */
0159: public void startPerfTest(String[] args) throws Exception {
0160: ArrayList testList = null;
0161: try {
0162: // comma separated list of the PerfTest implementation classes
0163: if (args.length > 0) {
0164: StringTokenizer tok = new StringTokenizer(args[0], ",");
0165: testList = new ArrayList();
0166: while (tok.hasMoreTokens()) {
0167: testList.add(tok.nextToken().trim());
0168: }
0169: } else {
0170: throw new IllegalArgumentException(
0171: "No test handles found!");
0172: }
0173: // number of test loops
0174: if (args.length > 1) {
0175: testLoops = args.length > 1 ? Integer.parseInt(args[1])
0176: : 1;
0177: }
0178: // number of threads
0179: if (args.length > 2) {
0180: concurrentThreads = Integer.parseInt(args[2]);
0181: }
0182: // number of insert/fetch/delete loops per thread
0183: if (args.length > 3) {
0184: iterationsPerThread = Integer.parseInt(args[3]);
0185: }
0186: // run in stress mode
0187: if (args.length > 4) {
0188: useStressMode = Boolean.valueOf(args[4]).booleanValue();
0189: }
0190: // log mode
0191: if (args.length > 5) {
0192: logAll = Boolean.valueOf(args[5]).booleanValue();
0193: }
0194: } catch (Exception e) {
0195: e.printStackTrace();
0196: System.err.println();
0197: System.err
0198: .println("Usage of PerfMain:"
0199: + "java -classpath CLASSPATH org.apache.ojb.performance.PerfMain"
0200: + " [comma separated list of PerfTest implementation classes]"
0201: + " [number of test loops]"
0202: + " [number of threads]"
0203: + " [number of insert/fetch/delete loops per thread]"
0204: + " [boolean - run in stress mode]"
0205: + " [boolean - if 'true' detailed log messages will be print]");
0206: System.err.println();
0207: System.err
0208: .println("Example: java -classpath"
0209: + " CLASSPATH org.apache.ojb.performance.PerfMain org.MyPerfTest 3 10 500 false");
0210: }
0211:
0212: if (logAll)
0213: printer()
0214: .println(
0215: " "
0216: + EOL
0217: + "Start OJB performance-test framework - running "
0218: + testLoops
0219: + " loops"
0220: + EOL
0221: + "-------------------------------------------------------");
0222:
0223: PerfRunner test;
0224: for (int i = 0; i < testLoops; i++) {
0225: Runtime rt = Runtime.getRuntime();
0226: long freeMem;
0227: if (logAll)
0228: printer().println(" Loop " + (i + 1));
0229:
0230: if (i % 2 == 0) {
0231: for (int j = 0; j < testList.size(); j++) {
0232: String perfTest = (String) testList.get(j);
0233: Class testHandle = Class.forName(perfTest);
0234: test = new PerfRunner(testHandle);
0235: test.registerPerfMain(this );
0236:
0237: rt.gc();
0238: Thread.sleep(300);
0239: rt.freeMemory();
0240: rt.gc();
0241: Thread.sleep(100);
0242: freeMem = rt.freeMemory();
0243: test.performTest();
0244: freeMem = (freeMem - rt.freeMemory()) / 1024;
0245: if (logAll)
0246: printer().println(
0247: " allocated memory=" + freeMem + "kb");
0248: // rt.gc();
0249: }
0250: } else {
0251: for (int j = (testList.size() - 1); j >= 0; j--) {
0252: String perfTest = (String) testList.get(j);
0253: Class testHandle = Class.forName(perfTest);
0254: test = new PerfRunner(testHandle);
0255: test.registerPerfMain(this );
0256:
0257: rt.gc();
0258: Thread.sleep(300);
0259: rt.freeMemory();
0260: rt.gc();
0261: Thread.sleep(100);
0262: freeMem = rt.freeMemory();
0263: test.performTest();
0264: freeMem = (freeMem - rt.freeMemory()) / 1024;
0265: if (logAll)
0266: printer()
0267: .println(
0268: " allocated memory: " + freeMem
0269: + " kb");
0270: // rt.gc();
0271: }
0272: }
0273: }
0274: }
0275:
0276: public void printResult() {
0277: printer().println();
0278: if (!getExceptionMap().isEmpty()) {
0279: StringBuffer buf = new StringBuffer();
0280: buf.append(EOL).append("Failures occured, test not valid:")
0281: .append(EOL);
0282: Iterator it = getExceptionMap().entrySet().iterator();
0283: while (it.hasNext()) {
0284: Map.Entry entry = (Map.Entry) it.next();
0285: buf.append("Failure cause by ").append(entry.getKey());
0286: if (entry.getValue() != null) {
0287: Throwable ex = ExceptionUtils
0288: .getRootCause((Exception) entry.getValue());
0289: if (ex == null)
0290: ex = (Exception) entry.getValue();
0291: buf.append(EOL).append("Exception was: ").append(
0292: EOL).append(
0293: ExceptionUtils.getStackTrace(ex));
0294: }
0295: buf.append(EOL);
0296: }
0297: printer().println(buf.toString());
0298: }
0299: printer().println(buildTestSummary(prepareTestResults()));
0300: }
0301:
0302: private PerfResult[] prepareTestResults() {
0303: List tmp = new ArrayList(resultMap.values());
0304: Collections.sort(tmp, new Comparator() {
0305: public int compare(Object o1, Object o2) {
0306: PerfResult r1 = (PerfResult) o1;
0307: PerfResult r2 = (PerfResult) o2;
0308: return new Long(r1.getTotalTime()).compareTo(new Long(
0309: r2.getTotalTime()));
0310: }
0311: });
0312:
0313: PerfResult[] results = (PerfResult[]) tmp
0314: .toArray(new PerfResult[tmp.size()]);
0315: long[][] calibration = new long[6][results.length];
0316: for (int k = 0; k < 6; k++) {
0317: for (int i = 0; i < results.length; i++) {
0318: PerfResult result = results[i];
0319: if (k == TEST_INSERT)
0320: calibration[TEST_INSERT][i] = result
0321: .getInsertPeriod();
0322: if (k == TEST_FETCH)
0323: calibration[TEST_FETCH][i] = result
0324: .getFetchPeriod();
0325: if (k == TEST_FETCH_2)
0326: calibration[TEST_FETCH_2][i] = result
0327: .getFetchSecondPeriod();
0328: if (k == TEST_BY_IDENTITY)
0329: calibration[TEST_BY_IDENTITY][i] = result
0330: .getByIdentityPeriod();
0331: if (k == TEST_UPDATE)
0332: calibration[TEST_UPDATE][i] = result
0333: .getUpdatePeriod();
0334: if (k == TEST_DELETE)
0335: calibration[TEST_DELETE][i] = result
0336: .getDeletePeriod();
0337: }
0338: }
0339:
0340: for (int k = 0; k < 6; k++) {
0341: if (k == TEST_INSERT) {
0342: long[] resultArray = calibration[TEST_INSERT];
0343: long minimum = NumberUtils.min(resultArray);
0344: for (int i = 0; i < results.length; i++) {
0345: results[i].setInsertMinimun(minimum);
0346: }
0347: }
0348: if (k == TEST_FETCH) {
0349: long[] resultArray = calibration[TEST_FETCH];
0350: long minimum = NumberUtils.min(resultArray);
0351: for (int i = 0; i < results.length; i++) {
0352: results[i].setFetchMinimun(minimum);
0353: }
0354: }
0355: if (k == TEST_FETCH_2) {
0356: long[] resultArray = calibration[TEST_FETCH_2];
0357: long minimum = NumberUtils.min(resultArray);
0358: for (int i = 0; i < results.length; i++) {
0359: results[i].setFetchSecondMinimun(minimum);
0360: }
0361: }
0362: if (k == TEST_BY_IDENTITY) {
0363: long[] resultArray = calibration[TEST_BY_IDENTITY];
0364: long minimum = NumberUtils.min(resultArray);
0365: for (int i = 0; i < results.length; i++) {
0366: results[i].setByIdentityMinimun(minimum);
0367: }
0368: }
0369: if (k == TEST_UPDATE) {
0370: long[] resultArray = calibration[TEST_UPDATE];
0371: long minimum = NumberUtils.min(resultArray);
0372: for (int i = 0; i < results.length; i++) {
0373: results[i].setUpdateMinimun(minimum);
0374: }
0375: }
0376: if (k == TEST_DELETE) {
0377: long[] resultArray = calibration[TEST_DELETE];
0378: long minimum = NumberUtils.min(resultArray);
0379: for (int i = 0; i < results.length; i++) {
0380: results[i].setDeleteMinimun(minimum);
0381: }
0382: }
0383: }
0384:
0385: return results;
0386: }
0387:
0388: private String buildTestSummary(PerfResult[] results) {
0389: int columnLength = 12;
0390: int columnNumbers = 8;
0391: final String indent = " ";
0392:
0393: StringBuffer buf = new StringBuffer();
0394: // table header
0395: buf.append(EOL);
0396: for (int i = 0; i < columnNumbers; i++) {
0397: buf.append(alignToLength(columnLength, "="));
0398: }
0399: buf.append(EOL);
0400: buf.append(alignToLength(columnLength, " "));
0401: String headline = "OJB PERFORMANCE TEST SUMMARY, " + new Date();
0402: buf.append(alignLeft(headline, columnLength));
0403: buf.append(EOL);
0404: for (int i = 0; i < columnNumbers; i++) {
0405: buf.append(alignToLength(columnLength, "-"));
0406: }
0407: buf.append(EOL);
0408: buf.append(indent).append(PerfMain.getConcurrentThreads());
0409: buf.append(" concurrent threads, handle ");
0410: buf.append(PerfMain.getIterationsPerThread());
0411: buf.append(" objects per thread");
0412: buf.append(EOL).append(indent).append(iterationsPerThread)
0413: .append(" INSERT operations per test instance");
0414: buf.append(EOL).append(indent + "FETCH collection of ").append(
0415: iterationsPerThread).append(
0416: " objects per test instance");
0417: buf.append(EOL).append(indent + "Repeat FETCH collection of ")
0418: .append(iterationsPerThread).append(
0419: " objects per test instance");
0420: int byIdCalls = (iterationsPerThread / PerfMain.BY_IDENTITY_FACTOR);
0421: buf.append(EOL).append(indent).append(
0422: (byIdCalls == 0 ? 1 : byIdCalls)).append(
0423: " get by Identity calls per test instance");
0424: buf.append(EOL).append(indent).append(iterationsPerThread)
0425: .append(" UPDATE operations per test instance");
0426: buf.append(EOL).append(indent).append(iterationsPerThread)
0427: .append(" DELETE operations per test instance");
0428: buf.append(EOL).append(indent);
0429: buf.append("- ").append(
0430: !(isUseStressMode()) ? "performance mode"
0431: : "stress mode");
0432: buf.append(" - results per test instance (average)");
0433: buf.append(EOL);
0434: for (int i = 0; i < columnNumbers; i++) {
0435: buf.append(alignToLength(columnLength, "="));
0436: }
0437: buf.append(EOL);
0438: buf.append(alignLeft("API", columnLength));
0439: //buf.append(alignLeft("Period", columnLength, " "));
0440: //buf.append(alignLeft("Total", columnLength, " "));
0441: buf.append(alignLeft("Total", columnLength));
0442:
0443: buf.append(alignLeft("Insert", columnLength));
0444: //buf.append(alignToLength(columnLength, " "));
0445: buf.append(alignLeft("Fetch", columnLength));
0446: //buf.append(alignToLength(columnLength, " "));
0447: buf.append(alignLeft("Fetch 2", columnLength));
0448: //buf.append(alignToLength(columnLength, " "));
0449: buf.append(alignLeft("by Id", columnLength));
0450: //buf.append(alignToLength(columnLength, " "));
0451: buf.append(alignLeft("Update", columnLength));
0452: //buf.append(alignToLength(columnLength, " "));
0453: buf.append(alignLeft("Delete", columnLength));
0454: //buf.append(alignToLength(columnLength, " "));
0455:
0456: buf.append(EOL);
0457: buf.append(alignToLength(columnLength, " "));
0458: //buf.append(alignLeft("[sec]", columnLength, " "));
0459: //buf.append(alignLeft("[sec]", columnLength, " "));
0460: buf.append(alignLeft("[%]", columnLength));
0461:
0462: buf.append(alignLeft("[msec]", columnLength));
0463: //buf.append(alignToLength(columnLength, " "));
0464: buf.append(alignLeft("[msec]", columnLength));
0465: //buf.append(alignToLength(columnLength, " "));
0466: buf.append(alignLeft("[msec]", columnLength));
0467: //buf.append(alignToLength(columnLength, " "));
0468: buf.append(alignLeft("[msec]", columnLength));
0469: //buf.append(alignToLength(columnLength, " "));
0470: buf.append(alignLeft("[msec]", columnLength));
0471: //buf.append(alignToLength(columnLength, " "));
0472: buf.append(alignLeft("[msec]", columnLength));
0473: //buf.append(alignToLength(columnLength, " "));
0474: buf.append(EOL);
0475: for (int i = 0; i < columnNumbers; i++) {
0476: buf.append(alignToLength(columnLength, "-"));
0477: }
0478:
0479: // fill table
0480: int counter = 0;
0481: double calibrationMark = 0;
0482: for (int i = 0; i < results.length; i++) {
0483: PerfResult result = results[i];
0484: buf.append(EOL);
0485: if (counter == 0) {
0486: // the first one is the fastest
0487: calibrationMark = result.getTotalTime();
0488: }
0489: //double period = (double) result.getTestPeriod() / 1000;
0490: //double total = (double) Math.round((double) result.getTotalTime()) / 1000;
0491: long percent = Math
0492: .round((result.getTotalTime() / calibrationMark) * 100);
0493:
0494: buf.append(alignLeft(result.getTestName(), columnLength));
0495: //buf.append(alignLeft(""+period, columnLength, " "));
0496: //buf.append(alignLeft(""+total, columnLength, " "));
0497: buf.append(alignLeft("" + percent, columnLength));
0498:
0499: buf.append(alignLeft(result.getInsertResult()
0500: + result.getInsertResultPercent(), columnLength));
0501: //buf.append(alignLeft(result.getInsertResultPercent(), columnLength, " "));
0502: buf.append(alignLeft(result.getFetchResult()
0503: + result.getFetchResultPercent(), columnLength));
0504: //buf.append(alignLeft(result.getFetchResultPercent(), columnLength, " "));
0505: buf.append(alignLeft(result.getFetchSecondResult()
0506: + result.getFetchSecondResultPercent(),
0507: columnLength));
0508: //buf.append(alignLeft(result.getFetchSecondResultPercent(), columnLength, " "));
0509: buf
0510: .append(alignLeft(result.getByIdentityResult()
0511: + result.getByIdentityResultPercent(),
0512: columnLength));
0513: //buf.append(alignLeft(result.getByIdentityResultPercent(), columnLength, " "));
0514: buf.append(alignLeft(result.getUpdateResult()
0515: + result.getUpdateResultPercent(), columnLength));
0516: //buf.append(alignLeft(result.getUpdateResultPercent(), columnLength, " "));
0517: buf.append(alignLeft(result.getDeleteResult()
0518: + result.getDeleteResultPercent(), columnLength));
0519: //buf.append(alignLeft(result.getDeleteResultPercent(), columnLength, " "));
0520: counter++;
0521: }
0522: buf.append(EOL);
0523: for (int i = 0; i < columnNumbers; i++) {
0524: buf.append(alignToLength(columnLength, "="));
0525: }
0526: // if(failures.size() > 0)
0527: // {
0528: // buf.append(EOL + "Failures detected:" + EOL);
0529: // for(int i = 0; i < failures.size(); i++)
0530: // {
0531: // PerfResult perfResult = (PerfResult) failures.get(i);
0532: // buf.append("name=" + perfResult.getTestName() + ", isValid=" +perfResult.isValid() + EOL);
0533: // }
0534: // }
0535: return buf.toString();
0536: }
0537:
0538: // private String alignRight(String target, int length)
0539: // {
0540: // return alignToLength(target, length, " ", true);
0541: // }
0542:
0543: private String alignLeft(String target, int length) {
0544: return alignToLength(target, length, " ", false);
0545: }
0546:
0547: private String alignToLength(int length, String fillCharacter) {
0548: return alignToLength("", length, fillCharacter, false);
0549: }
0550:
0551: private String alignToLength(String target, int length,
0552: String fillCharacter, boolean right) {
0553: if (target.length() > length)
0554: return target;
0555:
0556: int count = length - target.length();
0557: String blanks = "";
0558: for (int i = 0; i < count; i++) {
0559: blanks += fillCharacter;
0560: }
0561: return right ? blanks + target : target + blanks;
0562: }
0563:
0564: /**
0565: * testTimes[0] startTime/test length
0566: * testTimes[1] inserting times
0567: * testTimes[2] fetching times
0568: * testTimes[3] fetching repeat times
0569: * testTimes[4] get by Identity times
0570: * testTimes[5] updating times
0571: * testTimes[6] deleting times
0572: */
0573: public synchronized void addPeriodResult(String testName,
0574: long[] resultArr) {
0575: PerfResult result = (PerfResult) resultMap.get(testName);
0576: if (result == null) {
0577: result = new PerfResult();
0578: result.setTestName(testName);
0579: result.setStressMode(isUseStressMode());
0580: result.setIterationsPerThread(getIterationsPerThread());
0581: result.setNumberOfThreads(getConcurrentThreads());
0582: result.setTestLoops(getTestLoops());
0583: resultMap.put(testName, result);
0584:
0585: }
0586: result.addTestPeriod(resultArr[TIME_TOTAL]);
0587: result.addInsertPeriod(resultArr[TIME_INSERT]);
0588: result.addFetchPeriod(resultArr[TIME_FETCH]);
0589: result.addFetchSecondPeriod(resultArr[TIME_FETCH_2]);
0590: result.addByIdentityPeriod(resultArr[TIME_BY_IDENTITY]);
0591: result.addUpdatePeriod(resultArr[TIME_UPDATE]);
0592: result.addDeletePeriod(resultArr[TIME_DELETE]);
0593:
0594: if (logAll) {
0595: StringBuffer buf = new StringBuffer();
0596: buf.append(" Test '").append(result.getTestName()).append(
0597: "' [ms]").append(": testPeriod=").append(
0598: resultArr[0] / getConcurrentThreads()).append(
0599: " insert=").append(
0600: resultArr[1] / getConcurrentThreads()).append(
0601: " read=").append(
0602: resultArr[2] / getConcurrentThreads()).append(
0603: " read2=").append(
0604: resultArr[3] / getConcurrentThreads()).append(
0605: " byIdentity=").append(
0606: resultArr[4] / getConcurrentThreads()).append(
0607: " update=").append(
0608: resultArr[5] / getConcurrentThreads()).append(
0609: " delete=").append(
0610: resultArr[6] / getConcurrentThreads());
0611: printer().print(buf.toString());
0612: } else {
0613: printer().print(".");
0614: }
0615: }
0616:
0617: public synchronized void addConsistentResult(String testName,
0618: int objectsBefore, int objectsAfter) {
0619: ConsistentEntry ce = new ConsistentEntry(objectsBefore,
0620: objectsAfter);
0621: PerfResult result = (PerfResult) resultMap.get(testName);
0622: if (objectsBefore != objectsAfter) {
0623: try {
0624: throw new Exception("Wrong object count, before="
0625: + objectsBefore + ", after=" + objectsAfter);
0626: } catch (Exception e) {
0627: registerException(testName, e);
0628: }
0629: }
0630: result.addConsistentEntry(ce);
0631: }
0632:
0633: public synchronized void registerException(String causer,
0634: Exception e) {
0635: exceptionMap.put(causer, e);
0636: }
0637:
0638: public Map getExceptionMap() {
0639: return exceptionMap;
0640: }
0641:
0642: public Collection getResultList() {
0643: return resultMap.values();
0644: }
0645:
0646: public static int getIterationsPerThread() {
0647: return iterationsPerThread;
0648: }
0649:
0650: public static int getConcurrentThreads() {
0651: return concurrentThreads;
0652: }
0653:
0654: public static boolean isUseStressMode() {
0655: return useStressMode;
0656: }
0657:
0658: public static int getTestLoops() {
0659: return testLoops;
0660: }
0661:
0662: Object newInstance(Class target, Class argType, Object argInstance) {
0663: try {
0664: Class[] types = new Class[] { argType };
0665: Object[] args = new Object[] { argInstance };
0666: Constructor con = target.getConstructor(types);
0667: return con.newInstance(args);
0668: } catch (Exception e) {
0669: e.printStackTrace();
0670: throw new RuntimeException(
0671: "Can't create instance for class " + target
0672: + "using constructor argument " + argType
0673: + ", message is " + e.getMessage());
0674: }
0675: }
0676:
0677: //================================================================
0678: // inner class
0679: //================================================================
0680: static class PerfResult {
0681: private String testName;
0682: private long testPeriod;
0683: private boolean stressMode;
0684:
0685: private int testLoops;
0686: private int numberOfThreads;
0687: private int iterationsPerThread;
0688:
0689: private long insertPeriod;
0690: private long insertMinimun;
0691: private long fetchPeriod;
0692: private long fetchMinimun;
0693: private long fetchSecondPeriod;
0694: private long fetchSecondMinimun;
0695: private long byIdentityPeriod;
0696: private long byIdentityMinimun;
0697: private long updatePeriod;
0698: private long updateMinimun;
0699: private long deletePeriod;
0700: private long deleteMinimun;
0701:
0702: private boolean valid;
0703:
0704: private List consistentList;
0705:
0706: public PerfResult() {
0707: setValid(true);
0708: this .consistentList = new ArrayList();
0709: }
0710:
0711: public String toString() {
0712: StringBuffer buf = new StringBuffer();
0713: buf.append(EOL).append("[").append(
0714: this .getClass().getName());
0715: buf.append(EOL).append("testName=").append(testName);
0716: buf.append(EOL).append("testPeriod=").append(testPeriod);
0717: buf.append(EOL).append("testLoops=").append(testLoops);
0718: buf.append(EOL).append("numberOfThreads=").append(
0719: numberOfThreads);
0720: buf.append(EOL).append("iterationsPerThread=").append(
0721: iterationsPerThread);
0722: buf.append(EOL).append("isValid=").append(isValid());
0723: buf.append(EOL).append("insertPeriod=").append(
0724: getInsertPeriod());
0725: buf.append(EOL).append("fetchPeriod=").append(
0726: getFetchPeriod());
0727: buf.append(EOL).append("fetchSecondPeriod=").append(
0728: getFetchSecondPeriod());
0729: buf.append(EOL).append("byIdentity=").append(
0730: getByIdentityPeriod());
0731: buf.append(EOL).append("deletePeriod=").append(
0732: getDeletePeriod());
0733: buf.append(EOL).append("consistentList: ").append(
0734: consistentList);
0735: buf.append("]");
0736: return buf.toString();
0737: }
0738:
0739: public void addConsistentEntry(ConsistentEntry entry) {
0740: this .consistentList.add(entry);
0741: valid = valid && entry.isPassed();
0742: }
0743:
0744: public boolean isStressMode() {
0745: return stressMode;
0746: }
0747:
0748: public void setStressMode(boolean stressMode) {
0749: this .stressMode = stressMode;
0750: }
0751:
0752: public boolean isValid() {
0753: return valid;
0754: }
0755:
0756: public void setValid(boolean valid) {
0757: this .valid = valid;
0758: }
0759:
0760: public String getTestName() {
0761: return testName;
0762: }
0763:
0764: public void setTestName(String testName) {
0765: this .testName = testName;
0766: }
0767:
0768: public long getTestPeriod() {
0769: return testPeriod;
0770: }
0771:
0772: public synchronized void addTestPeriod(long aTestPeriod) {
0773: this .testPeriod += aTestPeriod;
0774: }
0775:
0776: public int getTestLoops() {
0777: return testLoops;
0778: }
0779:
0780: public void setTestLoops(int testLoops) {
0781: this .testLoops = testLoops;
0782: }
0783:
0784: public int getNumberOfThreads() {
0785: return numberOfThreads;
0786: }
0787:
0788: public void setNumberOfThreads(int numberOfThreads) {
0789: this .numberOfThreads = numberOfThreads;
0790: }
0791:
0792: public int getIterationsPerThread() {
0793: return iterationsPerThread;
0794: }
0795:
0796: public void setIterationsPerThread(int numberOfObjects) {
0797: this .iterationsPerThread = numberOfObjects;
0798: }
0799:
0800: public long getTotalTime() {
0801: long result = ((insertPeriod + fetchPeriod + updatePeriod + deletePeriod) / getTestLoops())
0802: / getNumberOfThreads();
0803: return result > 0 ? result : 1;
0804: }
0805:
0806: public long getInsertPeriod() {
0807: return (insertPeriod / getTestLoops())
0808: / getNumberOfThreads();
0809: }
0810:
0811: public synchronized void addInsertPeriod(long anInsertPeriod) {
0812: this .insertPeriod += anInsertPeriod;
0813: }
0814:
0815: public long getFetchPeriod() {
0816: return (fetchPeriod / getTestLoops())
0817: / getNumberOfThreads();
0818: }
0819:
0820: public synchronized void addFetchPeriod(long aFetchPeriod) {
0821: this .fetchPeriod += aFetchPeriod;
0822: }
0823:
0824: public long getFetchSecondPeriod() {
0825: return (fetchSecondPeriod / getTestLoops())
0826: / getNumberOfThreads();
0827: }
0828:
0829: public synchronized void addFetchSecondPeriod(long secondPeriod) {
0830: this .fetchSecondPeriod += secondPeriod;
0831: }
0832:
0833: public long getByIdentityPeriod() {
0834: return (byIdentityPeriod / getTestLoops())
0835: / getNumberOfThreads();
0836: }
0837:
0838: public synchronized void addByIdentityPeriod(
0839: long byIdentityPeriod) {
0840: this .byIdentityPeriod += byIdentityPeriod;
0841: }
0842:
0843: public long getUpdatePeriod() {
0844: return (updatePeriod / getTestLoops())
0845: / getNumberOfThreads();
0846: }
0847:
0848: public synchronized void addUpdatePeriod(long aUpdatePeriod) {
0849: this .updatePeriod += aUpdatePeriod;
0850: }
0851:
0852: public long getDeletePeriod() {
0853: return (deletePeriod / getTestLoops())
0854: / getNumberOfThreads();
0855: }
0856:
0857: public synchronized void addDeletePeriod(long aDeletePeriod) {
0858: this .deletePeriod += aDeletePeriod;
0859: }
0860:
0861: public void setInsertMinimun(long insertMinimun) {
0862: this .insertMinimun = insertMinimun > 1 ? insertMinimun : 1;
0863: }
0864:
0865: public void setFetchMinimun(long fetchMinimun) {
0866: this .fetchMinimun = fetchMinimun > 1 ? fetchMinimun : 1;
0867: }
0868:
0869: public void setFetchSecondMinimun(long fetchSecondMinimun) {
0870: this .fetchSecondMinimun = fetchSecondMinimun > 1 ? fetchSecondMinimun
0871: : 1;
0872: }
0873:
0874: public void setByIdentityMinimun(long byIdentityMinimun) {
0875: this .byIdentityMinimun = byIdentityMinimun > 1 ? byIdentityMinimun
0876: : 1;
0877: }
0878:
0879: public void setUpdateMinimun(long updateMinimun) {
0880: this .updateMinimun = updateMinimun > 1 ? updateMinimun : 1;
0881: }
0882:
0883: public void setDeleteMinimun(long deleteMinimun) {
0884: this .deleteMinimun = deleteMinimun > 1 ? deleteMinimun : 1;
0885: }
0886:
0887: public String getInsertResult() {
0888: long result = getInsertPeriod();
0889: return "" + result;
0890: }
0891:
0892: public String getFetchResult() {
0893: long result = getFetchPeriod();
0894: return "" + result;
0895: }
0896:
0897: public String getFetchSecondResult() {
0898: long result = getFetchSecondPeriod();
0899: return "" + result;
0900: }
0901:
0902: public String getByIdentityResult() {
0903: long result = getByIdentityPeriod();
0904: return "" + result;
0905: }
0906:
0907: public String getUpdateResult() {
0908: long result = getUpdatePeriod();
0909: return "" + result;
0910: }
0911:
0912: public String getDeleteResult() {
0913: long result = getDeletePeriod();
0914: return "" + result;
0915: }
0916:
0917: public String getInsertResultPercent() {
0918: long result = getInsertPeriod();
0919: return "(" + (int) ((result * 100) / insertMinimun) + "%)";
0920: }
0921:
0922: public String getFetchResultPercent() {
0923: long result = getFetchPeriod();
0924: return "(" + (int) ((result * 100) / fetchMinimun) + "%)";
0925: }
0926:
0927: public String getFetchSecondResultPercent() {
0928: long result = getFetchSecondPeriod();
0929: return "(" + (int) ((result * 100) / fetchSecondMinimun)
0930: + "%)";
0931: }
0932:
0933: public String getByIdentityResultPercent() {
0934: long result = getByIdentityPeriod();
0935: return "(" + (int) ((result * 100) / byIdentityMinimun)
0936: + "%)";
0937: }
0938:
0939: public String getUpdateResultPercent() {
0940: long result = getUpdatePeriod();
0941: return "(" + (int) ((result * 100) / updateMinimun) + "%)";
0942: }
0943:
0944: public String getDeleteResultPercent() {
0945: long result = getDeletePeriod();
0946: return "(" + (int) ((result * 100) / deleteMinimun) + "%)";
0947: }
0948: }
0949:
0950: //================================================================
0951: // inner class
0952: //================================================================
0953: static class ConsistentEntry {
0954: private int objectsBefore;
0955: private int objectsAfter;
0956:
0957: public ConsistentEntry(int objectsBefore, int objectsAfter) {
0958: this .objectsBefore = objectsBefore;
0959: this .objectsAfter = objectsAfter;
0960: }
0961:
0962: public int getObjectsBefore() {
0963: return objectsBefore;
0964: }
0965:
0966: public int getObjectsAfter() {
0967: return objectsAfter;
0968: }
0969:
0970: public boolean isPassed() {
0971: return objectsBefore == objectsAfter;
0972: }
0973:
0974: public String toString() {
0975: StringBuffer buf = new StringBuffer();
0976: buf.append("[").append(this .getClass().getName()).append(
0977: ": objectsBefore=").append(getObjectsBefore())
0978: .append(" objectsAfter=").append(objectsAfter)
0979: .append(" isPassed=").append(isPassed());
0980: return buf.toString();
0981: }
0982: }
0983:
0984: static class Printer {
0985: PrintStream console;
0986: PrintStream file;
0987:
0988: public Printer() {
0989: console = System.out;
0990: try {
0991: file = new PrintStream(new FileOutputStream(new File(
0992: "OJB-Performance-Result.txt")));
0993: } catch (FileNotFoundException e) {
0994: e.printStackTrace();
0995: }
0996: }
0997:
0998: void print(String str) {
0999: console.print(str);
1000: if (file != null)
1001: file.print(str);
1002: }
1003:
1004: void print(String str, boolean consoleOnly) {
1005: console.print(str);
1006: if (file != null && !consoleOnly)
1007: file.print(str);
1008: }
1009:
1010: void println(String str) {
1011: console.println(str);
1012: if (file != null)
1013: file.println(str);
1014: }
1015:
1016: void println() {
1017: print("");
1018: }
1019: }
1020: }
|