001: /**
002: * Copyright (C) 2001-2004 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.speedo.stress;
018:
019: import org.objectweb.speedo.SpeedoTestHelper;
020: import org.objectweb.speedo.api.SpeedoProperties;
021: import org.objectweb.speedo.api.ExceptionHelper;
022: import org.objectweb.util.monolog.api.BasicLevel;
023: import org.objectweb.jorm.api.PMapper;
024: import org.objectweb.jorm.api.PMapCluster;
025: import org.objectweb.perseus.cache.api.CacheAttributeController;
026:
027: import javax.jdo.PersistenceManager;
028: import javax.jdo.JDOException;
029: import java.util.Vector;
030: import java.util.Properties;
031: import java.util.ArrayList;
032: import java.util.Iterator;
033: import java.util.Arrays;
034: import java.util.HashMap;
035: import java.util.Set;
036:
037: /**
038: *
039: * @author S.Chassande-Barrioz
040: */
041: public abstract class StressHelper extends SpeedoTestHelper {
042:
043: public static Vector rollbackExceptions = new Vector();
044: public static Vector errors = new Vector();
045: public final static String STRESS_LOG_NAME = LOG_NAME + ".stress";
046:
047: protected String INTERACTIVE = getLoggerName() + ".interactive";
048: protected String THREAD = getLoggerName() + ".thread";
049: protected String TX = getLoggerName() + ".tx";
050: //protected String CREATION = getLoggerName() + ".creation";
051: protected String TIMEOUT = getLoggerName() + ".timeout";
052: protected String NBPRINT = getLoggerName() + ".nbprint";
053: protected boolean interactive;
054: protected boolean debug;
055: protected boolean hasRan = false;
056: protected static int nbPrint = 0;
057: protected static CacheAttributeController cac = null;
058: protected static int nbTest = 0;
059:
060: public StressHelper(String s) {
061: super (s);
062: interactive = Boolean.getBoolean(INTERACTIVE);
063: logger.log(BasicLevel.DEBUG, "interactive=" + interactive);
064: if (interactive) {
065: nbPrint = Integer.getInteger(NBPRINT, 0).intValue();
066: logger.log(BasicLevel.DEBUG, "nbPrint=" + nbPrint);
067: }
068: }
069:
070: /**
071: * @return the class name of to initialize
072: */
073: protected abstract String[] getClassNamesToInit();
074:
075: protected String getLogPrefix() {
076: return "";
077: }
078:
079: protected void cleanup() {
080: if (rollbackExceptions == null) {
081: rollbackExceptions = new Vector();
082: } else {
083: rollbackExceptions.clear();
084: }
085: if (errors == null) {
086: errors = new Vector();
087: } else {
088: errors.clear();
089: }
090: }
091:
092: protected void initDataStructure(boolean clean) throws Exception {
093: String[] classNameToInit = getClassNamesToInit();
094: PMapper mapper = getMapper(getPMF());
095: PersistenceManager pm = getPMF().getPersistenceManager();
096: for (int i = 0; i < classNameToInit.length; i++) {
097: pm.getObjectIdClass(Class.forName(classNameToInit[i]));
098: if (clean) {
099: PMapCluster pmc = mapper
100: .getPMapCluster(classNameToInit[i]);
101: assertNotNull("No PMapCluster for the class: "
102: + classNameToInit[i], pmc);
103: pmc.deleteData();
104: }
105: }
106: }
107:
108: public void setUp() throws Exception {
109: logger.log(BasicLevel.DEBUG, "setUp.");
110: cleanup();
111: initDataStructure(true);
112: debug = logger.isLoggable(BasicLevel.DEBUG);
113: logger.log(BasicLevel.DEBUG, "debug=" + debug);
114: }
115:
116: public void tearDown() {
117: logger.log(BasicLevel.DEBUG, "tearDown.");
118: if (hasRan) {
119: if (cac == null) {
120: synchronized (StressHelper.class) {
121: try {
122: cac = getCacheAttributeController(pmf);
123: } catch (Exception e) {
124: logger.log(BasicLevel.ERROR,
125: "Cache manager unreachable: " + pmf, e);
126: fail(e.getMessage());
127: }
128: }
129: }
130: logger.log(BasicLevel.DEBUG, getLogPrefix()
131: + "\tCache eviction... (size="
132: + cac.getCurrentSize() + ")");
133: PersistenceManager pm = pmf.getPersistenceManager();
134: pm.evictAll();
135: pm.close();
136: int cachesize = cac.getCurrentSize();
137: if (cachesize > 0) {
138: logger.log(BasicLevel.WARN, getLogPrefix()
139: + "\tCache eviction finished, size="
140: + cachesize);
141: }
142: }
143: }
144:
145: public Properties getPMFProperties() {
146: Properties p = super .getPMFProperties();
147: p.setProperty(SpeedoProperties.MAPPING_STRUCTURE,
148: SpeedoProperties.MAPPING_STRUCTURE_DD);
149: return p;
150: }
151:
152: /**
153: * Manages a set of tasks
154: */
155: public class TaskManager {
156:
157: /**
158: * The tasks list
159: */
160: public Task[] tasks;
161:
162: /**
163: * The timeout of tread waiting
164: */
165: public int timeout;
166:
167: /**
168: * @param nbThread the number of task for each task
169: * @param nbTx the number of transaction for each task
170: * @param timeout the thread timeoout
171: * @param ctx the context of the test
172: */
173: public TaskManager(int[] nbThread, int[] nbTx, int timeout,
174: Object ctx) {
175: tasks = new Task[nbThread.length];
176: this .timeout = timeout;
177: for (int i = 0; i < nbThread.length; i++) {
178: tasks[i] = newTask(i, nbTx[i], nbThread[i], this , ctx);
179: }
180: }
181:
182: /**
183: * @param taskId the task identifier
184: * @param nbTx the number of transaction to run
185: * @param nbThread the number of thread executing transactions
186: * @param taskManager
187: * @param ctx the context of the test.
188: * @return a new Task instance
189: */
190: public Task newTask(int taskId, int nbTx, int nbThread,
191: TaskManager taskManager, Object ctx) {
192: return new Task(taskId, nbTx, nbThread, taskManager);
193: }
194: }
195:
196: /**
197: * A task of a test. A task uses threads to execute a transaction, one or
198: * several times. All thread are in concurrency to execute transactions.
199: */
200: public class Task {
201: /**
202: * Task identifier
203: */
204: public int taskId;
205:
206: /**
207: * The threads executing transactions of the task
208: */
209: public Thread[] threads;
210:
211: /**
212: * indicates for each tansaction if it must be execute or not (already
213: * done or in progress)
214: */
215: public boolean[] txToExecute;
216:
217: /**
218: * The execution time of transactions
219: */
220: public long[] txExecTime;
221:
222: public TaskManager taskManager;
223:
224: public Task(int taskId, int nbTx, int nbThread,
225: TaskManager taskManager) {
226: this .taskManager = taskManager;
227: this .taskId = taskId;
228: txToExecute = new boolean[nbTx];
229: txExecTime = new long[nbTx];
230: threads = new Thread[nbThread];
231: Arrays.fill(txToExecute, true);
232: Arrays.fill(txExecTime, (long) -1);
233: }
234:
235: /**
236: * Finds (calculate) the next transaction id to execute
237: * @param threadId is the thread identifier requiring a transaction to
238: * execute
239: * @return an transaction identifier (index in the array 'txToExecute'
240: * and 'txExecTime'.
241: */
242: public int getTxId(int threadId) {
243: int txId = 0;
244: if (txToExecute.length == 0) {
245: return 0;
246: }
247: synchronized (txToExecute) {
248: for (txId = 0; txId < txToExecute.length; txId++) {
249: if (txToExecute[txId]) {
250: txToExecute[txId] = false;
251: return txId;
252: }
253: }
254: }
255: return -1;
256: }
257: }
258:
259: /**
260: * Represents a thread running a task
261: */
262: public class ThreadId {
263: public Task task;
264: public int threadId;
265:
266: public ThreadId(Task task, int threadId) {
267: this .task = task;
268: this .threadId = threadId;
269: }
270:
271: public String toString() {
272: return "(task=" + task.taskId + ", thread=" + threadId
273: + ")";
274: }
275: }
276:
277: /**
278: * Creates a task manager with several task
279: */
280: protected TaskManager newTaskManager(int nbTx, int nbThread,
281: int timeout, Object ctx) {
282: return newTaskManager(new int[] { nbTx },
283: new int[] { nbThread }, timeout, ctx);
284: }
285:
286: /**
287: * Creates a task manager with a single task
288: */
289: protected TaskManager newTaskManager(int nbTx[], int nbThread[],
290: int timeout, Object ctx) {
291: return new TaskManager(nbTx, nbThread, timeout, ctx);
292: }
293:
294: protected void perform(final int nbThread, final int nbTx,
295: final int threadTimeout, final Object ctx) {
296: perform(new int[] { nbThread }, new int[] { nbTx },
297: threadTimeout, ctx);
298: }
299:
300: /**
301: * Called before the test execution (like setup() method)
302: * @param tm the task manager running the test
303: * @param ctx the context of the test
304: */
305: protected void prepareTest(TaskManager tm, Object ctx) {
306: }
307:
308: /**
309: * Called before a task execution (like setup() method)
310: * @param task which is going to be executed
311: * @param ctx the context of the test
312: */
313: protected void prepareTask(Task task, Object ctx) {
314: }
315:
316: protected void logStatistic(TaskManager tm, long exectime,
317: Object ctx) {
318: String prefix = getLogPrefix();
319: int nbAllTx = 0;
320: int nbCommittedTx = 0;
321: double averageTxTime = 0;
322: for (int taskId = 0; taskId < tm.tasks.length; taskId++) {
323: final Task task = tm.tasks[taskId];
324: nbAllTx += task.txExecTime.length;
325: for (int txId = 0; txId < task.txExecTime.length; txId++) {
326: if (task.txExecTime[txId] != -1) {
327: nbCommittedTx++;
328: averageTxTime += task.txExecTime[txId];
329: }
330: }
331: }
332: averageTxTime /= nbAllTx;
333: displayMemory();
334: logger.log(BasicLevel.INFO, prefix + "\tTotal execution time= "
335: + exectime + "ms, committedTx= " + nbCommittedTx + " ("
336: + ((double) nbCommittedTx * 100) / nbAllTx + "%)");
337: logger.log(BasicLevel.INFO, prefix
338: + "\tAverage execution time per transaction: "
339: + averageTxTime + " ms)");
340: logger.log(BasicLevel.INFO, prefix
341: + "\tTransaction throughput: "
342: + ((double) nbCommittedTx / (double) exectime) * 1000
343: + " tx/sec");
344: if (errors.size() > 0) {
345: logger.log(BasicLevel.INFO, prefix + "\tThere are "
346: + errors.size() + "/" + nbAllTx
347: + " errors during the run");
348: }
349: }
350:
351: /**
352: *
353: * Launch the threads to execute the transactions
354: *
355: * @param nbThread Number of threads per task
356: * @param nbTx Number of transactions per task
357: * @param timeout Time to wait for a thread to die (in milliseconds)
358: * @param ctx is a context helping the transaction execution
359: */
360: protected void perform(final int nbThread[], final int nbTx[],
361: final int timeout, final Object ctx) {
362: final TaskManager tm = newTaskManager(nbThread, nbTx, timeout,
363: ctx);
364: final String prefix = getLogPrefix();
365: prepareTest(tm, ctx);
366: //------------ Create thread for each tasks ------------//
367: for (int taskId = 0; taskId < nbThread.length; taskId++) {
368: final Task task = tm.tasks[taskId];
369: logger.log(BasicLevel.INFO, prefix + "* TaskId=" + taskId
370: + ", thread=" + nbThread[taskId] + ", tx="
371: + nbTx[taskId] + ", timeout=" + timeout + "ms"
372: + ", context:" + ctx);
373: prepareTask(task, ctx);
374: for (int i = 0; i < nbThread[taskId]; i++) {
375: final int threadId = i;
376: task.threads[i] = new Thread(new Runnable() {
377: public void run() {
378: while (true) {
379: int txId = task.getTxId(threadId);
380: if (txId == -1) {
381: // All the transactions have been executed
382: break;
383: } else if (txId == -2) {
384: continue;
385: }
386: hasRan = true;
387: PerformResult pr = new PerformResult();
388: while (pr.again) {
389: perform(task, threadId, txId, ctx, pr);
390: if (pr.ok) {
391: if (task.txExecTime.length != 0) {
392: task.txExecTime[txId] = pr.execTime;
393: }
394: }
395: }
396: }
397: }
398: });
399: }
400: }
401: //-------------- Launch all threads ------------//
402: long exectime = System.currentTimeMillis();
403: int nbAllThread = 0;
404: for (int taskId = 0; taskId < nbThread.length; taskId++) {
405: Task task = tm.tasks[taskId];
406: nbAllThread += task.threads.length;
407: for (int threadId = 0; threadId < nbThread[taskId]; threadId++) {
408: logger.log(BasicLevel.DEBUG, prefix + "Start thread "
409: + threadId);
410: task.threads[threadId].start();
411: }
412: }
413: try {
414: //------------ wait threads ------------//
415: ArrayList al = new ArrayList(nbAllThread);
416: for (int taskId = 0; taskId < nbThread.length; taskId++) {
417: final Task task = tm.tasks[taskId];
418: for (int threadId = 0; threadId < task.threads.length; threadId++) {
419: task.threads[threadId]
420: .join(task.taskManager.timeout);
421: if (task.threads[threadId].isAlive()) {
422: ThreadId tid = new ThreadId(task, threadId);
423: al.add(tid);
424: logger
425: .log(
426: BasicLevel.DEBUG,
427: prefix
428: + "Thread "
429: + tid
430: + " is not finished after the delay, it could be blocked");
431: }
432: }
433: }
434: if (al.size() > 0) {
435: for (Iterator it = al.iterator(); it.hasNext();) {
436: ThreadId tid = (ThreadId) it.next();
437: if (!tid.task.threads[tid.threadId].isAlive()) {
438: logger.log(BasicLevel.DEBUG, prefix + "Thread "
439: + tid + " is late but ok.");
440: it.remove();
441: }
442: }
443: if (al.size() > 0) {
444: fail("Thread " + al + " is blocked!");
445: }
446: }
447: } catch (InterruptedException e) {
448: fail(e.getMessage());
449: } finally {
450: exectime = System.currentTimeMillis() - exectime;
451: logStatistic(tm, exectime, ctx);
452: }
453: }
454:
455: /**
456: * Allocate a PersistenceManager
457: */
458: protected PersistenceManager getPM(Task task, int threadId, int txId) {
459: PersistenceManager pm = pmf.getPersistenceManager();
460: if (debug) {
461: logger.log(BasicLevel.DEBUG, getLogPrefix() + "(Thread "
462: + threadId + ", tx " + txId + ", task "
463: + task.taskId + ") got a PersistenceManager");
464: }
465: return pm;
466: }
467:
468: /**
469: *Starts a JDO transaction
470: */
471: protected void beginTx(PersistenceManager pm, Task task,
472: int threadId, int txId) {
473: pm.currentTransaction().begin();
474: if (debug) {
475: logger.log(BasicLevel.DEBUG, getLogPrefix() + "(Thread "
476: + threadId + ", tx " + txId + ", task "
477: + task.taskId + ") began a transaction.");
478: }
479: }
480:
481: /**
482: * Commits a JDO transaction
483: */
484: protected void commitTx(PersistenceManager pm, Task task,
485: int threadId, int txId) {
486: pm.currentTransaction().commit();
487: if (debug) {
488: logger.log(BasicLevel.DEBUG, getLogPrefix() + "(Thread "
489: + threadId + ", tx " + txId + ", task "
490: + task.taskId + ") committed a transaction.");
491: }
492: }
493:
494: /**
495: * Rollbacks a JDO transaction due to an exception
496: */
497: protected void rollbackOnException(PersistenceManager pm,
498: Exception e, PerformResult res, Task task, int threadId,
499: int txId) {
500: Exception ie = ExceptionHelper.getNested(e);
501: rollbackExceptions.add(ie);
502: res.ok = false;
503: pm.currentTransaction().rollback();
504: logger.log(BasicLevel.INFO, getLogPrefix() + "(Thread "
505: + threadId + ", tx " + txId + ", task " + task.taskId
506: + " has been rolledback: try again", ie);
507: }
508:
509: /**
510: * Stop the transactions execution due to an error.
511: */
512: protected void stopOnError(PersistenceManager pm, Throwable t,
513: PerformResult res, Task task, int threadId, int txId) {
514: if (t instanceof Exception) {
515: t = ExceptionHelper.getNested((Exception) t);
516: }
517: errors.add(t);
518: res.ok = false;
519: res.again = false; // do no try to re execute the transaction
520: logger.log(BasicLevel.ERROR, getLogPrefix() + "(Thread "
521: + threadId + ", tx " + txId + ", task " + task.taskId
522: + " has a problem", t);
523: }
524:
525: /**
526: * Closes a persistence manager
527: */
528: protected void closePM(PersistenceManager pm, int threadId,
529: int txId, Task task, PerformResult res) {
530: try {
531: if (pm != null && !pm.isClosed()) {
532: try {
533: if (pm.currentTransaction().isActive()) {
534: pm.currentTransaction().rollback();
535: }
536: } finally {
537: pm.close();
538: }
539: }
540: } catch (JDOException e) {
541: logger.log(BasicLevel.ERROR, getLogPrefix() + "(Thread "
542: + threadId + ", tx " + txId + ", task "
543: + task.taskId + ") has been "
544: + (res.ok ? "committed" : "rolledback")
545: + " and the close occurs an error", e);
546: errors.add(e);
547: throw e;
548: }
549: }
550:
551: /**
552: * executes a transaction
553: * @param task task asking the transaction execution
554: * @param threadId thread identifier running the transaction
555: * @param txId transaction identifier
556: * @param ctx context of the test
557: * @param res result of the transaction execution. This object must be
558: * filled/modified by the method.
559: */
560: protected abstract void perform(Task task, int threadId, int txId,
561: Object ctx, PerformResult res);
562:
563: private static synchronized void incNbTest() {
564: nbTest++;
565: }
566:
567: private static boolean printStatistic() {
568: return ((nbPrint != 0) && (nbTest % nbPrint) == 0);
569: }
570:
571: /**
572: * It is used for transactions executions.
573: */
574: class PerformResult {
575: /**
576: * Indicates if the transaction must be played again
577: */
578: public boolean again;
579:
580: /**
581: * Indicates if the out of the transaction is ok
582: */
583: public boolean ok;
584:
585: /**
586: * is the execution time of the transaction
587: */
588: public long execTime;
589:
590: public PerformResult() {
591: again = true;
592: }
593:
594: /**
595: * Demarcates the real begin the transaction
596: */
597: public void beginTest() {
598: execTime = System.currentTimeMillis();
599: logger.log(BasicLevel.DEBUG, "beginTest nbTest=" + nbTest);
600: }
601:
602: /**
603: * Demarcates the real and right end of the transaction
604: */
605: public void endTest() {
606: execTime = System.currentTimeMillis() - execTime;
607: again = false;
608: ok = true;
609: StressHelper.incNbTest();
610: logger.log(BasicLevel.DEBUG, "endTest nbTest=" + nbTest);
611: if (StressHelper.printStatistic()) {
612: logger.log(BasicLevel.INFO, getLogPrefix() + "\tTest"
613: + nbTest + ": execution time=" + execTime
614: + "ms");
615: if (rollbackExceptions.size() > 0) {
616: logger.log(BasicLevel.INFO, getLogPrefix()
617: + "\tThere are "
618: + rollbackExceptions.size()
619: + " rollbacks during the run");
620: }
621: if (errors.size() > 0) {
622: logger.log(BasicLevel.INFO, getLogPrefix()
623: + "\tThere are " + errors.size()
624: + " errors during the run");
625: }
626: }
627: }
628: }
629:
630: /**
631: * Logs the memory informations
632: */
633: protected void displayMemory() {
634: Runtime r = Runtime.getRuntime();
635: // free memory
636: long free = r.freeMemory();
637: // Allocated and no allocated memory
638: long total = r.totalMemory();
639: // inused memory
640: long inuse = total - free;
641: logger.log(BasicLevel.INFO, getLogPrefix() + "\tMemory Size: "
642: + total + ", availlable memory:" + inuse);
643: }
644:
645: protected final static int ID_Th1 = 0;
646: protected final static int ID_Th1Tx10Cr1 = 1 + ID_Th1;
647: protected final static int ID_Th1Tx100Cr1 = 2 + ID_Th1;
648: protected final static int ID_Th1Tx1000Cr1 = 3 + ID_Th1;
649: protected final static int ID_Th1Tx10000Cr1 = 4 + ID_Th1;
650: protected final static int ID_Th1Tx100000Cr1 = 5 + ID_Th1;
651: protected final static int ID_Th1Tx10Cr10 = 6 + ID_Th1;
652: protected final static int ID_Th1Tx100Cr10 = 7 + ID_Th1;
653: protected final static int ID_Th1Tx1000Cr10 = 8 + ID_Th1;
654: protected final static int ID_Th1Tx10000Cr10 = 9 + ID_Th1;
655: protected final static int ID_Th1Tx100000Cr10 = 10 + ID_Th1;
656: protected final static int ID_Th1Tx10Cr100 = 11 + ID_Th1;
657: protected final static int ID_Th1Tx100Cr100 = 12 + ID_Th1;
658: protected final static int ID_Th1Tx1000Cr100 = 13 + ID_Th1;
659: protected final static int ID_Th1Tx10000Cr100 = 14 + ID_Th1;
660: protected final static int ID_Th1Tx10Cr500 = 15 + ID_Th1;
661: protected final static int ID_Th1Tx100Cr500 = 16 + ID_Th1;
662: protected final static int ID_Th1Tx1000Cr500 = 17 + ID_Th1;
663: protected final static int ID_Th1Tx10Cr1000 = 18 + ID_Th1;
664: protected final static int ID_Th1Tx100Cr1000 = 19 + ID_Th1;
665: protected final static int ID_Th1Tx1000Cr1000 = 20 + ID_Th1;
666: protected final static int ID_Th1Tx10Cr2000 = 21 + ID_Th1;
667: protected final static int ID_Th1Tx100Cr2000 = 22 + ID_Th1;
668: protected final static int ID_Th1Tx1000Cr2000 = 23 + ID_Th1;
669: protected final static int ID_Th1Tx10Cr10000 = 24 + ID_Th1;
670: protected final static int ID_Th1Tx100Cr10000 = 25 + ID_Th1;
671: protected final static int ID_Th2 = 25;
672: protected final static int ID_Th2Tx10Cr1 = 1 + ID_Th2;
673: protected final static int ID_Th2Tx100Cr1 = 2 + ID_Th2;
674: protected final static int ID_Th2Tx1000Cr1 = 3 + ID_Th2;
675: protected final static int ID_Th2Tx10000Cr1 = 4 + ID_Th2;
676: protected final static int ID_Th2Tx100000Cr1 = 5 + ID_Th2;
677: protected final static int ID_Th2Tx10Cr10 = 6 + ID_Th2;
678: protected final static int ID_Th2Tx100Cr10 = 7 + ID_Th2;
679: protected final static int ID_Th2Tx1000Cr10 = 8 + ID_Th2;
680: protected final static int ID_Th2Tx10000Cr10 = 9 + ID_Th2;
681: protected final static int ID_Th2Tx100000Cr10 = 10 + ID_Th2;
682: protected final static int ID_Th2Tx10Cr100 = 11 + ID_Th2;
683: protected final static int ID_Th2Tx100Cr100 = 12 + ID_Th2;
684: protected final static int ID_Th2Tx1000Cr100 = 13 + ID_Th2;
685: protected final static int ID_Th2Tx10000Cr100 = 14 + ID_Th2;
686: protected final static int ID_Th2Tx10Cr500 = 15 + ID_Th2;
687: protected final static int ID_Th2Tx100Cr500 = 16 + ID_Th2;
688: protected final static int ID_Th2Tx1000Cr500 = 17 + ID_Th2;
689: protected final static int ID_Th2Tx10Cr1000 = 18 + ID_Th2;
690: protected final static int ID_Th2Tx100Cr1000 = 19 + ID_Th2;
691: protected final static int ID_Th2Tx1000Cr1000 = 20 + ID_Th2;
692: protected final static int ID_Th2Tx10Cr2000 = 21 + ID_Th2;
693: protected final static int ID_Th2Tx100Cr2000 = 22 + ID_Th2;
694: protected final static int ID_Th2Tx1000Cr2000 = 23 + ID_Th2;
695: protected final static int ID_Th2Tx10Cr10000 = 24 + ID_Th2;
696: protected final static int ID_Th2Tx100Cr10000 = 25 + ID_Th2;
697: protected final static int ID_Th3 = 50;
698: protected final static int ID_Th3Tx10Cr1 = 1 + ID_Th3;
699: protected final static int ID_Th3Tx100Cr1 = 2 + ID_Th3;
700: protected final static int ID_Th3Tx1000Cr1 = 3 + ID_Th3;
701: protected final static int ID_Th3Tx10000Cr1 = 4 + ID_Th3;
702: protected final static int ID_Th3Tx100000Cr1 = 5 + ID_Th3;
703: protected final static int ID_Th3Tx10Cr10 = 6 + ID_Th3;
704: protected final static int ID_Th3Tx100Cr10 = 7 + ID_Th3;
705: protected final static int ID_Th3Tx1000Cr10 = 8 + ID_Th3;
706: protected final static int ID_Th3Tx10000Cr10 = 9 + ID_Th3;
707: protected final static int ID_Th3Tx100000Cr10 = 10 + ID_Th3;
708: protected final static int ID_Th3Tx10Cr100 = 11 + ID_Th3;
709: protected final static int ID_Th3Tx100Cr100 = 12 + ID_Th3;
710: protected final static int ID_Th3Tx1000Cr100 = 13 + ID_Th3;
711: protected final static int ID_Th3Tx10000Cr100 = 14 + ID_Th3;
712: protected final static int ID_Th3Tx10Cr500 = 15 + ID_Th3;
713: protected final static int ID_Th3Tx100Cr500 = 16 + ID_Th3;
714: protected final static int ID_Th3Tx1000Cr500 = 17 + ID_Th3;
715: protected final static int ID_Th3Tx10Cr1000 = 18 + ID_Th3;
716: protected final static int ID_Th3Tx100Cr1000 = 19 + ID_Th3;
717: protected final static int ID_Th3Tx1000Cr1000 = 20 + ID_Th3;
718: protected final static int ID_Th3Tx10Cr2000 = 21 + ID_Th3;
719: protected final static int ID_Th3Tx100Cr2000 = 22 + ID_Th3;
720: protected final static int ID_Th3Tx1000Cr2000 = 23 + ID_Th3;
721: protected final static int ID_Th3Tx10Cr10000 = 24 + ID_Th3;
722: protected final static int ID_Th3Tx100Cr10000 = 25 + ID_Th3;
723: protected final static int ID_Th4 = 75;
724: protected final static int ID_Th4Tx10Cr1 = 1 + ID_Th4;
725: protected final static int ID_Th4Tx100Cr1 = 2 + ID_Th4;
726: protected final static int ID_Th4Tx1000Cr1 = 3 + ID_Th4;
727: protected final static int ID_Th4Tx10000Cr1 = 4 + ID_Th4;
728: protected final static int ID_Th4Tx100000Cr1 = 5 + ID_Th4;
729: protected final static int ID_Th4Tx10Cr10 = 6 + ID_Th4;
730: protected final static int ID_Th4Tx100Cr10 = 7 + ID_Th4;
731: protected final static int ID_Th4Tx1000Cr10 = 8 + ID_Th4;
732: protected final static int ID_Th4Tx10000Cr10 = 9 + ID_Th4;
733: protected final static int ID_Th4Tx100000Cr10 = 10 + ID_Th4;
734: protected final static int ID_Th4Tx10Cr100 = 11 + ID_Th4;
735: protected final static int ID_Th4Tx100Cr100 = 12 + ID_Th4;
736: protected final static int ID_Th4Tx1000Cr100 = 13 + ID_Th4;
737: protected final static int ID_Th4Tx10000Cr100 = 14 + ID_Th4;
738: protected final static int ID_Th4Tx10Cr500 = 15 + ID_Th4;
739: protected final static int ID_Th4Tx100Cr500 = 16 + ID_Th4;
740: protected final static int ID_Th4Tx1000Cr500 = 17 + ID_Th4;
741: protected final static int ID_Th4Tx10Cr1000 = 18 + ID_Th4;
742: protected final static int ID_Th4Tx100Cr1000 = 19 + ID_Th4;
743: protected final static int ID_Th4Tx1000Cr1000 = 20 + ID_Th4;
744: protected final static int ID_Th4Tx10Cr2000 = 21 + ID_Th4;
745: protected final static int ID_Th4Tx100Cr2000 = 22 + ID_Th4;
746: protected final static int ID_Th4Tx1000Cr2000 = 23 + ID_Th4;
747: protected final static int ID_Th4Tx10Cr10000 = 24 + ID_Th4;
748: protected final static int ID_Th4Tx100Cr10000 = 25 + ID_Th4;
749: protected final static int ID_Th10 = 100;
750: protected final static int ID_Th10Tx10Cr1 = 1 + ID_Th10;
751: protected final static int ID_Th10Tx100Cr1 = 2 + ID_Th10;
752: protected final static int ID_Th10Tx1000Cr1 = 3 + ID_Th10;
753: protected final static int ID_Th10Tx10000Cr1 = 4 + ID_Th10;
754: protected final static int ID_Th10Tx100000Cr1 = 5 + ID_Th10;
755: protected final static int ID_Th10Tx10Cr10 = 6 + ID_Th10;
756: protected final static int ID_Th10Tx100Cr10 = 7 + ID_Th10;
757: protected final static int ID_Th10Tx1000Cr10 = 8 + ID_Th10;
758: protected final static int ID_Th10Tx10000Cr10 = 9 + ID_Th10;
759: protected final static int ID_Th10Tx100000Cr10 = 10 + ID_Th10;
760: protected final static int ID_Th10Tx10Cr100 = 11 + ID_Th10;
761: protected final static int ID_Th10Tx100Cr100 = 12 + ID_Th10;
762: protected final static int ID_Th10Tx1000Cr100 = 13 + ID_Th10;
763: protected final static int ID_Th10Tx10000Cr100 = 14 + ID_Th10;
764: protected final static int ID_Th10Tx10Cr500 = 15 + ID_Th10;
765: protected final static int ID_Th10Tx100Cr500 = 16 + ID_Th10;
766: protected final static int ID_Th10Tx1000Cr500 = 17 + ID_Th10;
767: protected final static int ID_Th10Tx10Cr1000 = 18 + ID_Th10;
768: protected final static int ID_Th10Tx100Cr1000 = 19 + ID_Th10;
769: protected final static int ID_Th10Tx1000Cr1000 = 20 + ID_Th10;
770: protected final static int ID_Th10Tx10Cr2000 = 21 + ID_Th10;
771: protected final static int ID_Th10Tx100Cr2000 = 22 + ID_Th10;
772: protected final static int ID_Th10Tx1000Cr2000 = 23 + ID_Th10;
773: protected final static int ID_Th10Tx10Cr10000 = 24 + ID_Th10;
774: protected final static int ID_Th10Tx100Cr10000 = 25 + ID_Th10;
775: protected final static int[] TESTNBC = { 0,
776: // ID_Th1
777: 10, 100, 1000, 10000, 100000, // CR 1
778: 100, 1000, 10000, 100000, 1000000, // CR 10
779: 1000, 10000, 100000, 1000000, // CR 100
780: 5000, 50000, 500000, // CR 500
781: 10000, 100000, 1000000, // CR 1.000
782: 20000, 200000, 2000000, // CR 2.000
783: 100000, 1000000, // CR 10.000
784: // ID_Th2
785: 10, 100, 1000, 10000, 100000, // CR 1
786: 100, 1000, 10000, 100000, 1000000, // CR 10
787: 1000, 10000, 100000, 1000000, // CR 100
788: 5000, 50000, 500000, // CR 500
789: 10000, 100000, 1000000, // CR 1.000
790: 20000, 200000, 2000000, // CR 2.000
791: 100000, 1000000, // CR 10.000
792: // ID_Th3
793: 10, 100, 1000, 10000, 100000, // CR 1
794: 100, 1000, 10000, 100000, 1000000, // CR 10
795: 1000, 10000, 100000, 1000000, // CR 100
796: 5000, 50000, 500000, // CR 500
797: 10000, 100000, 1000000, // CR 1.000
798: 20000, 200000, 2000000, // CR 2.000
799: 100000, 1000000, // CR 10.000
800: // ID_Th4
801: 10, 100, 1000, 10000, 100000, // CR 1
802: 100, 1000, 10000, 100000, 1000000, // CR 10
803: 1000, 10000, 100000, 1000000, // CR 100
804: 5000, 50000, 500000, // CR 500
805: 10000, 100000, 1000000, // CR 1.000
806: 20000, 200000, 2000000, // CR 2.000
807: 100000, 1000000, // CR 10.000
808: // ID_Th10
809: 10, 100, 1000, 10000, 100000, // CR 1
810: 100, 1000, 10000, 100000, 1000000, // CR 10
811: 1000, 10000, 100000, 1000000, // CR 100
812: 5000, 50000, 500000, // CR 500
813: 10000, 100000, 1000000, // CR 1.000
814: 20000, 200000, 2000000, // CR 2.000
815: 100000, 1000000, // CR 10.000
816: -1 };
817:
818: protected int getStartId(int testid) {
819: int res = 0;
820: while (testid > 0) {
821: testid--;
822: res += TESTNBC[testid];
823: }
824: return res;
825: }
826:
827: public class ObjectStatistic {
828:
829: HashMap oid2Touch = new HashMap();
830: long nbTouch = 0;
831:
832: public synchronized void touch(Object oid) {
833: Integer i = (Integer) oid2Touch.get(oid);
834: if (i == null) {
835: i = new Integer(1);
836: } else {
837: i = new Integer(i.intValue() + 1);
838: }
839: nbTouch++;
840: oid2Touch.put(oid, i);
841: }
842:
843: public Set getAccessedOid() {
844: return oid2Touch.keySet();
845: }
846:
847: public long getNbAccess() {
848: return nbTouch;
849: }
850: }
851: }
|