public class HiddenColumns
{
+ private static final int HASH_MULTIPLIER = 31;
+
private static final ReentrantReadWriteLock LOCK = new ReentrantReadWriteLock();
/*
/**
* Use this method to determine the set of hiddenRegion start positions
+ * between absolute position <start> and absolute position <end>
+ *
+ * @param start
+ * absolute residue to start from
+ * @param end
+ * absolute residue to end at
*
- * @return list of column number in visible view where hidden regions start
+ * @return list of column numbers in *visible* view where hidden regions start
*/
- public List<Integer> findHiddenRegionPositions()
+ public List<Integer> findHiddenRegionPositions(int start, int end)
{
try
{
{
positions = new ArrayList<>(hiddenColumns.size());
- positions.add(hiddenColumns.get(0)[0]);
- for (int i = 1; i < hiddenColumns.size(); ++i)
+ // navigate to start, keeping count of hidden columns
+ int i = 0;
+ int hiddenSoFar = 0;
+ while ((i < hiddenColumns.size())
+ && (hiddenColumns.get(i)[0] < start))
{
+ int[] region = hiddenColumns.get(i);
+ hiddenSoFar += region[1] - region[0] + 1;
+ i++;
+ }
- int result = 0;
- if (hiddenColumns != null)
- {
- int index = 0;
- int gaps = 0;
- do
- {
- int[] region = hiddenColumns.get(index);
- gaps += region[1] + 1 - region[0];
- result = region[1] + 1;
- index++;
- } while (index <= i);
-
- result -= gaps;
- }
- positions.add(result);
+ // 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
}
/**
- * propagate shift in alignment columns to column selection
- *
- * @param start
- * beginning of edit
- * @param left
- * shift in edit (+ve for removal, or -ve for inserts)
- */
- public List<int[]> compensateForEdit(int start, int change,
- ColumnSelection sel)
- {
- try
- {
- LOCK.writeLock().lock();
- List<int[]> deletedHiddenColumns = null;
-
- if (hiddenColumns != null)
- {
- deletedHiddenColumns = new ArrayList<>();
- int hSize = hiddenColumns.size();
- for (int i = 0; i < hSize; i++)
- {
- int[] region = hiddenColumns.get(i);
- if (region[0] > start && start + change > region[1])
- {
- deletedHiddenColumns.add(region);
-
- hiddenColumns.remove(i);
- i--;
- hSize--;
- continue;
- }
-
- if (region[0] > start)
- {
- region[0] -= change;
- region[1] -= change;
- }
-
- if (region[0] < 0)
- {
- region[0] = 0;
- }
-
- }
-
- this.revealHiddenColumns(0, sel);
- }
-
- return deletedHiddenColumns;
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
- * propagate shift in alignment columns to column selection special version of
- * compensateForEdit - allowing for edits within hidden regions
- *
- * @param start
- * beginning of edit
- * @param left
- * shift in edit (+ve for removal, or -ve for inserts)
- */
- public void compensateForDelEdits(int start, int change)
- {
- try
- {
- LOCK.writeLock().lock();
- if (hiddenColumns != null)
- {
- for (int i = 0; i < hiddenColumns.size(); i++)
- {
- int[] region = hiddenColumns.get(i);
- if (region[0] >= start)
- {
- region[0] -= change;
- }
- if (region[1] >= start)
- {
- region[1] -= change;
- }
- if (region[1] < region[0])
- {
- hiddenColumns.remove(i--);
- }
-
- if (region[0] < 0)
- {
- region[0] = 0;
- }
- if (region[1] < 0)
- {
- region[1] = 0;
- }
- }
- }
- } finally
- {
- LOCK.writeLock().unlock();
- }
- }
-
- /**
* return all visible segments between the given start and end boundaries
*
* @param start
LOCK.readLock().lock();
if (hiddenColumns != null && hiddenColumns.size() > 0)
{
- List<int[]> visiblecontigs = new ArrayList<>();
- List<int[]> regions = getHiddenRegions();
-
+ // 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[] region;
int hideStart;
int hideEnd;
+ int i = 0;
- for (int j = 0; vstart < end && j < regions.size(); j++)
+ for (int[] region : hiddenColumns)
{
- region = regions.get(j);
hideStart = region[0];
hideEnd = region[1];
+ // navigate to start
if (hideEnd < vstart)
{
continue;
}
if (hideStart > vstart)
{
- visiblecontigs.add(new int[] { vstart, hideStart - 1 });
+ vcontigs[i * 2] = vstart;
+ vcontigs[i * 2 + 1] = hideStart - 1;
+ i++;
}
vstart = hideEnd + 1;
+
+ // exit if we're past the end
+ if (vstart >= end)
+ {
+ break;
+ }
}
if (vstart < end)
{
- visiblecontigs.add(new int[] { vstart, end - 1 });
- }
- int[] vcontigs = new int[visiblecontigs.size() * 2];
- for (int i = 0, j = visiblecontigs.size(); i < j; i++)
- {
- int[] vc = visiblecontigs.get(i);
- visiblecontigs.set(i, null);
- vcontigs[i * 2] = vc[0];
- vcontigs[i * 2 + 1] = vc[1];
+ vcontigs[i * 2] = vstart;
+ vcontigs[i * 2 + 1] = end - 1;
+ i++;
}
- visiblecontigs.clear();
- return vcontigs;
+
+ // 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
{
for (int i = 0; i < iSize; i++)
{
StringBuffer visibleSeq = new StringBuffer();
- List<int[]> regions = getHiddenRegions();
int blockStart = start;
int blockEnd = end;
- int[] region;
int hideStart;
int hideEnd;
- for (int j = 0; j < regions.size(); j++)
+ for (int[] region : hiddenColumns)
{
- region = regions.get(j);
hideStart = region[0];
hideEnd = region[1];
// boundaries
List<int[]> regions = getHiddenRegions();
int spos = fpos;
- int lastvispos = -1;
int rcount = 0;
int hideStart = seq.getLength();
int hideEnd = -1;
start = p;
foundStart = true;
}
- lastvispos = p;
lpos = spos;
}
// look for next sequence position
// then mangle the alignmentAnnotation annotation array
Vector<Annotation[]> annels = new Vector<>();
Annotation[] els = null;
- List<int[]> regions = getHiddenRegions();
int blockStart = start;
int blockEnd = end;
- int[] region;
int hideStart;
int hideEnd;
int w = 0;
- for (int j = 0; j < regions.size(); j++)
+ for (int[] region : hiddenColumns)
{
- region = regions.get(j);
hideStart = region[0];
hideEnd = region[1];
break;
}
- annels.addElement(els = new Annotation[blockEnd - blockStart]);
+ els = new Annotation[blockEnd - blockStart];
+ annels.addElement(els);
System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
0, els.length);
w += els.length;
if (end > blockStart)
{
- annels.addElement(els = new Annotation[end - blockStart + 1]);
+ els = new Annotation[end - blockStart + 1];
+ annels.addElement(els);
if ((els.length
+ blockStart) <= alignmentAnnotation.annotations.length)
{
{
for (int[] hidden : hiddenColumns)
{
- hashCode = 31 * hashCode + hidden[0];
- hashCode = 31 * hashCode + hidden[1];
+ hashCode = HASH_MULTIPLIER * hashCode + hidden[0];
+ hashCode = HASH_MULTIPLIER * hashCode + hidden[1];
}
}
return hashCode;
LOCK.readLock().unlock();
}
}
-
}
{
HiddenColumns hc = new HiddenColumns();
- List<Integer> positions = hc.findHiddenRegionPositions();
+ List<Integer> positions = hc.findHiddenRegionPositions(0, 20);
assertTrue(positions.isEmpty());
hc.hideColumns(3, 7);
hc.hideColumns(10, 10);
hc.hideColumns(14, 15);
- positions = hc.findHiddenRegionPositions();
+ positions = hc.findHiddenRegionPositions(0, 20);
assertEquals(3, positions.size());
assertEquals(3, positions.get(0).intValue());
assertEquals(5, positions.get(1).intValue());
assertEquals(8, positions.get(2).intValue());
+
+ positions = hc.findHiddenRegionPositions(7, 20);
+ assertEquals(2, positions.size());
+ assertEquals(5, positions.get(0).intValue());
+ assertEquals(8, positions.get(1).intValue());
+
+ positions = hc.findHiddenRegionPositions(11, 13);
+ assertEquals(0, positions.size());
+
+ positions = hc.findHiddenRegionPositions(7, 20);
+ assertEquals(2, positions.size());
+ assertEquals(5, positions.get(0).intValue());
+ assertEquals(8, positions.get(1).intValue());
+
+ positions = hc.findHiddenRegionPositions(0, 1);
+ assertEquals(0, positions.size());
+
+ positions = hc.findHiddenRegionPositions(17, 20);
+ assertEquals(0, positions.size());
+
+ positions = hc.findHiddenRegionPositions(10, 15);
+ assertEquals(2, positions.size());
+ assertEquals(5, positions.get(0).intValue());
+ assertEquals(8, positions.get(1).intValue());
}
@Test(groups = { "Functional" })