nodeToFlowSet = new HashMap<N, BitSet>();
nodeToIndex = new HashMap<N, Integer>();
indexToNode = new HashMap<Integer,N>();
//build full set
fullSet = new BitSet(graph.size());
fullSet.flip(0, graph.size());//set all to true
//set up domain for intersection: head nodes are only dominated by themselves,
//other nodes are dominated by everything else
for(Iterator<N> i = graph.iterator(); i.hasNext();){
N o = i.next();
if(heads.contains(o)){
BitSet self = new BitSet();
self.set(indexOf(o));
nodeToFlowSet.put(o, self);
}
else{
nodeToFlowSet.put(o, fullSet);
}
}
boolean changed = true;
do{
changed = false;
for(Iterator<N> i = graph.iterator(); i.hasNext();){
N o = i.next();
if(heads.contains(o)) continue;
//initialize to the "neutral element" for the intersection
//this clone() is fast on BitSets (opposed to on HashSets)
BitSet predsIntersect = (BitSet) fullSet.clone();
//intersect over all predecessors
for(Iterator<N> j = graph.getPredsOf(o).iterator(); j.hasNext();){
BitSet predSet = nodeToFlowSet.get(j.next());
predsIntersect.and(predSet);
}
BitSet oldSet = nodeToFlowSet.get(o);
//each node dominates itself
predsIntersect.set(indexOf(o));
if(!predsIntersect.equals(oldSet)){
nodeToFlowSet.put(o, predsIntersect);
changed = true;