From a3c835f0495ade5c3ae7968dd9727c03710d870b Mon Sep 17 00:00:00 2001 From: kiramt Date: Fri, 6 Oct 2017 14:04:44 +0100 Subject: [PATCH] JAL-2674 Last moves to iterators --- src/jalview/datamodel/HiddenColumns.java | 285 +++++++++---------------- test/jalview/datamodel/HiddenColumnsTest.java | 114 +++++----- 2 files changed, 149 insertions(+), 250 deletions(-) diff --git a/src/jalview/datamodel/HiddenColumns.java b/src/jalview/datamodel/HiddenColumns.java index 4b0996f..fb1961e 100644 --- a/src/jalview/datamodel/HiddenColumns.java +++ b/src/jalview/datamodel/HiddenColumns.java @@ -60,7 +60,12 @@ public class HiddenColumns { if (copy.hiddenColumns != null) { - hiddenColumns = copy.copyHiddenRegionsToArrayList(0); + hiddenColumns = new ArrayList<>(); + Iterator it = copy.iterator(); + while (it.hasNext()) + { + hiddenColumns.add(it.next()); + } } } } finally @@ -305,8 +310,8 @@ public class HiddenColumns // earlier hidden columns. // Calculate the difference between the actual hidden col position // and region[0]-1, and then subtract from result to convert result - // from - // the adjusted hiddenColumn value to the adjusted region[0]-1 value + // from the adjusted hiddenColumn value to the adjusted region[0]-1 + // value. // However, if the region begins at 0 we cannot return region[0]-1 // just return 0 @@ -343,7 +348,6 @@ public class HiddenColumns { try { - LOCK.readLock().lock(); int distance = visibleDistance; @@ -352,73 +356,28 @@ public class HiddenColumns Iterator it = new ReverseRegionsIterator(0, start); - int[] region; - int gap = 0; - int nextstart = start; - - while (it.hasNext() && (distance - gap > 0)) + while (it.hasNext() && (distance > 0)) { - region = it.next(); + int[] region = it.next(); if (start > region[1]) { - - // subtract the gap to right of region from distance - distance -= start - region[1]; // gap; - - start = nextstart; - nextstart = region[0] - 1;// nextstart; - - - // calculate the next gap - - // gap = start - region[1]; - - // set start to just to left of current region - // nextstart = region[0] - 1; + if (start - region[1] <= distance) + { + distance -= start - region[1]; + start = region[0] - 1; + } + else + { + start = start - distance; + distance = 0; + } } } - if (!it.hasNext()) - { - // no hidden regions to left of startColumn - return start - distance; - } - else - { + return start - distance; - /* // walk backwards through the alignment subtracting the counts of - // visible - // columns from distance - int[] region; - int gap = 0; - int nextstart = start; - - while (it.hasNext() && (distance - gap > 0)) - { - region = it.next(); - - // subtract the gap to right of region from distance - distance -= gap; - start = nextstart; - - // calculate the next gap - - gap = start - region[1]; - - // set start to just to left of current region - nextstart = region[0] - 1; - } - */ - if (distance - gap > 0) - { - // fell out of loop because there are no more hidden regions - distance -= gap; - return nextstart - distance; - } - return start - distance; - } } finally { LOCK.readLock().unlock(); @@ -488,48 +447,12 @@ public class HiddenColumns } /** - * This method returns the index of the hidden region to the left of a column - * position. If the column is in a hidden region it returns the index of the - * region to the left. If there is no hidden region to the left it returns -1. - * - * @param pos - * position to find index relative to - */ - private int getHiddenIndexLeft(int pos) - { - try - { - LOCK.readLock().lock(); - - - Iterator it = new ReverseRegionsIterator(0, pos); - if (it.hasNext()) - { - int index = hiddenColumns.size() - 1; // need index of region not last - // one - while (it.hasNext()) - { - int[] region = it.next(); - if (pos > region[1]) - { - return index; - } - index--; - } - } - return -1; - } finally - { - LOCK.readLock().unlock(); - } - - } - - /** - * Adds the specified column range to the hidden columns + * Adds the specified column range to the hidden columns collection * * @param start + * start of range to add (absolute position in alignment) * @param end + * end of range to add (absolute position in alignment) */ public void hideColumns(int start, int end) { @@ -569,53 +492,7 @@ public class HiddenColumns boolean added = false; for (int i = 0; !added && i < hiddenColumns.size(); i++) { - int[] region = hiddenColumns.get(i); - - if (end < region[0] - 1) - { - /* - * insert discontiguous preceding range - */ - hiddenColumns.add(i, new int[] { start, end }); - added = true; - } - else if (end <= region[1]) - { - /* - * new range overlaps existing, or is contiguous preceding it - adjust - * start column - */ - region[0] = Math.min(region[0], start); - added = true; - } - else if (start <= region[1] + 1) - { - /* - * new range overlaps existing, or is contiguous following it - adjust - * start and end columns - */ - region[0] = Math.min(region[0], start); - region[1] = Math.max(region[1], end); - - /* - * also update or remove any subsequent ranges - * that are overlapped - */ - while (i < hiddenColumns.size() - 1) - { - int[] nextRegion = hiddenColumns.get(i + 1); - if (nextRegion[0] > end + 1) - { - /* - * gap to next hidden range - no more to update - */ - break; - } - region[1] = Math.max(nextRegion[1], end); - hiddenColumns.remove(i + 1); - } - added = true; - } + added = insertRangeAtRegion(i, start, end); } // for } } finally @@ -627,6 +504,66 @@ public class HiddenColumns } } + private boolean insertRangeAtRegion(int i, int start, int end) + { + boolean added = false; + + int[] region = hiddenColumns.get(i); + if (end < region[0] - 1) + { + /* + * insert discontiguous preceding range + */ + hiddenColumns.add(i, new int[] { start, end }); + added = true; + } + else if (end <= region[1]) + { + /* + * new range overlaps existing, or is contiguous preceding it - adjust + * start column + */ + region[0] = Math.min(region[0], start); + added = true; + } + else if (start <= region[1] + 1) + { + /* + * new range overlaps existing, or is contiguous following it - adjust + * start and end columns + */ + region[0] = Math.min(region[0], start); + region[1] = Math.max(region[1], end); + + /* + * also update or remove any subsequent ranges + * that are overlapped + */ + while (i < hiddenColumns.size() - 1) + { + int[] nextRegion = hiddenColumns.get(i + 1); + if (nextRegion[0] > end + 1) + { + /* + * gap to next hidden range - no more to update + */ + break; + } + region[1] = Math.max(nextRegion[1], end); + hiddenColumns.remove(i + 1); + } + added = true; + } + return added; + } + + /** + * Answers if a column in the alignment is visible + * + * @param column + * absolute position of column in the alignment + * @return true if column is visible + */ public boolean isVisible(int column) { try @@ -650,31 +587,17 @@ public class HiddenColumns } } - private ArrayList copyHiddenRegionsToArrayList(int startIndex) - { - int size = 0; - if (hiddenColumns != null) - { - size = hiddenColumns.size(); - } - ArrayList copy = new ArrayList<>(size); - - for (int i = startIndex, j = size; i < j; i++) - { - int[] rh; - int[] cp; - rh = hiddenColumns.get(i); - if (rh != null) - { - cp = new int[rh.length]; - System.arraycopy(rh, 0, cp, 0, rh.length); - copy.add(cp); - } - } - - return copy; - } - + /** + * Get the visible sections of a set of sequences + * + * @param start + * sequence position to start from + * @param end + * sequence position to end at + * @param seqs + * an array of sequences + * @return an array of strings encoding the visible parts of each sequence + */ public String[] getVisibleSequenceStrings(int start, int end, SequenceI[] seqs) { @@ -1564,22 +1487,6 @@ public class HiddenColumns init(lowerBound, upperBound); } - // Unbounded constructor - ReverseRegionsIterator() - { - if (hiddenColumns != null) - { - // iterator over full hiddenColumns collection - int last = hiddenColumns.get(hiddenColumns.size() - 1)[1]; - init(0, last); - } - else - { - // empty iterator - init(0, 0); - } - } - /** * Construct an iterator over hiddenColums bounded at * [lowerBound,upperBound] diff --git a/test/jalview/datamodel/HiddenColumnsTest.java b/test/jalview/datamodel/HiddenColumnsTest.java index 95c9fc6..3147aeb 100644 --- a/test/jalview/datamodel/HiddenColumnsTest.java +++ b/test/jalview/datamodel/HiddenColumnsTest.java @@ -119,67 +119,6 @@ public class HiddenColumnsTest HiddenColumns cs3 = new HiddenColumns(); cs3.hideColumns(0, 4); assertEquals(0, cs3.findColumnPosition(2)); - - } - - /** - * Test the method that finds the visible column position a given distance - * before another column - */ - @Test(groups = { "Functional" }) - public void testFindColumnNToLeft() - { - HiddenColumns cs = new HiddenColumns(); - - // test that without hidden columns, findColumnNToLeft returns - // position n to left of provided position - long pos = cs.subtractVisibleColumns(3, 10); - assertEquals(7, pos); - - // 0 returns same position - pos = cs.subtractVisibleColumns(0, 10); - assertEquals(10, pos); - - // overflow to left returns negative number - pos = cs.subtractVisibleColumns(3, 0); - assertEquals(-3, pos); - - // test that with hidden columns to left of result column - // behaviour is the same as above - cs.hideColumns(1, 3); - - // position n to left of provided position - pos = cs.subtractVisibleColumns(3, 10); - assertEquals(7, pos); - - // 0 returns same position - pos = cs.subtractVisibleColumns(0, 10); - assertEquals(10, pos); - - // test with one set of hidden columns between start and required position - cs.hideColumns(12, 15); - pos = cs.subtractVisibleColumns(8, 17); - assertEquals(5, pos); - - // test with two sets of hidden columns between start and required position - cs.hideColumns(20, 21); - pos = cs.subtractVisibleColumns(8, 23); - assertEquals(9, pos); - - // repeat last 2 tests with no hidden columns to left of required position - ColumnSelection colsel = new ColumnSelection(); - cs.revealAllHiddenColumns(colsel); - - // test with one set of hidden columns between start and required position - cs.hideColumns(12, 15); - pos = cs.subtractVisibleColumns(8, 17); - assertEquals(5, pos); - - // test with two sets of hidden columns between start and required position - cs.hideColumns(20, 21); - pos = cs.subtractVisibleColumns(8, 23); - assertEquals(9, pos); - } @Test(groups = { "Functional" }) @@ -1226,8 +1165,61 @@ public class HiddenColumnsTest h.hideColumns(0, 30); result = h.subtractVisibleColumns(31, 0); assertEquals(-31, result); + + HiddenColumns cs = new HiddenColumns(); + + // test that without hidden columns, findColumnNToLeft returns + // position n to left of provided position + long pos = cs.subtractVisibleColumns(3, 10); + assertEquals(7, pos); + + // 0 returns same position + pos = cs.subtractVisibleColumns(0, 10); + assertEquals(10, pos); + + // overflow to left returns negative number + pos = cs.subtractVisibleColumns(3, 0); + assertEquals(-3, pos); + + // test that with hidden columns to left of result column + // behaviour is the same as above + cs.hideColumns(1, 3); + + // position n to left of provided position + pos = cs.subtractVisibleColumns(3, 10); + assertEquals(7, pos); + + // 0 returns same position + pos = cs.subtractVisibleColumns(0, 10); + assertEquals(10, pos); + + // test with one set of hidden columns between start and required position + cs.hideColumns(12, 15); + pos = cs.subtractVisibleColumns(8, 17); + assertEquals(5, pos); + + // test with two sets of hidden columns between start and required position + cs.hideColumns(20, 21); + pos = cs.subtractVisibleColumns(8, 23); + assertEquals(9, pos); + + // repeat last 2 tests with no hidden columns to left of required position + ColumnSelection colsel = new ColumnSelection(); + cs.revealAllHiddenColumns(colsel); + + // test with one set of hidden columns between start and required position + cs.hideColumns(12, 15); + pos = cs.subtractVisibleColumns(8, 17); + assertEquals(5, pos); + + // test with two sets of hidden columns between start and required position + cs.hideColumns(20, 21); + pos = cs.subtractVisibleColumns(8, 23); + assertEquals(9, pos); + } + @Test(groups = "Functional") public void testBoundedIterator() { -- 1.7.10.2