1 4 package com.tctest.performance.sampledata; 5 6 import java.io.Serializable ; 7 import java.util.ArrayList ; 8 import java.util.List ; 9 import java.util.Random ; 10 11 public abstract class OrganicObjectGraph implements Serializable { 12 13 private static final int INT = 0; 14 private static final int STRING = 1; 15 private static final int SHORT = 2; 16 private static final int DOUBLE = 3; 17 private final int sequenceNumber; 18 private final String envKey; 19 private final List references = new ArrayList (); 20 private transient Random random; 21 private int changeIteration; private OrganicObjectGraph parent; 23 24 public OrganicObjectGraph(int sequenceNumber, String envKey) { 25 this.sequenceNumber = sequenceNumber; 26 this.envKey = envKey; 27 } 28 29 public OrganicObjectGraph() { 30 this.sequenceNumber = -1; 31 this.envKey = null; 32 } 33 34 synchronized void addReference(OrganicObjectGraph ref) { 35 references.add(ref); 36 } 37 38 public synchronized void mutateRandom(int changes) { 39 random = new Random (changeIteration++); 40 int changeCount = 0; 41 OrganicObjectGraph current = this; 42 while (changeCount < changes) { 43 if (oneOverTwo()) current = traverse(current); 44 else changeCount += update(current, changes, changeCount); 45 } 46 } 47 48 public synchronized int changeIterationCount() { 49 return changeIteration; 50 } 51 52 public int sequenceNumber() { 53 return sequenceNumber; 54 } 55 56 public String envKey() { 57 return envKey; 58 } 59 60 private int update(OrganicObjectGraph current, int totalChanges, int changeCount) { 61 int changes; 62 int fieldIndex; 63 int fieldType; 64 int size = current.getSize(); 65 do { 66 changes = new Long (Math.round(Math.sqrt(getRandom(totalChanges + 1)))).intValue(); 67 } while (changes == 0); 68 if (changes > totalChanges - changeCount) changes = totalChanges - changeCount; 69 70 for (int i = 0; i < changes; i++) { 71 fieldIndex = getRandom(size); 72 fieldType = current.getType(fieldIndex); 73 switch (fieldType) { 74 case INT: 75 current.setValue(fieldIndex, getRandom(999999999)); 76 break; 77 case STRING: 78 current.setValue(fieldIndex, getRandom(999999999) + "_STR"); 79 break; 80 case SHORT: 81 current.setValue(fieldIndex, Short.parseShort(getRandom(9999) + "")); 82 break; 83 case DOUBLE: 84 current.setValue(fieldIndex, random.nextDouble()); 85 break; 86 default: 87 break; 88 } 89 } 90 return changes; 91 } 92 93 private OrganicObjectGraph traverse(OrganicObjectGraph current) { 94 if (!twoOverThree() && (current.parent != null)) { 95 return current.parent; 96 } else if (references.size() > 0) { 97 int index = getRandom(references.size()); 98 return (OrganicObjectGraph) references.get(index); 99 } else if (current.parent != null) { 100 int index = getRandom(current.parent.references.size()); 101 return (OrganicObjectGraph) current.parent.references.get(index); 102 } else { 103 return this; 104 } 105 } 106 107 private boolean twoOverThree() { 108 return (getRandom(3) > 1) ? true : false; 109 } 110 111 private boolean oneOverTwo() { 112 return (getRandom(2) == 1) ? true : false; 113 } 114 115 protected synchronized void setParent(OrganicObjectGraph parent) { 116 this.parent = parent; 117 } 118 119 protected abstract int getSize(); 120 121 protected abstract int getType(int index); 122 123 protected void setValue(int index, int value) { 124 throw new RuntimeException ("No concrete implementation available."); 125 } 126 127 protected void setValue(int index, String value) { 128 throw new RuntimeException ("No concrete implementation available."); 129 } 130 131 protected void setValue(int index, short value) { 132 throw new RuntimeException ("No concrete implementation available."); 133 } 134 135 protected void setValue(int index, double value) { 136 throw new RuntimeException ("No concrete implementation available."); 137 } 138 139 private int getRandom(int bound) { 140 return new Long (Math.round(Math.floor(bound * random.nextDouble()))).intValue(); 141 } 142 143 public String toString() { 144 return String.valueOf(getSize()) + "\n" + toString(1); 145 } 146 147 public String toString(int level) { 148 String indent = ""; 149 for (int i = 0; i < level; i++) { 150 indent += " "; 151 } 152 String hierarchy = ""; 153 for (int i = 0; i < references.size(); i++) { 154 hierarchy += ((OrganicObjectGraph) references.get(i)).toString(level++); 155 } 156 return indent + String.valueOf(getSize()) + "\n" + hierarchy; 157 } 158 159 public boolean equals(Object rawObj) { 160 OrganicObjectGraph obj = (OrganicObjectGraph) rawObj; 161 OrganicObjectGraph thisChild; 162 OrganicObjectGraph objChild; 163 for (int i = 0; i < obj.references.size(); i++) { 164 thisChild = (OrganicObjectGraph) references.get(i); 165 objChild = (OrganicObjectGraph) obj.references.get(i); 166 if (thisChild == null || objChild == null) return false; 167 if (!thisChild.equals(objChild)) return false; 168 } 169 return true; 170 } 171 } 172 | Popular Tags |