From f63986510999f17f5fa7bf7af09c13cd888adf4e Mon Sep 17 00:00:00 2001 From: kiramt Date: Fri, 6 Oct 2017 10:29:29 +0100 Subject: [PATCH] JAL-2647 stashing --- src/jalview/datamodel/HiddenColumns.java | 302 +++++++++++++++++++++--------- 1 file changed, 216 insertions(+), 86 deletions(-) diff --git a/src/jalview/datamodel/HiddenColumns.java b/src/jalview/datamodel/HiddenColumns.java index c8f2bf6..4b0996f 100644 --- a/src/jalview/datamodel/HiddenColumns.java +++ b/src/jalview/datamodel/HiddenColumns.java @@ -128,7 +128,7 @@ public class HiddenColumns { LOCK.readLock().lock(); StringBuilder regionBuilder = new StringBuilder(); - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); while (it.hasNext()) { int[] range = it.next(); @@ -157,7 +157,7 @@ public class HiddenColumns { LOCK.readLock().lock(); int size = 0; - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); while (it.hasNext()) { int[] range = it.next(); @@ -219,7 +219,7 @@ public class HiddenColumns return false; } - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); Iterator thatit = that.iterator(); while (it.hasNext()) { @@ -251,7 +251,7 @@ public class HiddenColumns LOCK.readLock().lock(); int result = column; - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); while (it.hasNext()) { int[] region = it.next(); @@ -286,7 +286,7 @@ public class HiddenColumns int[] region = null; if (hiddenColumns != null) { - Iterator it = new LocalBoundedHiddenColsIterator(0, + Iterator it = new RegionsIterator(0, hiddenColumn); while (it.hasNext()) { @@ -350,57 +350,87 @@ public class HiddenColumns // in case startColumn is in a hidden region, move it to the left int start = adjustForHiddenColumns(findColumnPosition(startColumn)); - // get index of hidden region to left of start - int index = getHiddenIndexLeft(start); - if (index == -1) - { - // no hidden regions to left of startColumn - return start - distance; - } + Iterator it = new ReverseRegionsIterator(0, start); - // walk backwards through the alignment subtracting the counts of visible - // columns from distance int[] region; int gap = 0; int nextstart = start; - while ((index > -1) && (distance - gap > 0)) + while (it.hasNext() && (distance - gap > 0)) { - // subtract the gap to right of region from distance - distance -= gap; - start = nextstart; + 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 - region = hiddenColumns.get(index); - gap = start - region[1]; + // calculate the next gap - // set start to just to left of current region - nextstart = region[0] - 1; - index--; + // gap = start - region[1]; + + // set start to just to left of current region + // nextstart = region[0] - 1; + } } - if (distance - gap > 0) + if (!it.hasNext()) { - // fell out of loop because there are no more hidden regions - distance -= gap; - return nextstart - distance; + // no hidden regions to left of startColumn + return start - distance; + } + else + { + + /* // 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; } - return start - distance; } finally { LOCK.readLock().unlock(); } - } - - /** * This method returns the rightmost limit of a region of an alignment with * hidden columns. In otherwords, the next hidden column. * - * @param index - * int + * @param alPos + * the (visible) alignmentPosition to find the next hidden column for */ public int getHiddenBoundaryRight(int alPos) { @@ -409,33 +439,30 @@ public class HiddenColumns LOCK.readLock().lock(); if (hiddenColumns != null) { - int index = 0; - do + Iterator it = new RegionsIterator(); + while (it.hasNext()) { - int[] region = hiddenColumns.get(index); + int[] region = it.next(); if (alPos < region[0]) { return region[0]; } - - index++; - } while (index < hiddenColumns.size()); + } } - return alPos; } finally { LOCK.readLock().unlock(); } - } /** * This method returns the leftmost limit of a region of an alignment with * hidden columns. In otherwords, the previous hidden column. * - * @param index - * int + * @param alPos + * the (visible) alignmentPosition to find the previous hidden column + * for */ public int getHiddenBoundaryLeft(int alPos) { @@ -443,19 +470,14 @@ public class HiddenColumns { LOCK.readLock().lock(); - if (hiddenColumns != null) + Iterator it = new ReverseRegionsIterator(0, alPos); + while (it.hasNext()) { - int index = hiddenColumns.size() - 1; - do + int[] region = it.next(); + if (alPos > region[1]) { - int[] region = hiddenColumns.get(index); - if (alPos > region[1]) - { - return region[1]; - } - - index--; - } while (index > -1); + return region[1]; + } } return alPos; @@ -471,29 +493,30 @@ public class HiddenColumns * region to the left. If there is no hidden region to the left it returns -1. * * @param pos - * int + * position to find index relative to */ private int getHiddenIndexLeft(int pos) { try { - LOCK.readLock().lock(); - if (hiddenColumns != null) + + + Iterator it = new ReverseRegionsIterator(0, pos); + if (it.hasNext()) { - int index = hiddenColumns.size() - 1; - do + int index = hiddenColumns.size() - 1; // need index of region not last + // one + while (it.hasNext()) { - int[] region = hiddenColumns.get(index); + int[] region = it.next(); if (pos > region[1]) { return index; } - index--; - } while (index > -1); + } } - return -1; } finally { @@ -610,7 +633,7 @@ public class HiddenColumns { LOCK.readLock().lock(); - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); while (it.hasNext()) { int[] region = it.next(); @@ -724,7 +747,7 @@ public class HiddenColumns // Simply walk along the sequence whilst watching for hidden column // boundaries - Iterator regions = new LocalBoundedHiddenColsIterator(); + Iterator regions = new RegionsIterator(); int hideStart = seq.getLength(); int hideEnd = -1; int visPrev = 0; @@ -941,7 +964,7 @@ public class HiddenColumns try { LOCK.writeLock().lock(); - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); while (it.hasNext()) { int[] region = it.next(); @@ -969,7 +992,7 @@ public class HiddenColumns try { LOCK.writeLock().lock(); - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); while (it.hasNext()) { int[] region = it.next(); @@ -1063,7 +1086,7 @@ public class HiddenColumns // of // preceding visible gaps // update hidden columns at the same time - Iterator regions = new LocalBoundedHiddenColsIterator(); + Iterator regions = new RegionsIterator(); ArrayList newhidden = new ArrayList<>(); int numGapsBefore = 0; @@ -1168,7 +1191,7 @@ public class HiddenColumns { LOCK.readLock().lock(); int hashCode = 1; - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); while (it.hasNext()) { int[] hidden = it.next(); @@ -1220,7 +1243,7 @@ public class HiddenColumns { return; } - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); while (it.hasNext()) { int[] range = it.next(); @@ -1256,7 +1279,7 @@ public class HiddenColumns return new int[] { startPos, endPos }; } - Iterator it = new LocalBoundedHiddenColsIterator(); + Iterator it = new RegionsIterator(); while (it.hasNext()) { int[] range = it.next(); @@ -1304,7 +1327,7 @@ public class HiddenColumns int adjres = adjustForHiddenColumns(res); int[] reveal = null; - Iterator it = new LocalBoundedHiddenColsIterator(adjres - 2, + Iterator it = new RegionsIterator(adjres - 2, adjres + 2); while (it.hasNext()) { @@ -1420,14 +1443,17 @@ public class HiddenColumns /** * A local iterator which iterates over hidden column regions in a range. - * Works with the actual hidden columns collection (so locking before use may - * be required). + * Intended for use ONLY within the HiddenColumns class, because it works + * directly with the hiddenColumns collection without locking (callers should + * lock hiddenColumns). */ - private class LocalBoundedHiddenColsIterator implements Iterator + private class RegionsIterator implements Iterator { - private int start; // start position to iterate from + // start position to iterate from + private int start; - private int end; // end position to iterate to + // end position to iterate to + private int end; // current index in hiddenColumns private int currentPosition = 0; @@ -1435,20 +1461,24 @@ public class HiddenColumns // current column in hiddenColumns private int[] nextRegion = null; - LocalBoundedHiddenColsIterator(int lowerBound, int upperBound) + // Constructor with bounds + RegionsIterator(int lowerBound, int upperBound) { init(lowerBound, upperBound); } - LocalBoundedHiddenColsIterator() + // Unbounded constructor + RegionsIterator() { 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); } } @@ -1461,9 +1491,6 @@ public class HiddenColumns * 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) */ private void init(int lowerBound, int upperBound) { @@ -1512,14 +1539,114 @@ public class HiddenColumns } /** + * A local iterator which reverse iterates over hidden column regions in a + * range. Intended for use ONLY within the HiddenColumns class, because it + * works directly with the hiddenColumns collection without locking (callers + * should lock hiddenColumns). + */ + private class ReverseRegionsIterator implements Iterator + { + // start position to iterate to + private int start; + + // end position to iterate from + private int end; + + // current index in hiddenColumns + private int currentPosition = 0; + + // current column in hiddenColumns + private int[] nextRegion = null; + + // Constructor with bounds + ReverseRegionsIterator(int lowerBound, int upperBound) + { + 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] + * + * @param lowerBound + * lower bound to iterate to + * @param upperBound + * upper bound to iterate from + */ + private void init(int lowerBound, int upperBound) + { + start = lowerBound; + end = upperBound; + + if (hiddenColumns != null) + { + // iterate until a region overlaps with [start,end] + currentPosition = hiddenColumns.size() - 1; + while (currentPosition >= 0 + && hiddenColumns.get(currentPosition)[1] > end) + { + currentPosition--; + } + if (currentPosition >= 0) + { + nextRegion = hiddenColumns.get(currentPosition); + } + } + } + + @Override + public boolean hasNext() + { + return (hiddenColumns != null) && (nextRegion != null) + && (nextRegion[1] >= start); + } + + @Override + public int[] next() + { + int[] region = nextRegion; + currentPosition--; + if (currentPosition >= 0) + { + nextRegion = hiddenColumns.get(currentPosition); + } + else + { + nextRegion = null; + } + return region; + } + + } + + /** * An iterator which iterates over hidden column regions in a range. Works - * with a copy of the hidden columns collection. + * with a copy of the hidden columns collection. Intended to be used by + * callers OUTSIDE of HiddenColumns. */ private class BoundedHiddenColsIterator implements Iterator { - private int start; // start position to iterate from + // start position to iterate from + private int start; - private int end; // end position to iterate to + // end position to iterate to + private int end; // current index in hiddenColumns private int currentPosition = 0; @@ -1530,6 +1657,9 @@ public class HiddenColumns // local copy or reference to hiddenColumns private List localHidden; + /** + * Unbounded constructor + */ BoundedHiddenColsIterator() { if (hiddenColumns != null) -- 1.7.10.2