JAL=2674 Removed getHiddenColumnsCopy
[jalview.git] / src / jalview / datamodel / HiddenColumns.java
index 82e25b9..c77fb7b 100644 (file)
@@ -27,6 +27,7 @@ import java.util.BitSet;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.Vector;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -95,7 +96,7 @@ public class HiddenColumns
       if (copy != null)
       {
         hiddenColumns = new ArrayList<>();
-        Iterator<int[]> it = copy.getBoundedIterator(start, end, true);
+        Iterator<int[]> it = copy.getBoundedIterator(start, end);
         while (it.hasNext())
         {
           int[] region = it.next();
@@ -714,26 +715,6 @@ public class HiddenColumns
   }
 
   /**
-   * Returns a copy of the vector of hidden regions, as an ArrayList. Before
-   * using this method please consider if you really need access to the hidden
-   * regions - a new (or existing!) method on HiddenColumns might be more
-   * appropriate.
-   * 
-   * @return hidden regions as an ArrayList of [start,end] pairs
-   */
-  public ArrayList<int[]> getHiddenColumnsCopy()
-  {
-    try
-    {
-      LOCK.readLock().lock();
-      return copyHiddenRegionsToArrayList(0);
-    } finally
-    {
-      LOCK.readLock().unlock();
-    }
-  }
-
-  /**
    * return all visible segments between the given start and end boundaries
    * 
    * @param start
@@ -1513,21 +1494,19 @@ public class HiddenColumns
     }
   }
 
-  public Iterator<int[]> getBoundedIterator(int start, int end,
-          boolean useCopy)
+  public Iterator<int[]> getBoundedIterator(int start, int end)
   {
-    return new BoundedHiddenColsIterator(start, end, useCopy);
+    return new BoundedHiddenColsIterator(start, end, true);
   }
 
-  public Iterator<Integer> getBoundedStartIterator(int start, int end,
-          boolean useCopy)
+  public Iterator<Integer> getBoundedStartIterator(int start, int end)
   {
-    return new BoundedStartRegionIterator(start, end, useCopy);
+    return new BoundedStartRegionIterator(start, end, true);
   }
 
-  public Iterator<int[]> getBoundedVisRegionIterator(int start, int end)
+  public Iterator<Integer> getVisibleColsIterator(int start, int end)
   {
-    return new BoundedVisRegionIterator(start, end, true);
+    return new VisibleColsIterator(start, end, true);
   }
 
   /**
@@ -1536,11 +1515,8 @@ public class HiddenColumns
    * @author kmourao
    *
    */
-
-
   class BoundedHiddenColsIterator implements Iterator<int[]>
   {
-
     private int start; // start position to iterate from
 
     private int end; // end position to iterate to
@@ -1734,40 +1710,27 @@ public class HiddenColumns
     }
   }
 
-  class BoundedVisRegionIterator implements Iterator<int[]>
+  public class VisibleColsIterator implements Iterator<Integer>
   {
-    private int start; // start position to iterate from
+    private int last;
 
-    private int end; // end position to iterate to
+    private int current;
 
-    // current region in visColumns
-    private int[] currentRegion;
+    private int next;
 
-    // current index in visColumns
-    private int currentPosition = 0;
+    private List<int[]> localHidden = new ArrayList<>();
 
-    private List<int[]> vcontigs = null;
+    private int lasthiddenregion;
 
-    /**
-     * Construct an iterator over visibleColumn regions bounded at
-     * [lowerBound,upperBound]
-     * 
-     * @param lowerBound
-     *          lower bound to iterate from
-     * @param upperBound
-     *          upper bound to iterate to
-     * @param useCopyCols
-     *          whether to make a local copy for iteration (set to true if
-     *          calling from outwith the HiddenColumns class)
-     */
-    BoundedVisRegionIterator(int lowerBound, int upperBound,
-            boolean useCopy)
+    public VisibleColsIterator(int firstcol, int lastcol, boolean useCopy)
     {
+      last = lastcol;
+      current = firstcol;
+      next = firstcol;
+      lasthiddenregion = -1;
+
       try
       {
-        start = lowerBound;
-        end = upperBound;
-
         if (useCopy)
         {
           // assume that if useCopy is false the calling code has locked
@@ -1775,61 +1738,51 @@ public class HiddenColumns
           LOCK.readLock().lock();
         }
 
-        int visStart = start;
-
         if (hiddenColumns != null)
         {
-          vcontigs = new ArrayList<>(hiddenColumns.size() + 1);
-
-          // navigate to start, keeping count of hidden columns
           int i = 0;
-          int[] region = null;
-          while ((i < hiddenColumns.size())
-                  && (hiddenColumns.get(i)[0] <= start))
+          for (i = 0; i < hiddenColumns.size(); ++i)
           {
-            i++;
+            if (current >= hiddenColumns.get(i)[0]
+                    && current <= hiddenColumns.get(i)[1])
+            {
+              // current is hidden, move to right
+              current = hiddenColumns.get(i)[1] + 1;
+              next = current;
+            }
+            if (current < hiddenColumns.get(i)[0])
+            {
+              break;
+            }
           }
-          // if there was a hidden region before (i>=1), and it ended after
-          // start
-          // and before end, adjust visStart to be just after that region
-          if (i > 0)
+
+          lasthiddenregion = i - 1;
+
+          for (i = hiddenColumns.size() - 1; i >= 0; --i)
           {
-            region = hiddenColumns.get(i - 1);
-            if ((region[1] > start) && (region[1] < end))
+            if (last >= hiddenColumns.get(i)[0]
+                    && last <= hiddenColumns.get(i)[1])
             {
-              visStart = region[1] + 1;
+              // last is hidden, move to left
+              last = hiddenColumns.get(i)[0] - 1;
             }
-            else if (region[1] >= end)
+            if (last > hiddenColumns.get(i)[1])
             {
-              // previous hidden region covers whole range [start,end]
-              // early exit - vcontigs is empty
-              return;
+              break;
             }
           }
 
-          // iterate from start to end, adding start positions of each
-          // hidden region. Positions are visible columns count, not absolute
+          // make a local copy of the bit we need
+          i = lasthiddenregion + 1;
           while (i < hiddenColumns.size()
-                  && (hiddenColumns.get(i)[0] < end))
+                  && hiddenColumns.get(i)[0] <= last)
           {
-            region = hiddenColumns.get(i);
-            int[] prevVisibleRegion = new int[] { visStart, region[0] - 1 };
-            vcontigs.add(prevVisibleRegion);
-            visStart = region[1] + 1;
+            int[] region = new int[] { hiddenColumns.get(i)[0],
+                hiddenColumns.get(i)[1] };
+            localHidden.add(region);
             i++;
           }
-          // add on a final visible region if needed
-          if (visStart <= end)
-          {
-            int[] lastRegion = new int[] { visStart, end };
-            vcontigs.add(lastRegion);
-          }
-        }
-        else
-        {
-          vcontigs = new ArrayList<>();
-          int[] lastRegion = new int[] { start, end };
-          vcontigs.add(lastRegion);
+          lasthiddenregion = -1;
         }
       } finally
       {
@@ -1843,15 +1796,46 @@ public class HiddenColumns
     @Override
     public boolean hasNext()
     {
-      return (currentPosition < vcontigs.size());
+      return next <= last;
     }
 
     @Override
-    public int[] next()
+    public Integer next()
     {
-      currentRegion = vcontigs.get(currentPosition);
-      currentPosition++;
-      return currentRegion;
+      if (next > last)
+      {
+        throw new NoSuchElementException();
+      }
+      current = next;
+      if ((localHidden != null)
+              && (lasthiddenregion + 1 < localHidden.size()))
+      {
+        // still some more hidden regions
+        if (next + 1 < localHidden.get(lasthiddenregion + 1)[0])
+        {
+          // next+1 is still before the next hidden region
+          next++;
+        }
+        else if ((next + 1 >= localHidden.get(lasthiddenregion + 1)[0])
+                && (next + 1 <= localHidden.get(lasthiddenregion + 1)[1]))
+        {
+          // next + 1 is in the next hidden region
+          next = localHidden.get(lasthiddenregion + 1)[1] + 1;
+          lasthiddenregion++;
+        }
+      }
+      else
+      {
+        // finished with hidden regions, just increment normally
+        next++;
+      }
+      return current;
+    }
+
+    @Override
+    public void remove()
+    {
+      throw new UnsupportedOperationException();
     }
   }
 }