JAL-2759 cursor option for BoundedStartRegionIterator
[jalview.git] / src / jalview / datamodel / HiddenColumns.java
index 48cfb42..a81d3bd 100644 (file)
@@ -1420,7 +1420,20 @@ public class HiddenColumns
     try
     {
       LOCK.readLock().lock();
-      return new BoundedStartRegionIterator(start, end, hiddenColumns);
+
+      // get absolute position of column in alignment
+      int absoluteStart = adjustForHiddenColumns(start);
+
+      // Get cursor position and supply it to the iterator:
+      // Since we want visible region start, we look for a cursor for the
+      // (absoluteStart-1), then if absoluteStart is the start of a visible
+      // region we'll get the cursor pointing to the region before, which is
+      // what we want
+      HiddenCursorPosition pos = cursor
+              .findRegionForColumn(absoluteStart - 1);
+
+      return new BoundedStartRegionIterator(pos, start, end,
+              hiddenColumns);
     } finally
     {
       LOCK.readLock().unlock();
@@ -1453,9 +1466,9 @@ public class HiddenColumns
    * boundaries
    * 
    * @param start
-   *          (first column inclusive from 0)
+   *          first column, inclusive from 0, absolute value
    * @param end
-   *          (last column - not inclusive)
+   *          last column - not inclusive, absolute value
    */
   public Iterator<int[]> getVisContigsIterator(int start, int end)
   {
@@ -1484,172 +1497,23 @@ public class HiddenColumns
   public Iterator<int[]> getVisibleBlocksIterator(int start, int end,
           boolean useVisibleCoords)
   {
+    int adjstart = start;
+    int adjend = end;
     if (useVisibleCoords)
     {
-      // TODO
-      // we should really just convert start and end here with
-      // adjustForHiddenColumns
-      // and then create a VisibleContigsIterator
-      // but without a cursor this will be horribly slow in some situations
-      // ... so until then...
-      // return new VisibleBlocksVisBoundsIterator(start, end, true);
-      try
-      {
-        LOCK.readLock().lock();
-        int adjstart = adjustForHiddenColumns(start);
-        int adjend = adjustForHiddenColumns(end);
-        return new VisibleContigsIterator(adjstart, adjend + 1,
-                hiddenColumns);
-      } finally
-      {
-        LOCK.readLock().unlock();
-      }
+      adjstart = adjustForHiddenColumns(start);
+      adjend = adjustForHiddenColumns(end);
     }
-    else
-    {
-      try
-      {
-        LOCK.readLock().lock();
-        return new VisibleContigsIterator(start, end + 1, hiddenColumns);
-      } finally
-      {
-        LOCK.readLock().unlock();
-      }
-    }
-  }
-
-  /**
-   * An iterator which iterates over visible regions in a range. The range is
-   * specified in terms of visible column positions. Provides a special
-   * "endsAtHidden" indicator to allow callers to determine if the final visible
-   * column is adjacent to a hidden region.
-   */
-  public class VisibleBlocksVisBoundsIterator implements Iterator<int[]>
-  {
-    private List<int[]> vcontigs = new ArrayList<>();
-
-    private int currentPosition = 0;
-
-    private boolean endsAtHidden = false;
-
-    /**
-     * Constructor for iterator over visible regions in a range.
-     * 
-     * @param start
-     *          start position in terms of visible column position
-     * @param end
-     *          end position in terms of visible column position
-     * @param usecopy
-     *          whether to use a local copy of hidden columns
-     */
-    VisibleBlocksVisBoundsIterator(int start, int end, boolean usecopy)
-    {
-      /* actually this implementation always uses a local copy but this may change in future */
-      try
-      {
-        if (usecopy)
-        {
-          LOCK.readLock().lock();
-        }
-
-        if (hiddenColumns != null && hiddenColumns.size() > 0)
-        {
-          int blockStart = start;
-          int blockEnd = end;
-          int hiddenSoFar = 0;
-          int visSoFar = 0;
-
-          // iterate until a region begins within (start,end]
-          int i = 0;
-          while ((i < hiddenColumns.size())
-                  && (hiddenColumns.get(i)[0] <= blockStart + hiddenSoFar))
-          {
-            hiddenSoFar += hiddenColumns.get(i)[1] - hiddenColumns.get(i)[0]
-                    + 1;
-            i++;
-          }
-
-          blockStart += hiddenSoFar; // convert start to absolute position
-          blockEnd += hiddenSoFar; // convert end to absolute position
-
-          // iterate from start to end, adding each visible region. Positions
-          // are
-          // absolute, and all hidden regions which overlap [start,end] are
-          // used.
-          while (i < hiddenColumns.size()
-                  && (hiddenColumns.get(i)[0] <= blockEnd))
-          {
-            int[] region = hiddenColumns.get(i);
-
-            // end position of this visible region is either just before the
-            // start of the next hidden region, or the absolute position of
-            // 'end', whichever is lowest
-            blockEnd = Math.min(blockEnd, region[0] - 1);
-
-            vcontigs.add(new int[] { blockStart, blockEnd });
 
-            visSoFar += blockEnd - blockStart + 1;
-
-            // next visible region starts after this hidden region
-            blockStart = region[1] + 1;
-
-            hiddenSoFar += region[1] - region[0] + 1;
-
-            // reset blockEnd to absolute position of 'end', assuming we've now
-            // passed all hidden regions before end
-            blockEnd = end + hiddenSoFar;
-
-            i++;
-          }
-          if (visSoFar < end - start + 1)
-          {
-            // the number of visible columns we've accounted for is less than
-            // the number specified by end-start; work out the end position of
-            // the last visible region
-            blockEnd = blockStart + end - start - visSoFar;
-            vcontigs.add(new int[] { blockStart, blockEnd });
-
-            // if the last visible region ends at the next hidden region, set
-            // endsAtHidden=true
-            if (i < hiddenColumns.size()
-                    && hiddenColumns.get(i)[0] - 1 == blockEnd)
-            {
-              endsAtHidden = true;
-            }
-          }
-        }
-        else
-        {
-          // there are no hidden columns, return a single visible contig
-          vcontigs.add(new int[] { start, end });
-          endsAtHidden = false;
-        }
-      } finally
-      {
-        if (usecopy)
-        {
-          LOCK.readLock().unlock();
-        }
-      }
-    }
-
-    @Override
-    public boolean hasNext()
-    {
-      return (currentPosition < vcontigs.size());
-    }
-
-    @Override
-    public int[] next()
+    try
     {
-      int[] result = vcontigs.get(currentPosition);
-      currentPosition++;
-      return result;
-    }
+      LOCK.readLock().lock();
 
-    public boolean endsAtHidden()
+      return new VisibleContigsIterator(adjstart, adjend + 1,
+              hiddenColumns);
+    } finally
     {
-      return endsAtHidden;
+      LOCK.readLock().unlock();
     }
   }
 }