import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.locks.ReentrantReadWriteLock;
{
if (copy.hiddenColumns != null)
{
- hiddenColumns = copy.copyHiddenRegionsToArrayList();
+ hiddenColumns = copy.copyHiddenRegionsToArrayList(0);
}
}
} finally
// iterate from start to end, adding start positions of each
// hidden region. Positions are visible columns count, not absolute
while (i < hiddenColumns.size()
- && (hiddenColumns.get(i)[0] < end + hiddenSoFar))
+ && (hiddenColumns.get(i)[0] < end))
{
int[] region = hiddenColumns.get(i);
positions.add(region[0] - hiddenSoFar);
}
}
- private ArrayList<int[]> copyHiddenRegionsToArrayList()
+ private ArrayList<int[]> copyHiddenRegionsToArrayList(int startIndex)
{
int size = 0;
if (hiddenColumns != null)
}
ArrayList<int[]> copy = new ArrayList<>(size);
- for (int i = 0, j = size; i < j; i++)
+ for (int i = startIndex, j = size; i < j; i++)
{
int[] rh;
int[] cp;
try
{
LOCK.readLock().lock();
- return copyHiddenRegionsToArrayList();
+ return copyHiddenRegionsToArrayList(0);
} finally
{
LOCK.readLock().unlock();
LOCK.readLock().unlock();
}
}
+
+ public Iterator<int[]> getBoundedIterator(int start, int end,
+ boolean useCopy)
+ {
+ return new BoundedHiddenColsIterator(start, end, useCopy);
+ }
+
+ public Iterator<Integer> getBoundedStartIterator(int start, int end,
+ boolean useCopy)
+ {
+ return new BoundedStartRegionIterator(start, end, useCopy);
+ }
+
+ /**
+ * An iterator which iterates over hidden column regions in a range.
+ *
+ * @author kmourao
+ *
+ */
+
+
+ class BoundedHiddenColsIterator implements Iterator<int[]>
+ {
+
+ private int start; // start position to iterate from
+
+ private int end; // end position to iterate to
+
+ // current index in hiddenColumns
+ private int currentPosition = 0;
+
+ // current column in hiddenColumns
+ private int[] currentRegion;
+
+ // whether to make a local copy of hiddenColumns
+ private final boolean useCopy;
+
+ // local copy or reference to hiddenColumns
+ private List<int[]> localHidden;
+
+ /**
+ * Construct an iterator over hiddenColums bounded at
+ * [lowerBound,upperBound]
+ *
+ * @param lowerBound
+ * lower bound to iterate from
+ * @param upperBound
+ * upper bound to iterate to
+ * @param opt
+ * Option.OVERLAP: regions which overlap [lowerBound,upperBound]
+ * are included Option.START: regions which start in
+ * [lowerBound,upperBound] are included
+ * @param useAbsolutePos
+ * have bounds and return values with reference to absolute indices
+ * (if false, use indices for visible columns)
+ * @param useCopyCols
+ * whether to make a local copy of hiddenColumns for iteration (set
+ * to true if calling from outwith the HiddenColumns class)
+ */
+ BoundedHiddenColsIterator(int lowerBound, int upperBound,
+ boolean useCopyCols)
+ {
+ start = lowerBound;
+ end = upperBound;
+ useCopy = useCopyCols;
+
+ try
+ {
+ if (useCopy)
+ {
+ // assume that if useCopy is false the calling code has locked
+ // hiddenColumns
+ LOCK.readLock().lock();
+ }
+
+ if (hiddenColumns != null)
+ {
+ localHidden = new ArrayList<>();
+
+ // iterate until a region overlaps with [start,end]
+ int i = 0;
+ while ((i < hiddenColumns.size())
+ && (hiddenColumns.get(i)[1] < start))
+ {
+ i++;
+ }
+
+ // iterate from start to end, adding each hidden region. Positions are
+ // absolute, and all regions which *overlap* [start,end] are added.
+ while (i < hiddenColumns.size()
+ && (hiddenColumns.get(i)[0] <= end))
+ {
+ int[] rh;
+ int[] cp;
+ rh = hiddenColumns.get(i);
+ if (rh != null)
+ {
+ cp = new int[rh.length];
+ System.arraycopy(rh, 0, cp, 0, rh.length);
+ localHidden.add(cp);
+ }
+ i++;
+ }
+ }
+ }
+ finally
+ {
+ if (useCopy)
+ {
+ LOCK.readLock().unlock();
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return (localHidden != null)
+ && (currentPosition < localHidden.size());
+ }
+
+ @Override
+ public int[] next()
+ {
+ currentRegion = localHidden.get(currentPosition);
+ currentPosition++;
+ return currentRegion;
+ }
+ }
+
+ class BoundedStartRegionIterator implements Iterator<Integer>
+ {
+
+ private int start; // start position to iterate from
+
+ private int end; // end position to iterate to
+
+ // current index in hiddenColumns
+ private int currentPosition = 0;
+
+ // local copy or reference to hiddenColumns
+ private List<Integer> positions = null;
+
+ /**
+ * Construct an iterator over hiddenColums 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 of hiddenColumns for iteration (set
+ * to true if calling from outwith the HiddenColumns class)
+ */
+ BoundedStartRegionIterator(int lowerBound, int upperBound,
+ boolean useCopy)
+ {
+ start = lowerBound;
+ end = upperBound;
+
+ try
+ {
+ if (useCopy)
+ {
+ // assume that if useCopy is false the calling code has locked
+ // hiddenColumns
+ LOCK.readLock().lock();
+ }
+
+ if (hiddenColumns != null)
+ {
+ positions = new ArrayList<>(hiddenColumns.size());
+
+ // navigate to start, keeping count of hidden columns
+ int i = 0;
+ int hiddenSoFar = 0;
+ while ((i < hiddenColumns.size())
+ && (hiddenColumns.get(i)[0] < start + hiddenSoFar))
+ {
+ int[] region = hiddenColumns.get(i);
+ hiddenSoFar += region[1] - region[0] + 1;
+ i++;
+ }
+
+ // iterate from start to end, adding start positions of each
+ // hidden region. Positions are visible columns count, not absolute
+ while (i < hiddenColumns.size()
+ && (hiddenColumns.get(i)[0] <= end + hiddenSoFar))
+ {
+ int[] region = hiddenColumns.get(i);
+ positions.add(region[0] - hiddenSoFar);
+ hiddenSoFar += region[1] - region[0] + 1;
+ i++;
+ }
+ }
+ else
+ {
+ positions = new ArrayList<>();
+ }
+ } finally
+ {
+ if (useCopy)
+ {
+ LOCK.readLock().unlock();
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return (currentPosition < positions.size());
+ }
+
+ @Override
+ public Integer next()
+ {
+ int result = positions.get(currentPosition);
+ currentPosition++;
+ return result;
+ }
+ }
}