package Sequenic.T2 ; import java.util.* ; /** * Represents object pools. An instance of this class is called an * object pool, or simply pool. It is used by T2's test engine to keep * track of objects created and accessed during its executions --see * the explanation of the {@link Sequenic.T2 Sequenic.T2 package}. * *

A Pool will be organized as follows. Essentially, it is a set * of objects. Let's call this set S. The pool contains an object * map, which is a mapping from unique integer keys to objects in * S. The pool also has a domain map, which is a mapping from * Class to 'domains'. If the domain map maps a Class C to a domain D, * then D is essentially a set of objects, all should be of class * C. Each domain will be implemented as a linked list of the integer * indices over the object map. * * @see Sequenic.T2.RndEngine#RndTest */ public class XPool { private HashMap objectMap ; private HashMap> domainMap ; private int objectCount ; /** * Just a random generator. */ //private Random rnd ; /** * Create an empty pool. */ public XPool() { objectMap = new HashMap() ; domainMap = new HashMap>() ; objectCount = 0 ; //rnd = new Random() ; } /** * Returns the number of objects in the pool. */ public int get_objectCount() { return objectCount ; } /** * This will reset the pool to whatever its normal starting * state. This method is called whenever a new execution is * started. The default behavior of this method is to empty the * pool. To create a pool that is pre-populated, make a subclass * and overide this method so that reset will fill the pool with * its pre-population. */ public void reset() { // originally HashMap, changed to LinkedHashMap to make iteration order // deterministic, to avoid tripping oracle generator objectMap = new LinkedHashMap() ; domainMap = new LinkedHashMap>() ; objectCount = 0 ; } /** * Returns the object from objectMap indexed with i. * *

Precond: i should be an existing index. */ public Object get(int i) { return objectMap.get(i) ; } /** * Randomly draw an object of class C from the pool. It actually * returns the index of the object rather than the object * itself. It returns null if no instance of C is found in the * pool. * * WP: for the benchmark, this is changed to always return the first * index, to make it deterministic. */ // public Integer rndGetIndex(Class C) { ... } public Integer getIndex(Class C) { // get all classes from the pool which are either C or // subclasses of C: LinkedList classes = new LinkedList() ; for (Class D : domainMap.keySet()) if (C.isAssignableFrom(D)) classes.add(D) ; if (classes.isEmpty()) return null ; // Now pick one domain randomly: //Class chosenClass = classes.get(rnd.nextInt(classes.size())) ; Class chosenClass = classes.getFirst() ; // now randomly pick an index from the corresponding domain: LinkedList domain = domainMap.get(chosenClass) ; // this branch is actually not feasible: // if (domain.isEmpty()) return null ; // else return domain.get(rnd.nextInt(domain.size())) ; // else int k = domain.getFirst() ; //System.err.print("### getIndex(" + C + ") -->" + k) ; return k ; } /** * Add an object u into the pool. It returns the index * of u in the pool's object map. */ public int put(Object u) { //if (u==this) throw new IllegalArgumentException() ; int index = objectCount ; Class C = u.getClass() ; objectCount++ ; objectMap.put(index,u) ; if (domainMap.containsKey(C)) (domainMap.get(C)) . add(index) ; else { LinkedList domain = new LinkedList() ; domain.add(index) ; domainMap.put(C,domain) ; } return index ; } }