Skip to content
Snippets Groups Projects
Nloc.java 5.92 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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 = 2;
    
      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);
    
        return pump;
      }
    
    
      private Pump createDropletsequenceInPump(Pump pump, 
          BFTableEntry startConfiguration) {
        int noOfDroplets = startConfiguration.getNoOfDroplets();
        int minTimediff = startConfiguration.getMinTimediff();
    
        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 * minTimediff + 1)));
          }
        }
        return pump;
    
      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--) {
          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() - 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 - 1)) {
    
              if (curMinSteps > prevMinTimediff) {
                cur.setMinTimediff(curMinSteps);
              } else {
                cur.setMinTimediff(prevMinTimediff);
              }
              cur.setMaxTimediff(prevMaxTimediff);
              cur.setNoOfDroplets(prevNoOfDroplets);
    
            } else if (prevMinTimediff <= (prevMaxTimediff - 1) / 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);
          }
        }
      }