* (first column inclusive from 0)
* @param end
* (last column - not inclusive)
- * @return int[] {i_start, i_end, ..} where intervals lie in
+ * @return List<int[]> {[i_start, i_end], ..} where intervals lie in
* start<=i_start<=i_end<end
*/
- public int[] getVisibleContigs(int start, int end)
+ public List<int[]> getVisibleContigs(int start, int end)
{
try
{
LOCK.readLock().lock();
+ List<int[]> vcontigs = new ArrayList<>();
if (hiddenColumns != null && hiddenColumns.size() > 0)
{
- // max limit on number of visible contigs
- // so we can dimension array
- int maxcontigs = end - start + 1;
- if (maxcontigs > (hiddenColumns.size() + 1) * 2)
- {
- maxcontigs = (hiddenColumns.size() + 1) * 2;
- }
- int[] vcontigs = new int[maxcontigs];
int vstart = start;
int hideStart;
int hideEnd;
- int i = 0;
for (int[] region : hiddenColumns)
{
}
if (hideStart > vstart)
{
- vcontigs[i * 2] = vstart;
- vcontigs[i * 2 + 1] = hideStart - 1;
- i++;
+ int[] contig = new int[] { vstart, hideStart - 1 };
+ vcontigs.add(contig);
}
vstart = hideEnd + 1;
if (vstart < end)
{
- vcontigs[i * 2] = vstart;
- vcontigs[i * 2 + 1] = end - 1;
- i++;
+ int[] contig = new int[] { vstart, end - 1 };
+ vcontigs.add(contig);
}
-
- // copy final array into array of correct size
- int[] trimmmedContigs = new int[i * 2];
- System.arraycopy(vcontigs, 0, trimmmedContigs, 0, i * 2);
-
- return trimmmedContigs;
}
else
{
- return new int[] { start, end - 1 };
+ int[] contig = new int[] { start, end - 1 };
+ vcontigs.add(contig);
}
+ return vcontigs;
} finally
{
LOCK.readLock().unlock();
return new BoundedStartRegionIterator(start, end, useCopy);
}
+ public Iterator<int[]> getBoundedVisRegionIterator(int start, int end)
+ {
+ return new BoundedVisRegionIterator(start, end, true);
+ }
+
/**
* An iterator which iterates over hidden column regions in a range.
*
return result;
}
}
+
+ class BoundedVisRegionIterator implements Iterator<int[]>
+ {
+ private int start; // start position to iterate from
+
+ private int end; // end position to iterate to
+
+ // current region in visColumns
+ private int[] currentRegion;
+
+ // current index in visColumns
+ private int currentPosition = 0;
+
+ private List<int[]> vcontigs = null;
+
+ /**
+ * 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)
+ {
+ try
+ {
+ start = lowerBound;
+ end = upperBound;
+
+ if (useCopy)
+ {
+ // assume that if useCopy is false the calling code has locked
+ // 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))
+ {
+ i++;
+ }
+ // 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)
+ {
+ region = hiddenColumns.get(i - 1);
+ if ((region[1] > start) && (region[1] < end))
+ {
+ visStart = region[1] + 1;
+ }
+ else if (region[1] >= end)
+ {
+ // previous hidden region covers whole range [start,end]
+ // early exit - vcontigs is empty
+ return;
+ }
+ }
+
+ // 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))
+ {
+ region = hiddenColumns.get(i);
+ int[] prevVisibleRegion = new int[] { visStart, region[0] - 1 };
+ vcontigs.add(prevVisibleRegion);
+ visStart = region[1] + 1;
+ 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);
+ }
+ } finally
+ {
+ if (useCopy)
+ {
+ LOCK.readLock().unlock();
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return (currentPosition < vcontigs.size());
+ }
+
+ @Override
+ public int[] next()
+ {
+ currentRegion = vcontigs.get(currentPosition);
+ currentPosition++;
+ return currentRegion;
+ }
+ }
}