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;
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();
}
/**
- * 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
}
}
- 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);
}
/**
* @author kmourao
*
*/
-
-
class BoundedHiddenColsIterator implements Iterator<int[]>
{
-
private int start; // start position to iterate from
private int end; // end position to iterate to
}
}
- 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
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
{
@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();
}
}
}