1 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 ; 23 import java.nio.ByteBuffer ; 24 import java.security.SecureRandom ; 25 import java.util.ArrayList ; 26 import java.util.Arrays ; 27 import java.util.Collections ; 28 import java.util.HashMap ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.Random ; 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 secure = new SecureRandom (); 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 .class, BOOLEAN_WRAPPER); 68 classToInt.put(Byte .class, BYTE_WRAPPER); 69 classToInt.put(Character .class, CHAR_WRAPPER); 70 classToInt.put(Double .class, DOUBLE_WRAPPER); 71 classToInt.put(Float .class, FLOAT_WRAPPER); 72 classToInt.put(Integer .class, INT_WRAPPER); 73 classToInt.put(Long .class, LONG_WRAPPER); 74 classToInt.put(Short .class, SHORT_WRAPPER); 75 } 76 77 private final DataRoot root = new DataRoot(); 79 private final CyclicBarrier barrier; 80 81 public PrimitiveArrayTestApp(String 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 testClass = PrimitiveArrayTestApp.class.getName(); 88 TransparencyClassSpec spec = config.getOrCreateSpec(testClass); 89 90 String writeAllowedMethodExpression = "* " + testClass + "*.*(..)"; 91 config.addWriteAutolock(writeAllowedMethodExpression); 92 93 String 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 { 103 Object array = root.getArray(); 104 Class type = array.getClass().getComponentType(); 105 Object compare = root.getCompareData(type); 106 107 barrier.barrier(); 109 110 if (root.getIndex() != root.getNumArrays()) { throw new RuntimeException ("Not all data consumed"); } 112 113 readOnlyTest(array); 115 116 validate(false); 118 119 barrier.barrier(); 121 122 modifyDataWithWriteLock(array, intClassType(type)); 124 125 barrier.barrier(); 127 128 validate(true); 130 131 barrier.barrier(); 133 134 synchronized (array) { 135 System.arraycopy(compare, 0, array, 0, Array.getLength(array)); 137 } 138 139 barrier.barrier(); 141 142 validate(false); 144 } 145 146 private void readOnlyTest(Object array) { 147 Class type = array.getClass().getComponentType(); 148 149 try { 150 tryModifyDataWithReadOnlyLock(array, intClassType(type)); 151 throw new AssertionError ("I should have thrown an ReadOnlyException, type " + type.getName()); 152 } catch (ReadOnlyException roe) { 153 } 155 } 156 157 private void differentDataError(Object a1, Object a2, Class type) { 158 String msg = "Data of type [" + type + "] not equal\n"; 159 msg += ArrayUtils.toString(a1) + "\n\n"; 160 msg += ArrayUtils.toString(a2); 161 throw new RuntimeException (msg); 162 } 163 164 private void validate(boolean withMods) { 165 for (Iterator iter = root.getArrayIterator(); iter.hasNext();) { 166 Object actual = iter.next(); 167 Class type = actual.getClass().getComponentType(); 168 Object 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 array, int type) { 181 synchronized (array) { 182 modifyData(array, type); 183 } 184 } 185 186 190 private static void modifyDataWithWriteLock(Object array, int type) { 191 synchronized (array) { 192 modifyData(array, type); 193 } 194 } 195 196 private static void modifyData(Object 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 []) array); 224 break; 225 case BYTE_WRAPPER: 226 modifyByteWrapper((Byte []) array); 227 break; 228 case CHAR_WRAPPER: 229 modifyCharWrapper((Character []) array); 230 break; 231 case DOUBLE_WRAPPER: 232 modifyDoubleWrapper((Double []) array); 233 break; 234 case FLOAT_WRAPPER: 235 modifyFloatWrapper((Float []) array); 236 break; 237 case INT_WRAPPER: 238 modifyIntegerWrapper((Integer []) array); 239 break; 240 case LONG_WRAPPER: 241 modifyLongWrapper((Long []) array); 242 break; 243 case SHORT_WRAPPER: 244 modifyShortWrapper((Short []) array); 245 break; 246 default: 247 throw new RuntimeException ("bad type " + type); 248 } 249 } 250 251 private static void modifyShortWrapper(Short [] s) { 252 for (int i = 0; i < s.length; i++) { 253 s[i] = new Short ((short) (s[i].shortValue() + 1)); 254 } 255 } 256 257 private static void modifyLongWrapper(Long [] l) { 258 for (int i = 0; i < l.length; i++) { 259 l[i] = new Long (l[i].longValue() + 1); 260 } 261 } 262 263 private static void modifyIntegerWrapper(Integer [] i) { 264 for (int x = 0; x < i.length; x++) { 265 i[x] = new Integer (i[x].intValue() + 1); 266 } 267 } 268 269 private static void modifyFloatWrapper(Float [] f) { 270 for (int i = 0; i < f.length; i++) { 271 f[i] = new Float (f[i].floatValue() + 1); 272 } 273 } 274 275 private static void modifyDoubleWrapper(Double [] d) { 276 for (int i = 0; i < d.length; i++) { 277 d[i] = new Double (d[i].doubleValue() + 1); 278 } 279 } 280 281 private static void modifyCharWrapper(Character [] c) { 282 for (int i = 0; i < c.length; i++) { 283 c[i] = new Character ((char) (c[i].charValue() + 1)); 284 } 285 } 286 287 private static void modifyByteWrapper(Byte [] b) { 288 for (int i = 0; i < b.length; i++) { 289 b[i] = new Byte ((byte) (b[i].byteValue() + 1)); 290 } 291 } 292 293 private static void modifyBooleanWrapper(Boolean [] b) { 294 for (int i = 0; i < b.length; i++) { 295 b[i] = new Boolean (!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 array, Object 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 []) array, (Object []) compare); 369 } 370 371 } 373 374 private static Object createRandomArray(Random random, Class 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 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 ("bad type: " + type); 430 } 431 } 432 433 private static Character [] makeCharacterArray(char[] c) { 434 Character rv[] = new Character [c.length]; 435 for (int i = 0; i < rv.length; i++) { 436 rv[i] = new Character (c[i]); 437 } 438 return rv; 439 } 440 441 private static int intClassType(Class type) { 442 if (classToInt.containsKey(type)) { return classToInt.get(type); } 443 throw new RuntimeException ("No mapping for " + type); 444 } 445 446 private static ByteBuffer makeBuffer(Random 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 arrays = new ArrayList (); 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 [] booleanWrapperData = (Boolean []) makeArray(secure.nextLong(), Boolean .class); 469 Byte [] byteWrapperData = (Byte []) makeArray(secure.nextLong(), Byte .class); 470 Character [] charWrapperData = (Character []) makeArray(secure.nextLong(), Character .class); 471 Double [] doubleWrapperData = (Double []) makeArray(secure.nextLong(), Double .class); 472 Float [] floatWrapperData = (Float []) makeArray(secure.nextLong(), Float .class); 473 Integer [] intWrapperData = (Integer []) makeArray(secure.nextLong(), Integer .class); 474 Long [] longWrapperData = (Long []) makeArray(secure.nextLong(), Long .class); 475 Short [] shortWrapperData = (Short []) makeArray(secure.nextLong(), Short .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 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 getArray() { 509 synchronized (arrays) { 510 return arrays.get(index++); 511 } 512 } 513 514 Object getCompareData(Class type) { 515 long seed = ((Long ) seeds.get(type.getName())).longValue(); 516 return createRandomArray(new Random (seed), type); 517 } 518 519 private Object makeArray(long seed, Class type) { 520 System.err.println("Seed for type " + type + "=" + seed); 521 seeds.put(type.getName(), new Long (seed)); 522 return createRandomArray(new Random (seed), type); 523 } 524 } 525 526 } 527
| Popular Tags
|