001: package U2.T2;
002:
003: import java.util.*;
004:
005: /**
006: * Represents object pools. An instance of this class is called an
007: * object pool, or simply pool. It is used by T2's test engine to keep
008: * track of objects created and accessed during its executions --see
009: * the explanation of the {@link U2.T2 U2.T2 package}.
010: *
011: * <p> A Pool will be organized as follows. Essentially, it is a set
012: * of objects. Let's call this set S. The pool contains an <u>object
013: * map</u>, which is a mapping from unique integer keys to objects in
014: * S. The pool also has a <u>domain map</u>, which is a mapping from
015: * Class to 'domains'. If the domain map maps a Class C to a domain D,
016: * then D is essentially a set of objects, all should be of class
017: * C. Each domain will be implemented as a linked list of the integer
018: * indices over the object map.
019: *
020: */
021:
022: public class Pool {
023:
024: private HashMap<Integer, Object> objectMap;
025: private HashMap<Class, LinkedList<Integer>> domainMap;
026: private int objectCount;
027:
028: /**
029: * Just a random generator.
030: */
031: private Random rnd;
032:
033: /**
034: * Create an empty pool.
035: */
036: public Pool() {
037: objectMap = new HashMap<Integer, Object>();
038: domainMap = new HashMap<Class, LinkedList<Integer>>();
039: objectCount = 0;
040: rnd = new Random();
041: }
042:
043: /**
044: * Returns the number of objects in the pool.
045: */
046: public int get_objectCount() {
047: return objectCount;
048: }
049:
050: /**
051: * This will reset the pool to whatever its normal starting
052: * state. This method is called whenever a new execution is
053: * started. The default behavior of this method is to empty the
054: * pool. To create a pool that is pre-populated, make a subclass
055: * and overide this method so that reset will fill the pool with
056: * its pre-population.
057: */
058: public void reset() {
059: objectMap = new HashMap<Integer, Object>();
060: domainMap = new HashMap<Class, LinkedList<Integer>>();
061: objectCount = 0;
062: }
063:
064: /**
065: * Returns the object from objectMap indexed with i.
066: *
067: * <p>Precond: i should be an existing index.
068: */
069: public Object get(int i) {
070: return objectMap.get(i);
071: }
072:
073: /**
074: * Randomly draw an object of class C from the pool. It actually
075: * returns the index of the object rather than the object
076: * itself. It returns null if no instance of C is found in the
077: * pool.
078: */
079: public Integer rndGetIndex(Class C) {
080: // get all classes from the pool which are either C or
081: // subclasses of C:
082: LinkedList<Class> classes = new LinkedList<Class>();
083: for (Class D : domainMap.keySet())
084: if (C.isAssignableFrom(D))
085: classes.add(D);
086:
087: if (classes.isEmpty())
088: return null;
089:
090: // Now pick one domain randomly:
091: Class chosenClass = classes.get(rnd.nextInt(classes.size()));
092: // now randomly pick an index from the corresponding domain:
093: LinkedList<Integer> domain = domainMap.get(chosenClass);
094: if (domain.isEmpty())
095: return null;
096: else
097: return domain.get(rnd.nextInt(domain.size()));
098: }
099:
100: /**
101: * Add an object u into the pool. It returns the index
102: * of u in the pool's object map.
103: */
104: public int put(Object u) {
105: int index = objectCount;
106: Class C = u.getClass();
107: objectCount++;
108: objectMap.put(index, u);
109: if (domainMap.containsKey(C))
110: (domainMap.get(C)).add(index);
111: else {
112: LinkedList<Integer> domain = new LinkedList<Integer>();
113: domain.add(index);
114: domainMap.put(C, domain);
115: }
116: return index;
117: }
118:
119: /**
120: * For testing the class.
121: */
122: public static void main(String[] args) {
123: A a1 = new A("Alice");
124: A a2 = new A("Bob");
125: A2 a3 = new A2("Vilain", 100);
126: A2 a4 = new A2("Vilain", 999);
127:
128: Pool p = new Pool();
129: p.put(a1);
130: p.put(a2);
131: p.put(a3);
132: p.put(a4);
133:
134: Class A = a1.getClass();
135: Class A2 = a3.getClass();
136:
137: System.out.println("# " + p.get(p.rndGetIndex(A)));
138: System.out.println("# " + p.get(p.rndGetIndex(A)));
139: System.out.println("# " + p.get(p.rndGetIndex(A)));
140: System.out.println("# " + p.get(p.rndGetIndex(A)));
141: System.out.println("# " + p.get(p.rndGetIndex(A)));
142: System.out.println("> " + p.get(p.rndGetIndex(A2)));
143: System.out.println("> " + p.get(p.rndGetIndex(A2)));
144: System.out.println("> " + p.get(p.rndGetIndex(A2)));
145: System.out.println("> " + p.get(p.rndGetIndex(A2)));
146: System.out.println("> " + p.get(p.rndGetIndex(A2)));
147:
148: }
149:
150: }
|