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 Pool { private HashMap objectMap ; private HashMap> domainMap ; private int objectCount ; /** * Just a random generator. */ private Random rnd ; /** * Create an empty pool. */ public Pool() { objectMap = new HashMap() ; domainMap = new HashMap>() ; objectCount = 0 ; rnd = new Random() ; } public boolean classinv() { Set classes = domainMap.keySet() ; boolean ok = true ; MAINLOOP: for (Class C : classes) { List indices = domainMap.get(C) ; for (int i : indices) { ok = C.isAssignableFrom(objectMap.get(i).getClass()); if (!ok) break MAINLOOP ; } } return ok ; } /** * 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() { objectMap = new HashMap() ; domainMap = new HashMap>() ; 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. */ public Integer rndGetIndex(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())) ; // now randomly pick an index from the corresponding domain: LinkedList domain = domainMap.get(chosenClass) ; if (domain.isEmpty()) return null ; else return domain.get(rnd.nextInt(domain.size())) ; } public Integer rndGetIndex_spec(Class C) { assert C != null : "PRE" ; Integer res = rndGetIndex(C) ; assert res == null || (objectMap.containsKey(res) && C.isAssignableFrom(get(res).getClass())) : "POST"; return res ; } /** * Add an object u into the pool. It returns the index * of u in the pool's object map. */ public int put(Object u) { 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 ; } public int put_spec(Object u) { assert u != null : "PRE" ; int i = put(u) ; assert get(i) == u : "POST" ; return i ; } /** * For testing the class. */ /* public static void main(String[] args) { A a1 = new A("Alice") ; A a2 = new A("Bob") ; A2 a3 = new A2("Vilain",100) ; A2 a4 = new A2("Vilain",999) ; Pool p = new Pool() ; p.put(a1) ; p.put(a2) ; p.put(a3) ; p.put(a4) ; Class A = a1.getClass() ; Class A2 = a3.getClass() ; System.out.println("# " + p.get(p.rndGetIndex(A))) ; System.out.println("# " + p.get(p.rndGetIndex(A))) ; System.out.println("# " + p.get(p.rndGetIndex(A))) ; System.out.println("# " + p.get(p.rndGetIndex(A))) ; System.out.println("# " + p.get(p.rndGetIndex(A))) ; System.out.println("> " + p.get(p.rndGetIndex(A2))) ; System.out.println("> " + p.get(p.rndGetIndex(A2))) ; System.out.println("> " + p.get(p.rndGetIndex(A2))) ; System.out.println("> " + p.get(p.rndGetIndex(A2))) ; System.out.println("> " + p.get(p.rndGetIndex(A2))) ; } */ }