try
{
LOCK.readLock().lock();
- return new VisibleColsIterator(start, end, hiddenColumns);
+ return new RangeElementsIterator(start, end,
+ new RangeIterator(hiddenColumns));
} finally
{
LOCK.readLock().unlock();
--- /dev/null
+package jalview.datamodel;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Iterator over each element in a set of ranges i.e. if ranges is {[3,6],
+ * [12,15]} it will iterate over {3,4,5,6,12,13,14,15}. Uses a local copy of the
+ * set of ranges.
+ *
+ * @author kmourao
+ *
+ */
+public class RangeElementsIterator implements Iterator<Integer>
+{
+ private int last;
+
+ private int current;
+
+ private int next;
+
+ private Iterator<int[]> rangeIterator;
+
+ private int[] nextRange = null;
+
+ RangeElementsIterator(int from, int to, Iterator<int[]> it)
+ {
+ last = to;
+ current = from;
+ next = from;
+ rangeIterator = it;
+ if (rangeIterator.hasNext())
+ {
+ nextRange = rangeIterator.next();
+ }
+ checkNextRange();
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return next <= last;
+ }
+
+ @Override
+ public Integer next()
+ {
+ if (next > last)
+ {
+ throw new NoSuchElementException();
+ }
+
+ current = next;
+
+ // recalculate next
+ next++;
+
+ // if there are more ranges need to check if next is in a range
+ checkNextRange();
+ return current;
+ }
+
+ /**
+ * Check how next position relates to next range, and update next position if
+ * necessary
+ */
+ private void checkNextRange()
+ {
+ if (nextRange != null && next >= nextRange[0])
+ {
+ next = nextRange[1] + 1;
+ if (rangeIterator.hasNext())
+ {
+ nextRange = rangeIterator.next();
+ }
+ else
+ {
+ nextRange = null;
+ }
+
+ }
+ }
+
+ @Override
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+}
import java.util.List;
/**
- * An iterator which iterates over regions in a range. Works with a copy of the
- * collection of regions.
+ * An iterator which iterates over a list of ranges. Works with a copy of the
+ * collection of ranges.
*/
public class RangeIterator implements Iterator<int[]>
{
- // current index in regionsList
+ // current index in rangeList
private int currentPosition = 0;
- // current column in regionsList
- private int[] currentRegion;
+ // current range in rangeList
+ private int[] currentRange;
- // local copy or reference to regionsList
- private List<int[]> localRegions;
+ // local copy or reference to rangeList
+ private List<int[]> localRanges;
/**
* Unbounded constructor
*
- * @param regionsList
- * list of regions to iterate over
+ * @param rangeList
+ * list of ranges to iterate over
*/
- RangeIterator(List<int[]> regionsList)
+ RangeIterator(List<int[]> rangeList)
{
- if (!regionsList.isEmpty())
+ if (!rangeList.isEmpty())
{
- int last = regionsList.get(regionsList.size() - 1)[1];
- init(0, last, regionsList);
+ int last = rangeList.get(rangeList.size() - 1)[1];
+ init(0, last, rangeList);
}
else
{
- init(0, 0, regionsList);
+ init(0, 0, rangeList);
}
}
/**
- * Construct an iterator over regionsList bounded at [lowerBound,upperBound]
+ * Construct an iterator over rangeList bounded at [lowerBound,upperBound]
*
* @param lowerBound
* lower bound to iterate from
* @param upperBound
* upper bound to iterate to
- * @param regionsList
- * list of regions to iterate over
+ * @param rangeList
+ * list of ranges to iterate over
*/
RangeIterator(int lowerBound, int upperBound,
- List<int[]> regionsList)
+ List<int[]> rangeList)
{
- init(lowerBound, upperBound, regionsList);
+ init(lowerBound, upperBound, rangeList);
}
/**
- * Construct an iterator over regionsList bounded at [lowerBound,upperBound]
+ * Construct an iterator over rangeList bounded at [lowerBound,upperBound]
*
* @param lowerBound
* lower bound to iterate from
* upper bound to iterate to
*/
private void init(int lowerBound, int upperBound,
- List<int[]> regionsList)
+ List<int[]> rangeList)
{
int start = lowerBound;
int end = upperBound;
- if (regionsList != null)
+ if (rangeList != null)
{
- localRegions = new ArrayList<>();
+ localRanges = new ArrayList<>();
- // iterate until a region overlaps with [start,end]
+ // iterate until a range overlaps with [start,end]
int i = 0;
- while ((i < regionsList.size()) && (regionsList.get(i)[1] < start))
+ while ((i < rangeList.size()) && (rangeList.get(i)[1] < start))
{
i++;
}
- // iterate from start to end, adding each region. Positions are
- // absolute, and all regions which *overlap* [start,end] are added.
- while (i < regionsList.size() && (regionsList.get(i)[0] <= end))
+ // iterate from start to end, adding each range. Positions are
+ // absolute, and all ranges which *overlap* [start,end] are added.
+ while (i < rangeList.size() && (rangeList.get(i)[0] <= end))
{
- int[] rh = regionsList.get(i);
+ int[] rh = rangeList.get(i);
int[] cp = new int[2];
System.arraycopy(rh, 0, cp, 0, rh.length);
- localRegions.add(cp);
+ localRanges.add(cp);
i++;
}
}
@Override
public boolean hasNext()
{
- return (localRegions != null) && (currentPosition < localRegions.size());
+ return (localRanges != null) && (currentPosition < localRanges.size());
}
@Override
public int[] next()
{
- currentRegion = localRegions.get(currentPosition);
+ currentRange = localRanges.get(currentPosition);
currentPosition++;
- return currentRegion;
+ return currentRange;
}
@Override
public void remove()
{
- localRegions.remove(--currentPosition);
+ localRanges.remove(--currentPosition);
}
}
+++ /dev/null
-package jalview.datamodel;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-/**
- * Iterator over the visible *columns* (not regions) as determined by the set of
- * hidden columns. Uses a local copy of hidden columns.
- *
- * @author kmourao
- *
- */
-public class VisibleColsIterator implements Iterator<Integer>
-{
- private int last;
-
- private int current;
-
- private int next;
-
- private List<int[]> localHidden = new ArrayList<>();
-
- private int nexthiddenregion;
-
- VisibleColsIterator(int firstcol, int lastcol, List<int[]> hiddenColumns)
- {
- last = lastcol;
- current = firstcol;
- next = firstcol;
- nexthiddenregion = 0;
-
- if (hiddenColumns != null)
- {
- int i = 0;
- for (i = 0; i < hiddenColumns.size()
- && (current <= hiddenColumns.get(i)[0]); ++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;
- nexthiddenregion = i + 1;
- }
- }
-
- for (i = hiddenColumns.size() - 1; i >= 0
- && (last >= hiddenColumns.get(i)[1]); --i)
- {
- if (last >= hiddenColumns.get(i)[0]
- && last <= hiddenColumns.get(i)[1])
- {
- // last is hidden, move to left
- last = hiddenColumns.get(i)[0] - 1;
- }
- }
-
- // make a local copy of the bit we need
- i = nexthiddenregion;
- while (i < hiddenColumns.size() && hiddenColumns.get(i)[0] <= last)
- {
- int[] region = new int[] { hiddenColumns.get(i)[0],
- hiddenColumns.get(i)[1] };
- localHidden.add(region);
- i++;
- }
- }
- }
-
- @Override
- public boolean hasNext()
- {
- return next <= last;
- }
-
- @Override
- public Integer next()
- {
- if (next > last)
- {
- throw new NoSuchElementException();
- }
- current = next;
- if ((localHidden != null) && (nexthiddenregion < localHidden.size()))
- {
- // still some more hidden regions
- if (next + 1 < localHidden.get(nexthiddenregion)[0])
- {
- // next+1 is still before the next hidden region
- next++;
- }
- else if ((next + 1 >= localHidden.get(nexthiddenregion)[0])
- && (next + 1 <= localHidden.get(nexthiddenregion)[1]))
- {
- // next + 1 is in the next hidden region
- next = localHidden.get(nexthiddenregion)[1] + 1;
- nexthiddenregion++;
- }
- }
- else
- {
- // finished with hidden regions, just increment normally
- next++;
- }
- return current;
- }
-
- @Override
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
-}
HiddenColumns h = new HiddenColumns();
Iterator<Integer> it = h.getVisibleColsIterator(0, 10);
- assertTrue(it instanceof VisibleColsIterator);
+ assertTrue(it instanceof RangeElementsIterator);
}
@Test(groups = "Functional")
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-public class VisibleColsIteratorTest
+public class RangeElementsIteratorTest
{
HiddenColumns hiddenCols;