KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > test > perf > test > Thrasher


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.test.perf.test;
23 import org.jboss.test.perf.interfaces.*;
24
25 import java.util.*;
26
27 public class Thrasher implements Runnable JavaDoc {
28
29   static final int ACTION_SINGLE_READ = 0;
30   static final int ACTION_SINGLE_WRITE = 1;
31   static final int ACTION_BLOCK_READ = 2;
32   static final int ACTION_BLOCK_WRITE = 3;
33   static final int ACTION_FAILURE = 4;
34   static final int ACTION_COUNT = 5;
35   
36   static int[] timers = new int[ACTION_COUNT];
37   static int[] counters = new int[ACTION_COUNT];
38
39   static final String JavaDoc[] ACTION_LABELS = {
40     "single reads ",
41     "single writes",
42     "block reads ",
43     "block writes ",
44     "**FAILURES** ",
45   };
46
47   static final int ARG_THREADS = 0;
48   static final int ARG_ITERATIONS = 1;
49   static final int ARG_READ_PERC = 2;
50   static final int ARG_BLOCK_PERC = 3;
51   static final int ARG_BLOCK_MIN = 4;
52   static final int ARG_BLOCK_MAX = 5;
53   static final int ARG_SLEEP_MIN = 6;
54   static final int ARG_SLEEP_MAX = 7;
55   static final int ARG_ID_MIN = 8;
56   static final int ARG_ID_MAX = 9;
57   static final int ARG_COUNT = 10;
58
59   static final String JavaDoc[] ARG_LABELS = {
60     "threads ", "How many threads to run",
61     "iterations", "How many iterations per thread",
62     "read_perc ", "What percentage of access is readonly",
63     "block_perc", "What percentage of access is block oriented",
64     "block_min ", "The minimum block size per access (inclusive)",
65     "block_max ", "The maximum block size per access (exclusive)",
66     "sleep_min ", "The minimum sleep period between accesses in ms (inclusive)",
67     "sleep_max ", "The maximum sleep period between accesses in ms (exclusive)",
68     "id_min ", "The minimum id accessed (inclusive)",
69     "id_max ", "The maximum id accessed (exclusive)",
70   };
71
72   static final int[] argValues = new int[ARG_COUNT];
73
74   static private void usage() {
75     System.out.println("Usage: java Thrasher <jndi-name> [-options]\n\n" +
76                        " where options include:");
77     for(int a = 0; a < ARG_COUNT; a++) {
78       System.out.println(" -" + ARG_LABELS[a * 2] +
79                          " <n> \t" + ARG_LABELS[a * 2 + 1]);
80     }
81     System.exit(1);
82   }
83
84   public static void main(String JavaDoc[] args) throws Exception JavaDoc {
85
86     if(args.length < 1) {
87       usage();
88     }
89     String JavaDoc jndiName = args[0];
90
91     int[] argValues = new int[ARG_COUNT];
92     argValues[ARG_THREADS] = 1;
93     argValues[ARG_ITERATIONS] = 20;
94     argValues[ARG_READ_PERC] = 90;
95     argValues[ARG_BLOCK_PERC] = 10;
96     argValues[ARG_BLOCK_MIN] = 2;
97     argValues[ARG_BLOCK_MAX] = 10;
98     argValues[ARG_SLEEP_MIN] = 0;
99     argValues[ARG_SLEEP_MAX] = 0;
100     argValues[ARG_ID_MIN] = 0;
101     argValues[ARG_ID_MAX] = 100;
102
103     for(int i = 1; i < args.length; i++) {
104       boolean found = false;
105       for(int a = 0; a < ARG_COUNT; a++) {
106         String JavaDoc argLabel = "-" + ARG_LABELS[a * 2].trim();
107         if(args[i].equals(argLabel)) {
108           found = true;
109           if(++i >= args.length) {
110             System.out.println("Value expected for argument: " + argLabel);
111             System.exit(1);
112           }
113           int value;
114           try {
115             value = Integer.parseInt(args[i]);
116           }
117           catch(NumberFormatException JavaDoc e) {
118             System.out.println("Numeric value expected for argument: " + argLabel);
119             System.out.println(" error: " + e);
120             System.exit(1);
121             return;
122           }
123           argValues[a] = value;
124           break;
125         }
126       }
127       if(!found) {
128         usage();
129       }
130     }
131     Thrasher[] thrashers = new Thrasher[argValues[ARG_THREADS]];
132     {
133       Thread JavaDoc[] threads = new Thread JavaDoc[argValues[ARG_THREADS]];
134       for(int i = 0; i < argValues[ARG_THREADS]; i++) {
135         thrashers[i] = new Thrasher(jndiName, argValues);
136         threads[i] = new Thread JavaDoc(thrashers[i], "Thrasher[" + i + "]");
137         if(i < 5 ||
138            i >= argValues[ARG_THREADS] - 5) {
139           System.out.println("Starting thread: " + threads[i]);
140         }
141         threads[i].start();
142       }
143       for(int i = 0; i < argValues[ARG_THREADS]; i++) {
144         threads[i].join();
145       }
146     }
147     System.out.println("Configuration:");
148     for(int a = 0; a < ARG_COUNT; a++) {
149       System.out.println("\t" + ARG_LABELS[a * 2] + "\t" + argValues[a]);
150     }
151     {
152       System.out.println("Actions:");
153       for(int i = 0; i < ACTION_COUNT; i++) {
154         if(counters[i] != 0) {
155           float avg = (float) timers[i] / counters[i];
156           // round the value...
157
avg = (long) (avg * 10) / 10f;
158           System.out.println("\t" + counters[i] + "\t" +
159                              ACTION_LABELS[i] + "\tavg:\t" +
160                              avg + "\tms/Tx");
161         }
162       }
163     }
164     System.out.println("Performance:");
165     long totalTime = 0;
166     for(int i = 0; i < argValues[ARG_THREADS]; i++) {
167       long thrasherTime = thrashers[i]._elapsedTime;
168       totalTime += thrasherTime;
169       if(i < 5 ||
170          i >= argValues[ARG_THREADS] - 5) {
171         // only print out the first and last 5 enties...
172
float msPerTx = (float) thrasherTime / argValues[ARG_ITERATIONS];
173         float txPerSec = 1000 / msPerTx;
174         // round the values...
175
msPerTx = (long) (msPerTx * 10) / 10f;
176         txPerSec = (long) (txPerSec * 1000) / 1000f;
177         System.out.println("\tThread[" + i + "]: \t" +
178                            txPerSec + "\tTx/s \t" +
179                            msPerTx + "\tms/Tx");
180       }
181     }
182     {
183       float msPerTx = (float) totalTime / argValues[ARG_THREADS] / argValues[ARG_ITERATIONS];
184       float txPerSec = 1000 / msPerTx;
185       // round the values...
186
msPerTx = (long) (msPerTx * 10) / 10f;
187       txPerSec = (long) (txPerSec * 1000) / 1000f;
188       System.out.println("\tAverage: \t" +
189                          txPerSec + "\tTx/s \t" +
190                          msPerTx + "\tms/Tx");
191       float throughput = txPerSec * argValues[ARG_THREADS];
192       // round the value...
193
throughput = (long) (throughput * 1000) / 1000f;
194       System.out.println("\tThroughput: \t" + throughput + "\tTx/s");
195     }
196   }
197
198   private String JavaDoc _jndiName;
199   private int[] _args;
200   private long _elapsedTime;
201
202   private Thrasher(String JavaDoc jndiName, int[] args) {
203     _jndiName = jndiName;
204     _args = args;
205   }
206
207   public void run() {
208     try {
209       javax.naming.Context JavaDoc context = new javax.naming.InitialContext JavaDoc();
210       Object JavaDoc ref = context.lookup("Session");
211       SessionHome sessionHome = (SessionHome) ref;
212       /** CHANGES: Note that WebLogic does not support
213        ** Spec Compliant PortableRemoteObject way of
214        ** narrow
215         //(SessionHome) javax.rmi.PortableRemoteObject.narrow(ref, SessionHome.class);
216        **/

217       Session session = sessionHome.create(_jndiName);
218       java.util.Random JavaDoc random = new java.util.Random JavaDoc();
219       for(int i = 0; i < _args[ARG_ITERATIONS]; i++) {
220         boolean doBlocks = random.nextFloat() < _args[ARG_BLOCK_PERC] / 100f;
221         boolean doReadonly = random.nextFloat() < _args[ARG_READ_PERC] / 100f;
222         int id = getRandom(random, _args[ARG_ID_MIN], _args[ARG_ID_MAX]);
223         int blockSize = doBlocks ? getRandom(random, _args[ARG_BLOCK_MIN], _args[ARG_BLOCK_MAX]) : 0;
224         long before = System.currentTimeMillis();
225         int action;
226         if(doBlocks) {
227           if(id + blockSize > _args[ARG_ID_MAX]) {
228             // if the blocksize were going to overrun the border, shift the start back
229
id = _args[ARG_ID_MAX] - blockSize;
230           }
231           if(doReadonly) {
232             session.read(id, id + blockSize);
233             action = ACTION_BLOCK_READ;
234           }
235           else {
236             session.write(id, id + blockSize);
237             action = ACTION_BLOCK_WRITE;
238           }
239         }
240         else {
241           if(doReadonly) {
242             session.read(id);
243             action = ACTION_SINGLE_READ;
244           }
245           else {
246             session.write(id);
247             action = ACTION_SINGLE_WRITE;
248           }
249         }
250         long after = System.currentTimeMillis();
251         _elapsedTime += after - before;
252         timers[action] += after - before;
253         counters[action]++;
254         int sleep = getRandom(random, _args[ARG_SLEEP_MIN], _args[ARG_SLEEP_MAX]);
255         if(sleep != 0) {
256           try {
257             Thread.currentThread().sleep(sleep);
258           }
259           catch(InterruptedException JavaDoc e) {
260             // continue...
261
}
262         }
263       }
264       session.remove();
265     }
266     catch(Exception JavaDoc e) {
267       counters[ACTION_FAILURE]++;
268       e.printStackTrace();
269     }
270   }
271
272   static int getRandom(java.util.Random JavaDoc random, int min, int max) {
273     // first get a random non-negative number
274
int result = Math.abs(random.nextInt());
275     // get it into the specified range
276
int range = max - min;
277     if(range <= 0) {
278       return min;
279     }
280     result %= range;
281     result += min;
282     return result;
283   }
284
285 }
286
Popular Tags