From: kiramt Date: Tue, 6 Jun 2017 14:44:04 +0000 (+0100) Subject: JAL-2591 Added readwrite locking on HiddenColumns X-Git-Tag: Release_2_10_3b1~183^2~18 X-Git-Url: http://source.jalview.org/gitweb/?p=jalview.git;a=commitdiff_plain;h=defcce0ef74ffc0923b4387bcb5f0d867bf64831 JAL-2591 Added readwrite locking on HiddenColumns --- diff --git a/src/jalview/datamodel/HiddenColumns.java b/src/jalview/datamodel/HiddenColumns.java index f0d99e5..da0b854 100644 --- a/src/jalview/datamodel/HiddenColumns.java +++ b/src/jalview/datamodel/HiddenColumns.java @@ -8,9 +8,12 @@ import java.util.BitSet; import java.util.Collections; import java.util.List; import java.util.Vector; +import java.util.concurrent.locks.ReentrantReadWriteLock; public class HiddenColumns { + private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + /* * list of hidden column [start, end] ranges; the list is maintained in * ascending start column order @@ -35,15 +38,23 @@ public class HiddenColumns */ public int getSize() { - int size = 0; - if (hasHidden()) + try { - for (int[] range : hiddenColumns) + lock.readLock().lock(); + int size = 0; + if (hasHidden()) { - size += range[1] - range[0] + 1; + for (int[] range : hiddenColumns) + { + size += range[1] - range[0] + 1; + } } + return size; + } + finally + { + lock.readLock().unlock(); } - return size; } /** @@ -53,40 +64,56 @@ public class HiddenColumns */ public boolean hasHidden() { - return (hiddenColumns != null) && (!hiddenColumns.isEmpty()); + try + { + lock.readLock().lock(); + return (hiddenColumns != null) && (!hiddenColumns.isEmpty()); + } finally + { + lock.readLock().unlock(); + } + } @Override public boolean equals(Object obj) { - if (!(obj instanceof HiddenColumns)) + try { - return false; - } - HiddenColumns that = (HiddenColumns) obj; + lock.readLock().lock(); - /* - * check hidden columns are either both null, or match - */ - if (this.hiddenColumns == null) - { - return (that.hiddenColumns == null); - } - if (that.hiddenColumns == null - || that.hiddenColumns.size() != this.hiddenColumns.size()) - { - return false; - } - int i = 0; - for (int[] thisRange : hiddenColumns) - { - int[] thatRange = that.hiddenColumns.get(i++); - if (thisRange[0] != thatRange[0] || thisRange[1] != thatRange[1]) + if (!(obj instanceof HiddenColumns)) + { + return false; + } + HiddenColumns that = (HiddenColumns) obj; + + /* + * check hidden columns are either both null, or match + */ + if (this.hiddenColumns == null) + { + return (that.hiddenColumns == null); + } + if (that.hiddenColumns == null + || that.hiddenColumns.size() != this.hiddenColumns.size()) { return false; } + int i = 0; + for (int[] thisRange : hiddenColumns) + { + int[] thatRange = that.hiddenColumns.get(i++); + if (thisRange[0] != thatRange[0] || thisRange[1] != thatRange[1]) + { + return false; + } + } + return true; + } finally + { + lock.readLock().unlock(); } - return true; } /** @@ -98,19 +125,26 @@ public class HiddenColumns */ public int adjustForHiddenColumns(int column) { - int result = column; - if (hiddenColumns != null) + try { - for (int i = 0; i < hiddenColumns.size(); i++) + lock.readLock().lock(); + int result = column; + if (hiddenColumns != null) { - int[] region = hiddenColumns.elementAt(i); - if (result >= region[0]) + for (int i = 0; i < hiddenColumns.size(); i++) { - result += region[1] - region[0] + 1; + int[] region = hiddenColumns.elementAt(i); + if (result >= region[0]) + { + result += region[1] - region[0] + 1; + } } } + return result; + } finally + { + lock.readLock().unlock(); } - return result; } /** @@ -124,42 +158,52 @@ public class HiddenColumns */ public int findColumnPosition(int hiddenColumn) { - int result = hiddenColumn; - if (hiddenColumns != null) + try { - int index = 0; - int[] region; - do + lock.readLock().lock(); + int result = hiddenColumn; + if (hiddenColumns != null) { - region = hiddenColumns.elementAt(index++); - if (hiddenColumn > region[1]) + int index = 0; + int[] region; + do { - result -= region[1] + 1 - region[0]; - } - } while ((hiddenColumn > region[1]) && (index < hiddenColumns.size())); + region = hiddenColumns.elementAt(index++); + if (hiddenColumn > region[1]) + { + result -= region[1] + 1 - region[0]; + } + } while ((hiddenColumn > region[1]) + && (index < hiddenColumns.size())); - if (hiddenColumn >= region[0] && hiddenColumn <= region[1]) - { - // Here the hidden column is within a region, so - // we want to return the position of region[0]-1, adjusted for any - // 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 - - // However, if the region begins at 0 we cannot return region[0]-1 - // just return 0 - if (region[0] == 0) + if (hiddenColumn >= region[0] && hiddenColumn <= region[1]) { - return 0; - } - else - { - return result - (hiddenColumn - region[0] + 1); + // Here the hidden column is within a region, so + // we want to return the position of region[0]-1, adjusted for any + // 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 + + // However, if the region begins at 0 we cannot return region[0]-1 + // just return 0 + if (region[0] == 0) + { + return 0; + } + else + { + return result - (hiddenColumn - region[0] + 1); + } } } + return result; // return the shifted position after removing hidden + // columns. + } finally + { + lock.readLock().unlock(); } - return result; // return the shifted position after removing hidden columns. } /** @@ -175,6 +219,10 @@ public class HiddenColumns */ public int subtractVisibleColumns(int visibleDistance, int startColumn) { + try + { + + lock.readLock().lock(); int distance = visibleDistance; // in case startColumn is in a hidden region, move it to the left @@ -216,6 +264,10 @@ public class HiddenColumns return nextstart - distance; } return start - distance; + } finally + { + lock.readLock().unlock(); + } } @@ -228,28 +280,36 @@ public class HiddenColumns */ public int findHiddenRegionPosition(int hiddenRegion) { - int result = 0; - if (hiddenColumns != null) + try { - int index = 0; - int gaps = 0; - do + lock.readLock().lock(); + int result = 0; + if (hiddenColumns != null) { - int[] region = hiddenColumns.elementAt(index); - if (hiddenRegion == 0) + int index = 0; + int gaps = 0; + do { - return region[0]; - } + int[] region = hiddenColumns.elementAt(index); + if (hiddenRegion == 0) + { + return region[0]; + } - gaps += region[1] + 1 - region[0]; - result = region[1] + 1; - index++; - } while (index <= hiddenRegion); + gaps += region[1] + 1 - region[0]; + result = region[1] + 1; + index++; + } while (index <= hiddenRegion); - result -= gaps; - } + result -= gaps; + } - return result; + return result; + } + finally + { + lock.readLock().unlock(); + } } /** @@ -261,22 +321,29 @@ public class HiddenColumns */ public int getHiddenBoundaryRight(int alPos) { - if (hiddenColumns != null) + try { - int index = 0; - do + lock.readLock().lock(); + if (hiddenColumns != null) { - int[] region = hiddenColumns.elementAt(index); - if (alPos < region[0]) + int index = 0; + do { - return region[0]; - } + int[] region = hiddenColumns.elementAt(index); + if (alPos < region[0]) + { + return region[0]; + } - index++; - } while (index < hiddenColumns.size()); - } + index++; + } while (index < hiddenColumns.size()); + } - return alPos; + return alPos; + } finally + { + lock.readLock().unlock(); + } } @@ -289,6 +356,10 @@ public class HiddenColumns */ public int getHiddenBoundaryLeft(int alPos) { + try + { + lock.readLock().lock(); + if (hiddenColumns != null) { int index = hiddenColumns.size() - 1; @@ -305,7 +376,10 @@ public class HiddenColumns } return alPos; - + } finally + { + lock.readLock().unlock(); + } } /** @@ -318,6 +392,10 @@ public class HiddenColumns */ private int getHiddenIndexLeft(int pos) { + try + { + + lock.readLock().lock(); if (hiddenColumns != null) { int index = hiddenColumns.size() - 1; @@ -334,6 +412,10 @@ public class HiddenColumns } return -1; + } finally + { + lock.readLock().unlock(); + } } @@ -345,9 +427,28 @@ public class HiddenColumns */ public void hideColumns(int start, int end) { + hideColumns(start, end, false); + } + + /** + * Adds the specified column range to the hidden columns + * + * @param start + * @param end + */ + private void hideColumns(int start, int end, boolean alreadyLocked) + { + try + { + + if (!alreadyLocked) + { + lock.writeLock().lock(); + } + if (hiddenColumns == null) { - hiddenColumns = new Vector(); + hiddenColumns = new Vector<>(); } /* @@ -411,10 +512,21 @@ public class HiddenColumns * remaining case is that the new range follows everything else */ hiddenColumns.addElement(new int[] { start, end }); + } finally + { + if (!alreadyLocked) + { + lock.writeLock().unlock(); + } + } } public boolean isVisible(int column) { + try + { + lock.readLock().lock(); + if (hiddenColumns != null) { for (int[] region : hiddenColumns) @@ -427,6 +539,10 @@ public class HiddenColumns } return true; + } finally + { + lock.readLock().unlock(); + } } /** @@ -443,24 +559,33 @@ public class HiddenColumns */ public HiddenColumns(HiddenColumns copy) { - if (copy != null) + try { - if (copy.hiddenColumns != null) + + lock.readLock().lock(); + if (copy != null) { - hiddenColumns = new Vector(copy.hiddenColumns.size()); - for (int i = 0, j = copy.hiddenColumns.size(); i < j; i++) + if (copy.hiddenColumns != null) { - int[] rh, cp; - rh = copy.hiddenColumns.elementAt(i); - if (rh != null) + hiddenColumns = new Vector<>(copy.hiddenColumns.size()); + for (int i = 0, j = copy.hiddenColumns.size(); i < j; i++) { - cp = new int[rh.length]; - System.arraycopy(rh, 0, cp, 0, rh.length); - hiddenColumns.addElement(cp); + int[] rh, cp; + rh = copy.hiddenColumns.elementAt(i); + if (rh != null) + { + cp = new int[rh.length]; + System.arraycopy(rh, 0, cp, 0, rh.length); + hiddenColumns.addElement(cp); + } } } } } + finally + { + lock.readLock().unlock(); + } } /** @@ -474,42 +599,49 @@ public class HiddenColumns public List compensateForEdit(int start, int change, ColumnSelection sel) { - List deletedHiddenColumns = null; - - if (hiddenColumns != null) + try { - deletedHiddenColumns = new ArrayList(); - int hSize = hiddenColumns.size(); - for (int i = 0; i < hSize; i++) + lock.writeLock().lock(); + List deletedHiddenColumns = null; + + if (hiddenColumns != null) { - int[] region = hiddenColumns.elementAt(i); - if (region[0] > start && start + change > region[1]) + deletedHiddenColumns = new ArrayList<>(); + int hSize = hiddenColumns.size(); + for (int i = 0; i < hSize; i++) { - deletedHiddenColumns.add(region); + int[] region = hiddenColumns.elementAt(i); + if (region[0] > start && start + change > region[1]) + { + deletedHiddenColumns.add(region); - hiddenColumns.removeElementAt(i); - i--; - hSize--; - continue; - } + hiddenColumns.removeElementAt(i); + i--; + hSize--; + continue; + } - if (region[0] > start) - { - region[0] -= change; - region[1] -= change; - } + if (region[0] > start) + { + region[0] -= change; + region[1] -= change; + } + + if (region[0] < 0) + { + region[0] = 0; + } - if (region[0] < 0) - { - region[0] = 0; } + this.revealHiddenColumns(0, sel); } - this.revealHiddenColumns(0, sel); + return deletedHiddenColumns; + } finally + { + lock.writeLock().unlock(); } - - return deletedHiddenColumns; } /** @@ -523,34 +655,42 @@ public class HiddenColumns */ public void compensateForDelEdits(int start, int change) { - if (hiddenColumns != null) + try { - for (int i = 0; i < hiddenColumns.size(); i++) + lock.writeLock().lock(); + if (hiddenColumns != null) { - int[] region = hiddenColumns.elementAt(i); - if (region[0] >= start) + for (int i = 0; i < hiddenColumns.size(); i++) { - region[0] -= change; - } - if (region[1] >= start) - { - region[1] -= change; - } - if (region[1] < region[0]) - { - hiddenColumns.removeElementAt(i--); - } + int[] region = hiddenColumns.elementAt(i); + if (region[0] >= start) + { + region[0] -= change; + } + if (region[1] >= start) + { + region[1] -= change; + } + if (region[1] < region[0]) + { + hiddenColumns.removeElementAt(i--); + } - if (region[0] < 0) - { - region[0] = 0; - } - if (region[1] < 0) - { - region[1] = 0; + if (region[0] < 0) + { + region[0] = 0; + } + if (region[1] < 0) + { + region[1] = 0; + } } } } + finally + { + lock.writeLock().unlock(); + } } /** @@ -565,111 +705,127 @@ public class HiddenColumns */ public int[] getVisibleContigs(int start, int end) { - if (hiddenColumns != null && hiddenColumns.size() > 0) + try { - List visiblecontigs = new ArrayList(); - List regions = getHiddenRegions(); + lock.readLock().lock(); + if (hiddenColumns != null && hiddenColumns.size() > 0) + { + List visiblecontigs = new ArrayList<>(); + List regions = getHiddenRegions(); - int vstart = start; - int[] region; - int hideStart, hideEnd; + int vstart = start; + int[] region; + int hideStart, hideEnd; - for (int j = 0; vstart < end && j < regions.size(); j++) - { - region = regions.get(j); - hideStart = region[0]; - hideEnd = region[1]; + for (int j = 0; vstart < end && j < regions.size(); j++) + { + region = regions.get(j); + hideStart = region[0]; + hideEnd = region[1]; + + if (hideEnd < vstart) + { + continue; + } + if (hideStart > vstart) + { + visiblecontigs.add(new int[] { vstart, hideStart - 1 }); + } + vstart = hideEnd + 1; + } - if (hideEnd < vstart) + if (vstart < end) { - continue; + visiblecontigs.add(new int[] { vstart, end - 1 }); } - if (hideStart > vstart) + int[] vcontigs = new int[visiblecontigs.size() * 2]; + for (int i = 0, j = visiblecontigs.size(); i < j; i++) { - visiblecontigs.add(new int[] { vstart, hideStart - 1 }); + int[] vc = visiblecontigs.get(i); + visiblecontigs.set(i, null); + vcontigs[i * 2] = vc[0]; + vcontigs[i * 2 + 1] = vc[1]; } - vstart = hideEnd + 1; - } - - if (vstart < end) - { - visiblecontigs.add(new int[] { vstart, end - 1 }); + visiblecontigs.clear(); + return vcontigs; } - int[] vcontigs = new int[visiblecontigs.size() * 2]; - for (int i = 0, j = visiblecontigs.size(); i < j; i++) + else { - int[] vc = visiblecontigs.get(i); - visiblecontigs.set(i, null); - vcontigs[i * 2] = vc[0]; - vcontigs[i * 2 + 1] = vc[1]; + return new int[] { start, end - 1 }; } - visiblecontigs.clear(); - return vcontigs; } - else + finally { - return new int[] { start, end - 1 }; + lock.readLock().unlock(); } } public String[] getVisibleSequenceStrings(int start, int end, SequenceI[] seqs) { - int i, iSize = seqs.length; - String selections[] = new String[iSize]; - if (hiddenColumns != null && hiddenColumns.size() > 0) + try { - for (i = 0; i < iSize; i++) + lock.readLock().lock(); + int i, iSize = seqs.length; + String selections[] = new String[iSize]; + if (hiddenColumns != null && hiddenColumns.size() > 0) { - StringBuffer visibleSeq = new StringBuffer(); - List regions = getHiddenRegions(); - - int blockStart = start, blockEnd = end; - int[] region; - int hideStart, hideEnd; - - for (int j = 0; j < regions.size(); j++) + for (i = 0; i < iSize; i++) { - region = regions.get(j); - hideStart = region[0]; - hideEnd = region[1]; + StringBuffer visibleSeq = new StringBuffer(); + List regions = getHiddenRegions(); - if (hideStart < start) + int blockStart = start, blockEnd = end; + int[] region; + int hideStart, hideEnd; + + for (int j = 0; j < regions.size(); j++) { - continue; - } + region = regions.get(j); + hideStart = region[0]; + hideEnd = region[1]; - blockStart = Math.min(blockStart, hideEnd + 1); - blockEnd = Math.min(blockEnd, hideStart); + if (hideStart < start) + { + continue; + } - if (blockStart > blockEnd) - { - break; + blockStart = Math.min(blockStart, hideEnd + 1); + blockEnd = Math.min(blockEnd, hideStart); + + if (blockStart > blockEnd) + { + break; + } + + visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd)); + + blockStart = hideEnd + 1; + blockEnd = end; } - visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd)); + if (end > blockStart) + { + visibleSeq.append(seqs[i].getSequence(blockStart, end)); + } - blockStart = hideEnd + 1; - blockEnd = end; + selections[i] = visibleSeq.toString(); } - - if (end > blockStart) + } + else + { + for (i = 0; i < iSize; i++) { - visibleSeq.append(seqs[i].getSequence(blockStart, end)); + selections[i] = seqs[i].getSequenceAsString(start, end); } - - selections[i] = visibleSeq.toString(); } + + return selections; } - else + finally { - for (i = 0; i < iSize; i++) - { - selections[i] = seqs[i].getSequenceAsString(start, end); - } + lock.readLock().unlock(); } - - return selections; } /** @@ -684,70 +840,79 @@ public class HiddenColumns */ public int[] locateVisibleBoundsOfSequence(SequenceI seq) { - int fpos = seq.getStart(), lpos = seq.getEnd(); - int start = 0; - - if (hiddenColumns == null || hiddenColumns.size() == 0) + try { - int ifpos = seq.findIndex(fpos) - 1, ilpos = seq.findIndex(lpos) - 1; - return new int[] { ifpos, ilpos, fpos, lpos, ifpos, ilpos }; - } + lock.readLock().lock(); + int fpos = seq.getStart(), lpos = seq.getEnd(); + int start = 0; - // Simply walk along the sequence whilst watching for hidden column - // boundaries - List regions = getHiddenRegions(); - int spos = fpos, lastvispos = -1, rcount = 0, hideStart = seq - .getLength(), hideEnd = -1; - int visPrev = 0, visNext = 0, firstP = -1, lastP = -1; - boolean foundStart = false; - for (int p = 0, pLen = seq.getLength(); spos <= seq.getEnd() - && p < pLen; p++) - { - if (!Comparison.isGap(seq.getCharAt(p))) + if (hiddenColumns == null || hiddenColumns.size() == 0) { - // keep track of first/last column - // containing sequence data regardless of visibility - if (firstP == -1) - { - firstP = p; - } - lastP = p; - // update hidden region start/end - while (hideEnd < p && rcount < regions.size()) - { - int[] region = regions.get(rcount++); - visPrev = visNext; - visNext += region[0] - visPrev; - hideStart = region[0]; - hideEnd = region[1]; - } - if (hideEnd < p) - { - hideStart = seq.getLength(); - } - // update visible boundary for sequence - if (p < hideStart) + int ifpos = seq.findIndex(fpos) - 1, + ilpos = seq.findIndex(lpos) - 1; + return new int[] { ifpos, ilpos, fpos, lpos, ifpos, ilpos }; + } + + // Simply walk along the sequence whilst watching for hidden column + // boundaries + List regions = getHiddenRegions(); + int spos = fpos, lastvispos = -1, rcount = 0, + hideStart = seq.getLength(), hideEnd = -1; + int visPrev = 0, visNext = 0, firstP = -1, lastP = -1; + boolean foundStart = false; + for (int p = 0, pLen = seq.getLength(); spos <= seq.getEnd() + && p < pLen; p++) + { + if (!Comparison.isGap(seq.getCharAt(p))) { - if (!foundStart) + // keep track of first/last column + // containing sequence data regardless of visibility + if (firstP == -1) + { + firstP = p; + } + lastP = p; + // update hidden region start/end + while (hideEnd < p && rcount < regions.size()) + { + int[] region = regions.get(rcount++); + visPrev = visNext; + visNext += region[0] - visPrev; + hideStart = region[0]; + hideEnd = region[1]; + } + if (hideEnd < p) { - fpos = spos; - start = p; - foundStart = true; + hideStart = seq.getLength(); } - lastvispos = p; - lpos = spos; + // update visible boundary for sequence + if (p < hideStart) + { + if (!foundStart) + { + fpos = spos; + start = p; + foundStart = true; + } + lastvispos = p; + lpos = spos; + } + // look for next sequence position + spos++; } - // look for next sequence position - spos++; } + if (foundStart) + { + return new int[] { findColumnPosition(start), + findColumnPosition(lastvispos), fpos, lpos, firstP, lastP }; + } + // otherwise, sequence was completely hidden + return new int[] { visPrev, visNext, 0, 0, firstP, lastP }; } - if (foundStart) + finally { - return new int[] { findColumnPosition(start), - findColumnPosition(lastvispos), fpos, lpos, firstP, lastP }; + lock.readLock().unlock(); } - // otherwise, sequence was completely hidden - return new int[] { visPrev, visNext, 0, 0, firstP, lastP }; } /** @@ -775,88 +940,97 @@ public class HiddenColumns public void makeVisibleAnnotation(int start, int end, AlignmentAnnotation alignmentAnnotation) { - if (alignmentAnnotation.annotations == null) - { - return; - } - if (start == end && end == -1) + try { - start = 0; - end = alignmentAnnotation.annotations.length; - } - if (hiddenColumns != null && hiddenColumns.size() > 0) - { - // then mangle the alignmentAnnotation annotation array - Vector annels = new Vector(); - Annotation[] els = null; - List regions = getHiddenRegions(); - int blockStart = start, blockEnd = end; - int[] region; - int hideStart, hideEnd, w = 0; - - for (int j = 0; j < regions.size(); j++) + lock.readLock().lock(); + if (alignmentAnnotation.annotations == null) { - region = regions.get(j); - hideStart = region[0]; - hideEnd = region[1]; + return; + } + if (start == end && end == -1) + { + start = 0; + end = alignmentAnnotation.annotations.length; + } + if (hiddenColumns != null && hiddenColumns.size() > 0) + { + // then mangle the alignmentAnnotation annotation array + Vector annels = new Vector<>(); + Annotation[] els = null; + List regions = getHiddenRegions(); + int blockStart = start, blockEnd = end; + int[] region; + int hideStart, hideEnd, w = 0; - if (hideStart < start) + for (int j = 0; j < regions.size(); j++) { - continue; - } + region = regions.get(j); + hideStart = region[0]; + hideEnd = region[1]; - blockStart = Math.min(blockStart, hideEnd + 1); - blockEnd = Math.min(blockEnd, hideStart); + if (hideStart < start) + { + continue; + } - if (blockStart > blockEnd) - { - break; - } + blockStart = Math.min(blockStart, hideEnd + 1); + blockEnd = Math.min(blockEnd, hideStart); - annels.addElement(els = new Annotation[blockEnd - blockStart]); - System.arraycopy(alignmentAnnotation.annotations, blockStart, els, - 0, els.length); - w += els.length; - blockStart = hideEnd + 1; - blockEnd = end; - } + if (blockStart > blockEnd) + { + break; + } - if (end > blockStart) - { - annels.addElement(els = new Annotation[end - blockStart + 1]); - if ((els.length + blockStart) <= alignmentAnnotation.annotations.length) + annels.addElement(els = new Annotation[blockEnd - blockStart]); + System.arraycopy(alignmentAnnotation.annotations, blockStart, els, + 0, els.length); + w += els.length; + blockStart = hideEnd + 1; + blockEnd = end; + } + + if (end > blockStart) { - // copy just the visible segment of the annotation row - System.arraycopy(alignmentAnnotation.annotations, blockStart, - els, 0, els.length); + annels.addElement(els = new Annotation[end - blockStart + 1]); + if ((els.length + + blockStart) <= alignmentAnnotation.annotations.length) + { + // copy just the visible segment of the annotation row + System.arraycopy(alignmentAnnotation.annotations, blockStart, + els, 0, els.length); + } + else + { + // copy to the end of the annotation row + System.arraycopy(alignmentAnnotation.annotations, blockStart, + els, 0, + (alignmentAnnotation.annotations.length - blockStart)); + } + w += els.length; } - else + if (w == 0) { - // copy to the end of the annotation row - System.arraycopy(alignmentAnnotation.annotations, blockStart, - els, 0, - (alignmentAnnotation.annotations.length - blockStart)); + return; } - w += els.length; - } - if (w == 0) - { - return; - } - alignmentAnnotation.annotations = new Annotation[w]; - w = 0; + alignmentAnnotation.annotations = new Annotation[w]; + w = 0; - for (Annotation[] chnk : annels) + for (Annotation[] chnk : annels) + { + System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w, + chnk.length); + w += chnk.length; + } + } + else { - System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w, - chnk.length); - w += chnk.length; + alignmentAnnotation.restrict(start, end); } } - else + finally { - alignmentAnnotation.restrict(start, end); + lock.readLock().unlock(); } } @@ -866,7 +1040,14 @@ public class HiddenColumns */ public boolean hasHiddenColumns() { - return hiddenColumns != null && hiddenColumns.size() > 0; + try + { + lock.readLock().lock(); + return hiddenColumns != null && hiddenColumns.size() > 0; + } finally + { + lock.readLock().unlock(); + } } /** @@ -875,7 +1056,14 @@ public class HiddenColumns */ public boolean hasManyHiddenColumns() { - return hiddenColumns != null && hiddenColumns.size() > 1; + try + { + lock.readLock().lock(); + return hiddenColumns != null && hiddenColumns.size() > 1; + } finally + { + lock.readLock().unlock(); + } } /** @@ -886,10 +1074,17 @@ public class HiddenColumns */ public void hideInsertionsFor(SequenceI sr) { - List inserts = sr.getInsertions(); - for (int[] r : inserts) + try { - hideColumns(r[0], r[1]); + lock.writeLock().lock(); + List inserts = sr.getInsertions(); + for (int[] r : inserts) + { + hideColumns(r[0], r[1], true); + } + } finally + { + lock.writeLock().unlock(); } } @@ -898,19 +1093,27 @@ public class HiddenColumns */ public void revealAllHiddenColumns(ColumnSelection sel) { - if (hiddenColumns != null) + try { - for (int i = 0; i < hiddenColumns.size(); i++) + lock.writeLock().lock(); + if (hiddenColumns != null) { - int[] region = hiddenColumns.elementAt(i); - for (int j = region[0]; j < region[1] + 1; j++) + for (int i = 0; i < hiddenColumns.size(); i++) { - sel.addElement(j); + int[] region = hiddenColumns.elementAt(i); + for (int j = region[0]; j < region[1] + 1; j++) + { + sel.addElement(j); + } } } - } - hiddenColumns = null; + hiddenColumns = null; + } + finally + { + lock.writeLock().unlock(); + } } /** @@ -921,23 +1124,31 @@ public class HiddenColumns */ public void revealHiddenColumns(int start, ColumnSelection sel) { - for (int i = 0; i < hiddenColumns.size(); i++) + try { - int[] region = hiddenColumns.elementAt(i); - if (start == region[0]) + lock.writeLock().lock(); + for (int i = 0; i < hiddenColumns.size(); i++) { - for (int j = region[0]; j < region[1] + 1; j++) + int[] region = hiddenColumns.elementAt(i); + if (start == region[0]) { - sel.addElement(j); - } + for (int j = region[0]; j < region[1] + 1; j++) + { + sel.addElement(j); + } - hiddenColumns.removeElement(region); - break; + hiddenColumns.removeElement(region); + break; + } + } + if (hiddenColumns.size() == 0) + { + hiddenColumns = null; } } - if (hiddenColumns.size() == 0) + finally { - hiddenColumns = null; + lock.writeLock().unlock(); } } @@ -1044,15 +1255,23 @@ public class HiddenColumns */ public void pruneDeletions(List shifts) { - // delete any intervals intersecting. - if (hiddenColumns != null) + try { - pruneIntervalVector(shifts, hiddenColumns); - if (hiddenColumns != null && hiddenColumns.size() == 0) + lock.writeLock().lock(); + // delete any intervals intersecting. + if (hiddenColumns != null) { - hiddenColumns = null; + pruneIntervalVector(shifts, hiddenColumns); + if (hiddenColumns != null && hiddenColumns.size() == 0) + { + hiddenColumns = null; + } } } + finally + { + lock.writeLock().unlock(); + } } /** @@ -1251,16 +1470,24 @@ public class HiddenColumns @Override public int hashCode() { - int hashCode = 1; - if (hiddenColumns != null) + try { - for (int[] hidden : hiddenColumns) + lock.readLock().lock(); + int hashCode = 1; + if (hiddenColumns != null) { - hashCode = 31 * hashCode + hidden[0]; - hashCode = 31 * hashCode + hidden[1]; + for (int[] hidden : hiddenColumns) + { + hashCode = 31 * hashCode + hidden[0]; + hashCode = 31 * hashCode + hidden[1]; + } } + return hashCode; + } + finally + { + lock.readLock().unlock(); } - return hashCode; } /** @@ -1271,11 +1498,19 @@ public class HiddenColumns */ public void hideMarkedBits(BitSet inserts) { - for (int firstSet = inserts.nextSetBit(0), lastSet = 0; firstSet >= 0; firstSet = inserts - .nextSetBit(lastSet)) + try { - lastSet = inserts.nextClearBit(firstSet); - hideColumns(firstSet, lastSet - 1); + lock.writeLock().lock(); + for (int firstSet = inserts + .nextSetBit(0), lastSet = 0; firstSet >= 0; firstSet = inserts + .nextSetBit(lastSet)) + { + lastSet = inserts.nextClearBit(firstSet); + hideColumns(firstSet, lastSet - 1, true); + } + } finally + { + lock.writeLock().unlock(); } } @@ -1286,13 +1521,21 @@ public class HiddenColumns */ public void markHiddenRegions(BitSet inserts) { - if (hiddenColumns == null) + try { - return; + lock.readLock().lock(); + if (hiddenColumns == null) + { + return; + } + for (int[] range : hiddenColumns) + { + inserts.set(range[0], range[1] + 1); + } } - for (int[] range : hiddenColumns) + finally { - inserts.set(range[0], range[1] + 1); + lock.readLock().unlock(); } }