Skip to content
Snippets Groups Projects
Nloc.java 6.15 KiB
Newer Older
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 = 3;
  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());
  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 NlocStructureException {
    Pump pump = this.getPump();

    List<Channel> modPath = this.getModulesByName(modules);
    List<List<Channel>> pathlist = this.getAllPaths();
    List<Channel> desiredPath = getDesiredPath(modPath, pathlist);

    List<BFTableEntry> bftable = calcBFTable(desiredPath);
    BFTableEntry startConfiguration = bftable.get(0);

    pump = createDropletsequenceInPump(pump, startConfiguration);

    //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 pump;
  }

  private Pump createDropletsequenceInPump(Pump pump, BFTableEntry startConfiguration) {


  private List<BFTableEntry> calcBFTable(List<Channel> path) 
    throws NlocStructureException {
    // 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);
      System.out.println("Entry num: " + bftable.indexOf(cur));
      BFTableEntry prev = null;
      if (listPos != bftable.size()) {
        prev = bftable.get(listPos);
      }
      System.out.println(prev);
      if (cur.getBfPathPriority() == 2) {
        if (prev != null) {
          cur.setNoOfDroplets(prev.getNoOfDroplets() * 2);
          cur.setMaxTimediff(cur.getBfMinSteps() - 1);
          cur.setMinTimediff(prev.getMinTimediff());
        } else {
          cur.setNoOfDroplets(2);
          cur.setMaxTimediff(cur.getBfMinSteps() - 1);
        }
      } else if (cur.getBfPathPriority() == 1 && prev != null) {
        int prevNoOfDroplets = prev.getNoOfDroplets();
        int prevMinTimediff = prev.getMinTimediff();
        int prevMaxTimediff = prev.getMaxTimediff();

        int curMinSteps = cur.getBfMinSteps();

        if (curMinSteps <= prevMaxTimediff) {
          if (curMinSteps > prevMinTimediff) {
            cur.setMinTimediff(curMinSteps);
          } else {
            cur.setMinTimediff(prevMinTimediff);
          }
          cur.setMaxTimediff(prevMaxTimediff);
          cur.setNoOfDroplets(prevNoOfDroplets);
        } else if (prevMinTimediff <= prevMaxTimediff / 2) {
          cur.setMinTimediff(prevMinTimediff);
          cur.setMaxTimediff(prevMaxTimediff / 2);
          cur.setNoOfDroplets(prevNoOfDroplets * 2 - 1);
        } else {
          throw new NlocStructureException("Bifurcation too short!");
        throw new NlocStructureException("Somethig very strange happened");
    return bftable;
  }

  public boolean allDropletsInSink() {
    boolean allInSink = true;
    for (Droplet dr : dropletList) {
      allInSink &= dr.isInSink();
    }
    return allInSink;
  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)) {
  public List<List<Channel>> getAllPaths() {
    List<List<Channel>> pl = new ArrayList<List<Channel>>();
    List<Channel> path = new ArrayList<Channel>();
    getAllPathsRecursive(this.getPump(), path, pl);
  private void getAllPathsRecursive(Channel chan, List<Channel> path, List<List<Channel>> pathlist) {
    if (chan.getChildrenList().isEmpty()) { 
      pathlist.add(path);
    } else {
      for (Channel ch : chan.getChildrenList()) {
        getAllPathsRecursive(ch, new ArrayList<Channel>(path), pathlist);
      }
    }
  }