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))) ;
}
*/
}