package nloc; import java.util.List; import java.util.ArrayList; import java.util.ListIterator; import java.util.Arrays; public class Nloc { public static final int MIN_TIMEDIFF = 6; private List<Channel> chanlist; private List<Droplet> dropletList; public Nloc (List<Channel> chanlist) { this.chanlist = chanlist; this.dropletList = new ArrayList<Droplet>(); } public void addChannel(Channel chan) { chanlist.add(chan); } public Pump getPump() { Pump pump = null; for (Channel chan : chanlist) { if (chan instanceof Pump) pump = (Pump)chan; } return pump; } public boolean simulate() { boolean works = true; while (!allDropletsInSink()) { try { this.moveDroplets(); } catch (CoalescedDropletException e) { works = false; System.out.println(e.getDroplet()); break; } } return works; } public List<Droplet> getDropletList() { return dropletList; } public void moveDroplets() throws CoalescedDropletException { for (Droplet dr : dropletList) { dr.move(); } for (Droplet dr: dropletList) { if (dr.coalesce()) throw new CoalescedDropletException(dr); } } //public Pump generateDropletSequence(List<String> modules) // throws BifurcationTooShortException { public List<BFTableEntry> generateDropletSequence(List<String> modules) { Pump pump = this.getPump(); int timediff = MIN_TIMEDIFF + 1; List<Channel> modPath = this.getModulesByName(modules); List<List<Channel>> pathlist = this.getAllPaths(); List<Channel> desiredPath = getDesiredPath(modPath, pathlist); List<BFTableEntry> startConfigruation = calcBFTable(desiredPath); //cumulatedDropletTimeDiffList = calcCumTDiffList(timediffList); //dropletList = generateDropletList(noOfDroplets); //pump = generateSequenceAsPump(dropletList, cumulatedDropletTimeDiffList); //for (int i = 0; i < noOfDroplets; i++){ // if (!pump.containsDroplets()) { // dropletList.add(new Droplet(DropletType.PAYLOAD, // new Position(pump,1))); // } else { // dropletList.add(new Droplet(DropletType.HEADER, // new Position(pump,i + i * timediff + 1))); // } //} return startConfigruation; } private List<BFTableEntry> calcBFTable(List<Channel> path) { // initialize table List<BFTableEntry> bftable = new ArrayList<BFTableEntry>(); ListIterator<Channel> iter = path.listIterator(); while(iter.hasNext()) { Channel current = iter.next(); if (current.isBifurcation()) { Channel following = iter.next(); int prio = current.getChildrenList().indexOf(following) + 1; int bfMinSteps = current.getChildrenList().get(0).getHSteps(); bftable.add(new BFTableEntry(prio, bfMinSteps)); iter.previous(); } } // end while table init /* calculate noOfDroplets and timediff range traversing the table from * "end" to "start" */ for (int listPos = bftable.size(); listPos > 0; listPos--) { System.out.println("listpos: " + listPos + " Size: " + bftable.size()); BFTableEntry cur = bftable.get(listPos - 1); BFTableEntry prev = null; if (listPos != bftable.size()) { prev = bftable.get(listPos); } if (cur.getBfPathPriority() == 2) { if (prev != null) { cur.setNoOfDroplets(prev.getNoOfDroplets() * 2); cur.setMaxTimediff(cur.getBfMinSteps()); cur.setMinTimediff(prev.getMinTimediff()); } else { cur.setNoOfDroplets(2); cur.setMaxTimediff(cur.getBfMinSteps()); } } if (cur.getBfPathPriority() == 1 && prev != null) { //TODO: //checkTableDown() //if violation // mindist = previous.getMaxTimediff(); // maxdist = current.getMinTimediff(); // noOfDroplets = noOfDroplets * 2 -1; //if noviolation // mindist = current.getMinTimediff(); // maxidst = previous.getMaxTimediff(); } else { // throw some exception } } return bftable; //ListIterator<BFTableEntry> bftiter = bftable.listIterator(bftable.size()); //int noOfDroplets = 1; //while(bftiter.hasPrevious()) { // // get number of droplets from the following table entry // // (next in this case because of the reverse processing of the list) // if (bftable.size() != bftable.indexOf(current) + 1) { // BFTableEntry following = bftiter.next(); // noOfDroplets = following.getNoOfDroplets(); // bftiter.previous(); // } // BFTableEntry current = bftiter.previous(); // int prio = current.getBfPathPriority(); // int minSteps = current.getBfMinSteps(); // int minTimediff = current.getMinTimediff(); // int maxTimediff = current.getMaxTimediff(); // if (prio == 2) { // current.setNoOfDroplets(noOfDroplets * 2); // current.setMaxTimediff(minSteps); // } else if (prio == 1) { // //TODO: // //checkTableDown() // //if violation // // mindist = previous.getMaxTimediff(); // // maxdist = current.getMinTimediff(); // // noOfDroplets = noOfDroplets * 2 -1; // //if noviolation // // mindist = current.getMinTimediff(); // // maxidst = previous.getMaxTimediff(); // } else { // // throw some exception // } //} //return bftable.get(0); } public boolean allDropletsInSink() { boolean allInSink = true; for (Droplet dr : dropletList) { allInSink &= dr.isInSink(); } return allInSink; } //public int getNumberOfDroplets(List<Channel> desiredPath) // throws BifurcationTooShortException { // int numOfDroplets = 1; // ListIterator<Channel> iter = desiredPath.listIterator(); // while(iter.hasNext()) { // Channel current = iter.next(); // if (current.isBifurcation()) { // Channel following = iter.next(); // int neededMinLength = numOfDroplets * Nloc.MIN_TIMEDIFF + // numOfDroplets - 1; // int prio = current.getChildrenList().indexOf(following) + 1; // iter.previous(); // for (int i = 1; i < prio; i++) { // int bifurcChildHSteps = current.getChildrenList().get(i).getHSteps(); // if (bifurcChildHSteps < neededMinLength) { // throw new BifurcationTooShortException(current, neededMinLength); // } // } // numOfDroplets *= (current.getChildrenList().indexOf(following) + 1); // } // } // return numOfDroplets; //} public List<Channel> getDesiredPath(List<Channel> modules, List<List<Channel>> pathlist) { List<Channel> found = new ArrayList<Channel>(); for (List<Channel> path : pathlist) { if (path.containsAll(modules)) { found = path; } } return found; } private List<Channel> getModulesByName(List<String> names) { List<Channel> ret = new ArrayList<Channel>(); for (String name : names) { for (Channel ch : chanlist) { if (ch instanceof Module && ch.getName().equals(name)) { ret.add(ch); } } } return ret; } public List<List<Channel>> getAllPaths() { List<List<Channel>> pl = new ArrayList<List<Channel>>(); List<Channel> path = new ArrayList<Channel>(); getAllPathsRecursive(this.getPump(), path, pl); return pl; } private void getAllPathsRecursive(Channel chan, List<Channel> path, List<List<Channel>> pathlist) { path.add(chan); if (chan.getChildrenList().isEmpty()) { pathlist.add(path); } else { for (Channel ch : chan.getChildrenList()) { getAllPathsRecursive(ch, new ArrayList<Channel>(path), pathlist); } } } }