KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tctest > PrimitiveArrayTestApp


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tctest;
5
6 import org.apache.commons.lang.ArrayUtils;
7
8 import EDU.oswego.cs.dl.util.concurrent.CyclicBarrier;
9
10 import com.tc.object.config.ConfigVisitor;
11 import com.tc.object.config.DSOClientConfigHelper;
12 import com.tc.object.config.TransparencyClassSpec;
13 import com.tc.object.config.spec.CyclicBarrierSpec;
14 import com.tc.object.tx.ReadOnlyException;
15 import com.tc.simulator.app.ApplicationConfig;
16 import com.tc.simulator.listener.ListenerProvider;
17 import com.tc.util.Assert;
18 import com.tctest.runner.AbstractErrorCatchingTransparentApp;
19
20 import gnu.trove.TObjectIntHashMap;
21
22 import java.lang.reflect.Array JavaDoc;
23 import java.nio.ByteBuffer JavaDoc;
24 import java.security.SecureRandom JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Arrays JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Random JavaDoc;
33
34 public class PrimitiveArrayTestApp extends AbstractErrorCatchingTransparentApp {
35
36   private static final int BOOLEAN = 1;
37   private static final int BYTE = 2;
38   private static final int CHAR = 3;
39   private static final int DOUBLE = 4;
40   private static final int FLOAT = 5;
41   private static final int INT = 6;
42   private static final int LONG = 7;
43   private static final int SHORT = 8;
44
45   private static final int BOOLEAN_WRAPPER = 9;
46   private static final int BYTE_WRAPPER = 10;
47   private static final int CHAR_WRAPPER = 11;
48   private static final int DOUBLE_WRAPPER = 12;
49   private static final int FLOAT_WRAPPER = 13;
50   private static final int INT_WRAPPER = 14;
51   private static final int LONG_WRAPPER = 15;
52   private static final int SHORT_WRAPPER = 16;
53
54   private static final TObjectIntHashMap classToInt = new TObjectIntHashMap();
55   private static final SecureRandom JavaDoc secure = new SecureRandom JavaDoc();
56
57   static {
58     classToInt.put(Boolean.TYPE, BOOLEAN);
59     classToInt.put(Byte.TYPE, BYTE);
60     classToInt.put(Character.TYPE, CHAR);
61     classToInt.put(Double.TYPE, DOUBLE);
62     classToInt.put(Float.TYPE, FLOAT);
63     classToInt.put(Integer.TYPE, INT);
64     classToInt.put(Long.TYPE, LONG);
65     classToInt.put(Short.TYPE, SHORT);
66
67     classToInt.put(Boolean JavaDoc.class, BOOLEAN_WRAPPER);
68     classToInt.put(Byte JavaDoc.class, BYTE_WRAPPER);
69     classToInt.put(Character JavaDoc.class, CHAR_WRAPPER);
70     classToInt.put(Double JavaDoc.class, DOUBLE_WRAPPER);
71     classToInt.put(Float JavaDoc.class, FLOAT_WRAPPER);
72     classToInt.put(Integer JavaDoc.class, INT_WRAPPER);
73     classToInt.put(Long JavaDoc.class, LONG_WRAPPER);
74     classToInt.put(Short JavaDoc.class, SHORT_WRAPPER);
75   }
76
77   // roots
78
private final DataRoot root = new DataRoot();
79   private final CyclicBarrier barrier;
80
81   public PrimitiveArrayTestApp(String JavaDoc appId, ApplicationConfig cfg, ListenerProvider listenerProvider) {
82     super(appId, cfg, listenerProvider);
83     this.barrier = new CyclicBarrier(getParticipantCount());
84   }
85
86   public static void visitL1DSOConfig(ConfigVisitor visitor, DSOClientConfigHelper config) {
87     String JavaDoc testClass = PrimitiveArrayTestApp.class.getName();
88     TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
89
90     String JavaDoc writeAllowedMethodExpression = "* " + testClass + "*.*(..)";
91     config.addWriteAutolock(writeAllowedMethodExpression);
92
93     String JavaDoc readOnlyMethodExpression = "* " + testClass + "*.*ReadOnly*(..)";
94     config.addReadAutolock(readOnlyMethodExpression);
95
96     spec.addRoot("root", "the-data-root-yo");
97     spec.addRoot("barrier", "barrier");
98     config.addIncludePattern(DataRoot.class.getName());
99     new CyclicBarrierSpec().visit(visitor, config);
100   }
101
102   protected void runTest() throws Throwable JavaDoc {
103     Object JavaDoc array = root.getArray();
104     Class JavaDoc type = array.getClass().getComponentType();
105     Object JavaDoc compare = root.getCompareData(type);
106
107     // wait for all nodes to get arrays
108
barrier.barrier();
109
110     // make sure all the data was consumed
111
if (root.getIndex() != root.getNumArrays()) { throw new RuntimeException JavaDoc("Not all data consumed"); }
112
113     // read only tests.
114
readOnlyTest(array);
115
116     // calling this has the side effect of making sure none of the shared arrays have actually changed yet
117
validate(false);
118
119     // wait for all read only tests to finish.
120
barrier.barrier();
121
122     // modify my one type locally
123
modifyDataWithWriteLock(array, intClassType(type));
124
125     // wait for all nodes to do modifications
126
barrier.barrier();
127
128     // validate all the changes made by the other nodes
129
validate(true);
130
131     // wait for all nodes to do validations
132
barrier.barrier();
133
134     synchronized (array) {
135       // test System.arrayCopy()
136
System.arraycopy(compare, 0, array, 0, Array.getLength(array));
137     }
138
139     // wait for all nodes to do finish arraycopy (data should be back to original values)
140
barrier.barrier();
141
142     // validate the arraycopy calls
143
validate(false);
144   }
145
146   private void readOnlyTest(Object JavaDoc array) {
147     Class JavaDoc type = array.getClass().getComponentType();
148
149     try {
150       tryModifyDataWithReadOnlyLock(array, intClassType(type));
151       throw new AssertionError JavaDoc("I should have thrown an ReadOnlyException, type " + type.getName());
152     } catch (ReadOnlyException roe) {
153       // expected
154
}
155   }
156
157   private void differentDataError(Object JavaDoc a1, Object JavaDoc a2, Class JavaDoc type) {
158     String JavaDoc msg = "Data of type [" + type + "] not equal\n";
159     msg += ArrayUtils.toString(a1) + "\n\n";
160     msg += ArrayUtils.toString(a2);
161     throw new RuntimeException JavaDoc(msg);
162   }
163
164   private void validate(boolean withMods) {
165     for (Iterator JavaDoc iter = root.getArrayIterator(); iter.hasNext();) {
166       Object JavaDoc actual = iter.next();
167       Class JavaDoc type = actual.getClass().getComponentType();
168       Object JavaDoc expect = root.getCompareData(type);
169
170       if (withMods) {
171         modifyData(expect, intClassType(type));
172       }
173
174       if (!compareData(actual, expect)) {
175         differentDataError(actual, expect, type);
176       }
177     }
178   }
179
180   private static void tryModifyDataWithReadOnlyLock(Object JavaDoc array, int type) {
181     synchronized (array) {
182       modifyData(array, type);
183     }
184   }
185
186   /*
187    * The synchronized statement inside each individual modify data method such as modifyBoolean() are moved to the
188    * caller method in order to provide both test for modifying data with read only lock and write lock.
189    */

190   private static void modifyDataWithWriteLock(Object JavaDoc array, int type) {
191     synchronized (array) {
192       modifyData(array, type);
193     }
194   }
195
196   private static void modifyData(Object JavaDoc array, int type) {
197     switch (type) {
198       case BOOLEAN:
199         modifyBoolean((boolean[]) array);
200         break;
201       case BYTE:
202         modifyByte((byte[]) array);
203         break;
204       case CHAR:
205         modifyChar((char[]) array);
206         break;
207       case DOUBLE:
208         modifyDouble((double[]) array);
209         break;
210       case FLOAT:
211         modifyFloat((float[]) array);
212         break;
213       case INT:
214         modifyInt((int[]) array);
215         break;
216       case LONG:
217         modifyLong((long[]) array);
218         break;
219       case SHORT:
220         modifyShort((short[]) array);
221         break;
222       case BOOLEAN_WRAPPER:
223         modifyBooleanWrapper((Boolean JavaDoc[]) array);
224         break;
225       case BYTE_WRAPPER:
226         modifyByteWrapper((Byte JavaDoc[]) array);
227         break;
228       case CHAR_WRAPPER:
229         modifyCharWrapper((Character JavaDoc[]) array);
230         break;
231       case DOUBLE_WRAPPER:
232         modifyDoubleWrapper((Double JavaDoc[]) array);
233         break;
234       case FLOAT_WRAPPER:
235         modifyFloatWrapper((Float JavaDoc[]) array);
236         break;
237       case INT_WRAPPER:
238         modifyIntegerWrapper((Integer JavaDoc[]) array);
239         break;
240       case LONG_WRAPPER:
241         modifyLongWrapper((Long JavaDoc[]) array);
242         break;
243       case SHORT_WRAPPER:
244         modifyShortWrapper((Short JavaDoc[]) array);
245         break;
246       default:
247         throw new RuntimeException JavaDoc("bad type " + type);
248     }
249   }
250
251   private static void modifyShortWrapper(Short JavaDoc[] s) {
252     for (int i = 0; i < s.length; i++) {
253       s[i] = new Short JavaDoc((short) (s[i].shortValue() + 1));
254     }
255   }
256
257   private static void modifyLongWrapper(Long JavaDoc[] l) {
258     for (int i = 0; i < l.length; i++) {
259       l[i] = new Long JavaDoc(l[i].longValue() + 1);
260     }
261   }
262
263   private static void modifyIntegerWrapper(Integer JavaDoc[] i) {
264     for (int x = 0; x < i.length; x++) {
265       i[x] = new Integer JavaDoc(i[x].intValue() + 1);
266     }
267   }
268
269   private static void modifyFloatWrapper(Float JavaDoc[] f) {
270     for (int i = 0; i < f.length; i++) {
271       f[i] = new Float JavaDoc(f[i].floatValue() + 1);
272     }
273   }
274
275   private static void modifyDoubleWrapper(Double JavaDoc[] d) {
276     for (int i = 0; i < d.length; i++) {
277       d[i] = new Double JavaDoc(d[i].doubleValue() + 1);
278     }
279   }
280
281   private static void modifyCharWrapper(Character JavaDoc[] c) {
282     for (int i = 0; i < c.length; i++) {
283       c[i] = new Character JavaDoc((char) (c[i].charValue() + 1));
284     }
285   }
286
287   private static void modifyByteWrapper(Byte JavaDoc[] b) {
288     for (int i = 0; i < b.length; i++) {
289       b[i] = new Byte JavaDoc((byte) (b[i].byteValue() + 1));
290     }
291   }
292
293   private static void modifyBooleanWrapper(Boolean JavaDoc[] b) {
294     for (int i = 0; i < b.length; i++) {
295       b[i] = new Boolean JavaDoc(!b[i].booleanValue());
296     }
297   }
298
299   private static void modifyShort(short[] s) {
300     for (int i = 0; i < s.length; i++) {
301       s[i]++;
302     }
303   }
304
305   private static void modifyLong(long[] l) {
306     for (int i = 0; i < l.length; i++) {
307       l[i]++;
308     }
309   }
310
311   private static void modifyInt(int[] i) {
312     for (int x = 0; x < i.length; x++) {
313       i[x]++;
314     }
315   }
316
317   private static void modifyFloat(float[] f) {
318     for (int i = 0; i < f.length; i++) {
319       f[i]++;
320     }
321   }
322
323   private static void modifyDouble(double[] d) {
324     for (int i = 0; i < d.length; i++) {
325       d[i]++;
326     }
327   }
328
329   private static void modifyChar(char[] c) {
330     for (int i = 0; i < c.length; i++) {
331       c[i]++;
332     }
333   }
334
335   private static void modifyByte(byte[] b) {
336     for (int i = 0; i < b.length; i++) {
337       b[i]++;
338     }
339   }
340
341   private static void modifyBoolean(boolean[] b) {
342     for (int i = 0; i < b.length; i++) {
343       b[i] = !b[i];
344     }
345   }
346
347   private static boolean compareData(Object JavaDoc array, Object JavaDoc compare) {
348     int type = intClassType(array.getClass().getComponentType());
349
350     switch (type) {
351       case BOOLEAN:
352         return Arrays.equals((boolean[]) array, (boolean[]) compare);
353       case BYTE:
354         return Arrays.equals((byte[]) array, (byte[]) compare);
355       case CHAR:
356         return Arrays.equals((char[]) array, (char[]) compare);
357       case DOUBLE:
358         return Arrays.equals((double[]) array, (double[]) compare);
359       case FLOAT:
360         return Arrays.equals((float[]) array, (float[]) compare);
361       case INT:
362         return Arrays.equals((int[]) array, (int[]) compare);
363       case LONG:
364         return Arrays.equals((long[]) array, (long[]) compare);
365       case SHORT:
366         return Arrays.equals((short[]) array, (short[]) compare);
367       default:
368         return Arrays.equals((Object JavaDoc[]) array, (Object JavaDoc[]) compare);
369     }
370
371     // unreachable
372
}
373
374   private static Object JavaDoc createRandomArray(Random JavaDoc random, Class JavaDoc type) {
375     int length = 10 + random.nextInt(100);
376     Assert.assertTrue("length = " + length, length > 0);
377
378     switch (intClassType(type)) {
379       case BOOLEAN:
380         boolean[] b = new boolean[length];
381         for (int i = 0; i < b.length; i++) {
382           b[i] = random.nextBoolean();
383         }
384         return b;
385       case BYTE:
386         return makeBuffer(random, length).array();
387       case CHAR:
388         char[] c = new char[length];
389         makeBuffer(random, length * 2).asCharBuffer().get(c);
390         return c;
391       case DOUBLE:
392         double[] d = new double[length];
393         makeBuffer(random, length * 8).asDoubleBuffer().get(d);
394         return d;
395       case FLOAT:
396         float f[] = new float[length];
397         makeBuffer(random, length * 4).asFloatBuffer().get(f);
398         return f;
399       case INT:
400         int[] i = new int[length];
401         makeBuffer(random, length * 4).asIntBuffer().get(i);
402         return i;
403       case LONG:
404         long[] l = new long[length];
405         makeBuffer(random, length * 8).asLongBuffer().get(l);
406         return l;
407       case SHORT:
408         short[] s = new short[length];
409         makeBuffer(random, length * 2).asShortBuffer().get(s);
410         return s;
411       case BOOLEAN_WRAPPER:
412         return ArrayUtils.toObject((boolean[]) createRandomArray(random, Boolean.TYPE));
413       case BYTE_WRAPPER:
414         return ArrayUtils.toObject((byte[]) createRandomArray(random, Byte.TYPE));
415       case CHAR_WRAPPER:
416         // I don't know why there isn't char[] version of ArrayUtils.toObject()
417
return makeCharacterArray((char[]) createRandomArray(random, Character.TYPE));
418       case DOUBLE_WRAPPER:
419         return ArrayUtils.toObject((double[]) createRandomArray(random, Double.TYPE));
420       case FLOAT_WRAPPER:
421         return ArrayUtils.toObject((float[]) createRandomArray(random, Float.TYPE));
422       case INT_WRAPPER:
423         return ArrayUtils.toObject((int[]) createRandomArray(random, Integer.TYPE));
424       case LONG_WRAPPER:
425         return ArrayUtils.toObject((long[]) createRandomArray(random, Long.TYPE));
426       case SHORT_WRAPPER:
427         return ArrayUtils.toObject((short[]) createRandomArray(random, Short.TYPE));
428       default:
429         throw new RuntimeException JavaDoc("bad type: " + type);
430     }
431   }
432
433   private static Character JavaDoc[] makeCharacterArray(char[] c) {
434     Character JavaDoc rv[] = new Character JavaDoc[c.length];
435     for (int i = 0; i < rv.length; i++) {
436       rv[i] = new Character JavaDoc(c[i]);
437     }
438     return rv;
439   }
440
441   private static int intClassType(Class JavaDoc type) {
442     if (classToInt.containsKey(type)) { return classToInt.get(type); }
443     throw new RuntimeException JavaDoc("No mapping for " + type);
444   }
445
446   private static ByteBuffer JavaDoc makeBuffer(Random JavaDoc random, int length) {
447     byte[] data = new byte[length];
448     random.nextBytes(data);
449     return ByteBuffer.wrap(data);
450   }
451
452   private static class DataRoot {
453     private final Map seeds = new HashMap();
454     private final List JavaDoc arrays = new ArrayList JavaDoc();
455     private int index = 0;
456
457     DataRoot() {
458
459       boolean[] booleanData = (boolean[]) makeArray(secure.nextLong(), Boolean.TYPE);
460       byte[] byteData = (byte[]) makeArray(secure.nextLong(), Byte.TYPE);
461       char[] charData = (char[]) makeArray(secure.nextLong(), Character.TYPE);
462       double[] doubleData = (double[]) makeArray(secure.nextLong(), Double.TYPE);
463       float[] floatData = (float[]) makeArray(secure.nextLong(), Float.TYPE);
464       int[] intData = (int[]) makeArray(secure.nextLong(), Integer.TYPE);
465       long[] longData = (long[]) makeArray(secure.nextLong(), Long.TYPE);
466       short[] shortData = (short[]) makeArray(secure.nextLong(), Short.TYPE);
467
468       Boolean JavaDoc[] booleanWrapperData = (Boolean JavaDoc[]) makeArray(secure.nextLong(), Boolean JavaDoc.class);
469       Byte JavaDoc[] byteWrapperData = (Byte JavaDoc[]) makeArray(secure.nextLong(), Byte JavaDoc.class);
470       Character JavaDoc[] charWrapperData = (Character JavaDoc[]) makeArray(secure.nextLong(), Character JavaDoc.class);
471       Double JavaDoc[] doubleWrapperData = (Double JavaDoc[]) makeArray(secure.nextLong(), Double JavaDoc.class);
472       Float JavaDoc[] floatWrapperData = (Float JavaDoc[]) makeArray(secure.nextLong(), Float JavaDoc.class);
473       Integer JavaDoc[] intWrapperData = (Integer JavaDoc[]) makeArray(secure.nextLong(), Integer JavaDoc.class);
474       Long JavaDoc[] longWrapperData = (Long JavaDoc[]) makeArray(secure.nextLong(), Long JavaDoc.class);
475       Short JavaDoc[] shortWrapperData = (Short JavaDoc[]) makeArray(secure.nextLong(), Short JavaDoc.class);
476
477       arrays.add(booleanData);
478       arrays.add(byteData);
479       arrays.add(charData);
480       arrays.add(doubleData);
481       arrays.add(floatData);
482       arrays.add(intData);
483       arrays.add(longData);
484       arrays.add(shortData);
485
486       arrays.add(booleanWrapperData);
487       arrays.add(byteWrapperData);
488       arrays.add(charWrapperData);
489       arrays.add(doubleWrapperData);
490       arrays.add(floatWrapperData);
491       arrays.add(intWrapperData);
492       arrays.add(longWrapperData);
493       arrays.add(shortWrapperData);
494     }
495
496     public Iterator JavaDoc getArrayIterator() {
497       return Collections.unmodifiableList(arrays).iterator();
498     }
499
500     int getIndex() {
501       return this.index;
502     }
503
504     int getNumArrays() {
505       return this.arrays.size();
506     }
507
508     Object JavaDoc getArray() {
509       synchronized (arrays) {
510         return arrays.get(index++);
511       }
512     }
513
514     Object JavaDoc getCompareData(Class JavaDoc type) {
515       long seed = ((Long JavaDoc) seeds.get(type.getName())).longValue();
516       return createRandomArray(new Random JavaDoc(seed), type);
517     }
518
519     private Object JavaDoc makeArray(long seed, Class JavaDoc type) {
520       System.err.println("Seed for type " + type + "=" + seed);
521       seeds.put(type.getName(), new Long JavaDoc(seed));
522       return createRandomArray(new Random JavaDoc(seed), type);
523     }
524   }
525
526 }
527
Popular Tags