JAL-2674 Last moves to iterators
authorkiramt <k.mourao@dundee.ac.uk>
Fri, 6 Oct 2017 13:04:44 +0000 (14:04 +0100)
committerkiramt <k.mourao@dundee.ac.uk>
Fri, 6 Oct 2017 13:04:44 +0000 (14:04 +0100)
src/jalview/datamodel/HiddenColumns.java
test/jalview/datamodel/HiddenColumnsTest.java

index 4b0996f..fb1961e 100644 (file)
@@ -60,7 +60,12 @@ public class HiddenColumns
       {
         if (copy.hiddenColumns != null)
         {
-          hiddenColumns = copy.copyHiddenRegionsToArrayList(0);
+          hiddenColumns = new ArrayList<>();
+          Iterator<int[]> it = copy.iterator();
+          while (it.hasNext())
+          {
+            hiddenColumns.add(it.next());
+          }
         }
       }
     } finally
@@ -305,8 +310,8 @@ public class HiddenColumns
           // earlier hidden columns.
           // Calculate the difference between the actual hidden col position
           // and region[0]-1, and then subtract from result to convert result
-          // from
-          // the adjusted hiddenColumn value to the adjusted region[0]-1 value
+          // from the adjusted hiddenColumn value to the adjusted region[0]-1
+          // value.
 
           // However, if the region begins at 0 we cannot return region[0]-1
           // just return 0
@@ -343,7 +348,6 @@ public class HiddenColumns
   {
     try
     {
-
       LOCK.readLock().lock();
       int distance = visibleDistance;
 
@@ -352,73 +356,28 @@ public class HiddenColumns
 
       Iterator<int[]> it = new ReverseRegionsIterator(0, start);
 
-      int[] region;
-      int gap = 0;
-      int nextstart = start;
-
-      while (it.hasNext() && (distance - gap > 0))
+      while (it.hasNext() && (distance > 0))
       {
-        region = it.next();
+        int[] region = it.next();
 
         if (start > region[1])
         {
-          
-
           // subtract the gap to right of region from distance
-          distance -= start - region[1]; // gap;
-
-          start = nextstart;
-          nextstart = region[0] - 1;// nextstart;
-
-
-          // calculate the next gap
-
-          // gap = start - region[1];
-
-          // set start to just to left of current region
-          // nextstart = region[0] - 1;
+          if (start - region[1] <= distance)
+          {
+            distance -= start - region[1];
+            start = region[0] - 1;
+          }
+          else
+          {
+            start = start - distance;
+            distance = 0;
+          }
         }
       }
 
-      if (!it.hasNext())
-      {
-        // no hidden regions to left of startColumn
-        return start - distance;
-      }
-      else
-      {
+      return start - distance;
 
-        /*        // walk backwards through the alignment subtracting the counts of
-        // visible
-        // columns from distance
-        int[] region;
-        int gap = 0;
-        int nextstart = start;
-        
-        while (it.hasNext() && (distance - gap > 0))
-        {
-          region = it.next();
-          
-          // subtract the gap to right of region from distance
-          distance -= gap;
-          start = nextstart;
-        
-          // calculate the next gap
-          
-          gap = start - region[1];
-        
-          // set start to just to left of current region
-          nextstart = region[0] - 1;
-        }
-        */
-        if (distance - gap > 0)
-        {
-          // fell out of loop because there are no more hidden regions
-          distance -= gap;
-          return nextstart - distance;
-        }
-        return start - distance;
-      }
     } finally
     {
       LOCK.readLock().unlock();
@@ -488,48 +447,12 @@ public class HiddenColumns
   }
 
   /**
-   * This method returns the index of the hidden region to the left of a column
-   * position. If the column is in a hidden region it returns the index of the
-   * region to the left. If there is no hidden region to the left it returns -1.
-   * 
-   * @param pos
-   *          position to find index relative to
-   */
-  private int getHiddenIndexLeft(int pos)
-  {
-    try
-    {
-      LOCK.readLock().lock();
-
-
-      Iterator<int[]> it = new ReverseRegionsIterator(0, pos);
-      if (it.hasNext())
-      {
-        int index = hiddenColumns.size() - 1; // need index of region not last
-                                              // one
-        while (it.hasNext())
-        {
-          int[] region = it.next();
-          if (pos > region[1])
-          {
-            return index;
-          }
-          index--;
-        }
-      }
-      return -1;
-    } finally
-    {
-      LOCK.readLock().unlock();
-    }
-
-  }
-
-  /**
-   * Adds the specified column range to the hidden columns
+   * Adds the specified column range to the hidden columns collection
    * 
    * @param start
+   *          start of range to add (absolute position in alignment)
    * @param end
+   *          end of range to add (absolute position in alignment)
    */
   public void hideColumns(int start, int end)
   {
@@ -569,53 +492,7 @@ public class HiddenColumns
         boolean added = false;
         for (int i = 0; !added && i < hiddenColumns.size(); i++)
         {
-          int[] region = hiddenColumns.get(i);
-
-          if (end < region[0] - 1)
-          {
-            /*
-             * insert discontiguous preceding range
-             */
-            hiddenColumns.add(i, new int[] { start, end });
-            added = true;
-          }
-          else if (end <= region[1])
-          {
-            /*
-             * new range overlaps existing, or is contiguous preceding it - adjust
-             * start column
-             */
-            region[0] = Math.min(region[0], start);
-            added = true;
-          }
-          else if (start <= region[1] + 1)
-          {
-            /*
-             * new range overlaps existing, or is contiguous following it - adjust
-             * start and end columns
-             */
-            region[0] = Math.min(region[0], start);
-            region[1] = Math.max(region[1], end);
-
-            /*
-             * also update or remove any subsequent ranges 
-             * that are overlapped
-             */
-            while (i < hiddenColumns.size() - 1)
-            {
-              int[] nextRegion = hiddenColumns.get(i + 1);
-              if (nextRegion[0] > end + 1)
-              {
-                /*
-                 * gap to next hidden range - no more to update
-                 */
-                break;
-              }
-              region[1] = Math.max(nextRegion[1], end);
-              hiddenColumns.remove(i + 1);
-            }
-            added = true;
-          }
+          added = insertRangeAtRegion(i, start, end);
         } // for
       }
     } finally
@@ -627,6 +504,66 @@ public class HiddenColumns
     }
   }
 
+  private boolean insertRangeAtRegion(int i, int start, int end)
+  {
+    boolean added = false;
+
+    int[] region = hiddenColumns.get(i);
+    if (end < region[0] - 1)
+    {
+      /*
+       * insert discontiguous preceding range
+       */
+      hiddenColumns.add(i, new int[] { start, end });
+      added = true;
+    }
+    else if (end <= region[1])
+    {
+      /*
+       * new range overlaps existing, or is contiguous preceding it - adjust
+       * start column
+       */
+      region[0] = Math.min(region[0], start);
+      added = true;
+    }
+    else if (start <= region[1] + 1)
+    {
+      /*
+       * new range overlaps existing, or is contiguous following it - adjust
+       * start and end columns
+       */
+      region[0] = Math.min(region[0], start);
+      region[1] = Math.max(region[1], end);
+
+      /*
+       * also update or remove any subsequent ranges 
+       * that are overlapped
+       */
+      while (i < hiddenColumns.size() - 1)
+      {
+        int[] nextRegion = hiddenColumns.get(i + 1);
+        if (nextRegion[0] > end + 1)
+        {
+          /*
+           * gap to next hidden range - no more to update
+           */
+          break;
+        }
+        region[1] = Math.max(nextRegion[1], end);
+        hiddenColumns.remove(i + 1);
+      }
+      added = true;
+    }
+    return added;
+  }
+
+  /**
+   * Answers if a column in the alignment is visible
+   * 
+   * @param column
+   *          absolute position of column in the alignment
+   * @return true if column is visible
+   */
   public boolean isVisible(int column)
   {
     try
@@ -650,31 +587,17 @@ public class HiddenColumns
     }
   }
 
-  private ArrayList<int[]> copyHiddenRegionsToArrayList(int startIndex)
-  {
-    int size = 0;
-    if (hiddenColumns != null)
-    {
-      size = hiddenColumns.size();
-    }
-    ArrayList<int[]> copy = new ArrayList<>(size);
-
-    for (int i = startIndex, j = size; i < j; i++)
-    {
-      int[] rh;
-      int[] cp;
-      rh = hiddenColumns.get(i);
-      if (rh != null)
-      {
-        cp = new int[rh.length];
-        System.arraycopy(rh, 0, cp, 0, rh.length);
-        copy.add(cp);
-      }
-    }
-
-    return copy;
-  }
-
+  /**
+   * Get the visible sections of a set of sequences
+   * 
+   * @param start
+   *          sequence position to start from
+   * @param end
+   *          sequence position to end at
+   * @param seqs
+   *          an array of sequences
+   * @return an array of strings encoding the visible parts of each sequence
+   */
   public String[] getVisibleSequenceStrings(int start, int end,
           SequenceI[] seqs)
   {
@@ -1564,22 +1487,6 @@ public class HiddenColumns
       init(lowerBound, upperBound);
     }
 
-    // Unbounded constructor
-    ReverseRegionsIterator()
-    {
-      if (hiddenColumns != null)
-      {
-        // iterator over full hiddenColumns collection
-        int last = hiddenColumns.get(hiddenColumns.size() - 1)[1];
-        init(0, last);
-      }
-      else
-      {
-        // empty iterator
-        init(0, 0);
-      }
-    }
-
     /**
      * Construct an iterator over hiddenColums bounded at
      * [lowerBound,upperBound]
index 95c9fc6..3147aeb 100644 (file)
@@ -119,67 +119,6 @@ public class HiddenColumnsTest
     HiddenColumns cs3 = new HiddenColumns();
     cs3.hideColumns(0, 4);
     assertEquals(0, cs3.findColumnPosition(2));
-
-  }
-
-  /**
-   * Test the method that finds the visible column position a given distance
-   * before another column
-   */
-  @Test(groups = { "Functional" })
-  public void testFindColumnNToLeft()
-  {
-    HiddenColumns cs = new HiddenColumns();
-
-    // test that without hidden columns, findColumnNToLeft returns
-    // position n to left of provided position
-    long pos = cs.subtractVisibleColumns(3, 10);
-    assertEquals(7, pos);
-
-    // 0 returns same position
-    pos = cs.subtractVisibleColumns(0, 10);
-    assertEquals(10, pos);
-
-    // overflow to left returns negative number
-    pos = cs.subtractVisibleColumns(3, 0);
-    assertEquals(-3, pos);
-
-    // test that with hidden columns to left of result column
-    // behaviour is the same as above
-    cs.hideColumns(1, 3);
-
-    // position n to left of provided position
-    pos = cs.subtractVisibleColumns(3, 10);
-    assertEquals(7, pos);
-
-    // 0 returns same position
-    pos = cs.subtractVisibleColumns(0, 10);
-    assertEquals(10, pos);
-
-    // test with one set of hidden columns between start and required position
-    cs.hideColumns(12, 15);
-    pos = cs.subtractVisibleColumns(8, 17);
-    assertEquals(5, pos);
-
-    // test with two sets of hidden columns between start and required position
-    cs.hideColumns(20, 21);
-    pos = cs.subtractVisibleColumns(8, 23);
-    assertEquals(9, pos);
-
-    // repeat last 2 tests with no hidden columns to left of required position
-    ColumnSelection colsel = new ColumnSelection();
-    cs.revealAllHiddenColumns(colsel);
-
-    // test with one set of hidden columns between start and required position
-    cs.hideColumns(12, 15);
-    pos = cs.subtractVisibleColumns(8, 17);
-    assertEquals(5, pos);
-
-    // test with two sets of hidden columns between start and required position
-    cs.hideColumns(20, 21);
-    pos = cs.subtractVisibleColumns(8, 23);
-    assertEquals(9, pos);
-
   }
 
   @Test(groups = { "Functional" })
@@ -1226,8 +1165,61 @@ public class HiddenColumnsTest
     h.hideColumns(0, 30);
     result = h.subtractVisibleColumns(31, 0);
     assertEquals(-31, result);
+
+    HiddenColumns cs = new HiddenColumns();
+
+    // test that without hidden columns, findColumnNToLeft returns
+    // position n to left of provided position
+    long pos = cs.subtractVisibleColumns(3, 10);
+    assertEquals(7, pos);
+
+    // 0 returns same position
+    pos = cs.subtractVisibleColumns(0, 10);
+    assertEquals(10, pos);
+
+    // overflow to left returns negative number
+    pos = cs.subtractVisibleColumns(3, 0);
+    assertEquals(-3, pos);
+
+    // test that with hidden columns to left of result column
+    // behaviour is the same as above
+    cs.hideColumns(1, 3);
+
+    // position n to left of provided position
+    pos = cs.subtractVisibleColumns(3, 10);
+    assertEquals(7, pos);
+
+    // 0 returns same position
+    pos = cs.subtractVisibleColumns(0, 10);
+    assertEquals(10, pos);
+
+    // test with one set of hidden columns between start and required position
+    cs.hideColumns(12, 15);
+    pos = cs.subtractVisibleColumns(8, 17);
+    assertEquals(5, pos);
+
+    // test with two sets of hidden columns between start and required position
+    cs.hideColumns(20, 21);
+    pos = cs.subtractVisibleColumns(8, 23);
+    assertEquals(9, pos);
+
+    // repeat last 2 tests with no hidden columns to left of required position
+    ColumnSelection colsel = new ColumnSelection();
+    cs.revealAllHiddenColumns(colsel);
+
+    // test with one set of hidden columns between start and required position
+    cs.hideColumns(12, 15);
+    pos = cs.subtractVisibleColumns(8, 17);
+    assertEquals(5, pos);
+
+    // test with two sets of hidden columns between start and required position
+    cs.hideColumns(20, 21);
+    pos = cs.subtractVisibleColumns(8, 23);
+    assertEquals(9, pos);
+
   }
 
+
   @Test(groups = "Functional")
   public void testBoundedIterator()
   {