X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2FHiddenColumns.java;h=c0a43eea64ba09df70ed8e5686e58334ecb772f0;hb=4cc3017f070e0bc1b291d9cfaf572b1c9c5e76d3;hp=596631298fa53be6d9582744334fe8a81c009043;hpb=fd8dc2879b13709703b57dd7ed4b3754b253e12f;p=jalview.git diff --git a/src/jalview/datamodel/HiddenColumns.java b/src/jalview/datamodel/HiddenColumns.java index 5966312..c0a43ee 100644 --- a/src/jalview/datamodel/HiddenColumns.java +++ b/src/jalview/datamodel/HiddenColumns.java @@ -33,19 +33,51 @@ 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 */ - private Vector hiddenColumns; + private ArrayList hiddenColumns; + + /** + * Constructor + */ + public HiddenColumns() + { + } + + /** + * Copy constructor + * + * @param copy + */ + public HiddenColumns(HiddenColumns copy) + { + try + { + LOCK.writeLock().lock(); + if (copy != null) + { + if (copy.hiddenColumns != null) + { + hiddenColumns = copy.copyHiddenRegionsToArrayList(); + } + } + } finally + { + LOCK.writeLock().unlock(); + } + } /** - * This Method is used to return all the HiddenColumn regions + * This method is used to return all the HiddenColumn regions and is intended + * to remain private. External callers which need a copy of the regions can + * call getHiddenColumnsCopyAsList. * * @return empty list or List of hidden column intervals */ - public List getHiddenRegions() + private List getHiddenRegions() { return hiddenColumns == null ? Collections. emptyList() : hiddenColumns; @@ -95,7 +127,7 @@ public class HiddenColumns { LOCK.readLock().lock(); int size = 0; - if (hasHidden()) + if (hasHiddenColumns()) { for (int[] range : hiddenColumns) { @@ -103,29 +135,10 @@ public class HiddenColumns } } return size; - } - finally - { - LOCK.readLock().unlock(); - } - } - - /** - * Answers if there are any hidden columns - * - * @return true if there are hidden columns - */ - public boolean hasHidden() - { - try - { - LOCK.readLock().lock(); - return (hiddenColumns != null) && (!hiddenColumns.isEmpty()); } finally { LOCK.readLock().unlock(); } - } @Override @@ -186,7 +199,7 @@ public class HiddenColumns { for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (result >= region[0]) { result += region[1] - region[0] + 1; @@ -221,7 +234,7 @@ public class HiddenColumns int[] region; do { - region = hiddenColumns.elementAt(index++); + region = hiddenColumns.get(index++); if (hiddenColumn > region[1]) { result -= region[1] + 1 - region[0]; @@ -276,47 +289,47 @@ public class HiddenColumns { LOCK.readLock().lock(); - int distance = visibleDistance; + int distance = visibleDistance; - // in case startColumn is in a hidden region, move it to the left - int start = adjustForHiddenColumns(findColumnPosition(startColumn)); + // 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; - } + // 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; + } - // walk backwards through the alignment subtracting the counts of visible - // columns from distance - int[] region; - int gap = 0; - int nextstart = 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)) - { - // subtract the gap to right of region from distance - distance -= gap; - start = nextstart; + while ((index > -1) && (distance - gap > 0)) + { + // subtract the gap to right of region from distance + distance -= gap; + start = nextstart; - // calculate the next gap - region = hiddenColumns.get(index); - gap = start - region[1]; + // calculate the next gap + region = hiddenColumns.get(index); + gap = start - region[1]; - // set start to just to left of current region - nextstart = region[0] - 1; - index--; - } + // set start to just to left of current region + nextstart = region[0] - 1; + index--; + } - if (distance - gap > 0) - { - // fell out of loop because there are no more hidden regions - distance -= gap; - return nextstart - distance; - } - return start - distance; + 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(); @@ -340,7 +353,7 @@ public class HiddenColumns { positions = new ArrayList<>(hiddenColumns.size()); - positions.add(hiddenColumns.elementAt(0)[0]); + positions.add(hiddenColumns.get(0)[0]); for (int i = 1; i < hiddenColumns.size(); ++i) { @@ -351,7 +364,7 @@ public class HiddenColumns int gaps = 0; do { - int[] region = hiddenColumns.elementAt(index); + int[] region = hiddenColumns.get(index); gaps += region[1] + 1 - region[0]; result = region[1] + 1; index++; @@ -368,8 +381,7 @@ public class HiddenColumns } return positions; - } - finally + } finally { LOCK.readLock().unlock(); } @@ -392,7 +404,7 @@ public class HiddenColumns int index = 0; do { - int[] region = hiddenColumns.elementAt(index); + int[] region = hiddenColumns.get(index); if (alPos < region[0]) { return region[0]; @@ -423,22 +435,22 @@ public class HiddenColumns { LOCK.readLock().lock(); - if (hiddenColumns != null) - { - int index = hiddenColumns.size() - 1; - do + if (hiddenColumns != null) { - int[] region = hiddenColumns.elementAt(index); - if (alPos > region[1]) + int index = hiddenColumns.size() - 1; + do { - return region[1]; - } + int[] region = hiddenColumns.get(index); + if (alPos > region[1]) + { + return region[1]; + } - index--; - } while (index > -1); - } + index--; + } while (index > -1); + } - return alPos; + return alPos; } finally { LOCK.readLock().unlock(); @@ -459,22 +471,22 @@ public class HiddenColumns { LOCK.readLock().lock(); - if (hiddenColumns != null) - { - int index = hiddenColumns.size() - 1; - do + if (hiddenColumns != null) { - int[] region = hiddenColumns.elementAt(index); - if (pos > region[1]) + int index = hiddenColumns.size() - 1; + do { - return index; - } + int[] region = hiddenColumns.get(index); + if (pos > region[1]) + { + return index; + } - index--; - } while (index > -1); - } + index--; + } while (index > -1); + } - return -1; + return -1; } finally { LOCK.readLock().unlock(); @@ -490,28 +502,23 @@ 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) - { + boolean wasAlreadyLocked = false; try { - - if (!alreadyLocked) + // check if the write lock was already locked by this thread, + // as this method can be called internally in loops within HiddenColumns + if (!LOCK.isWriteLockedByCurrentThread()) { LOCK.writeLock().lock(); } + else + { + wasAlreadyLocked = true; + } if (hiddenColumns == null) { - hiddenColumns = new Vector<>(); + hiddenColumns = new ArrayList<>(); } /* @@ -520,14 +527,14 @@ public class HiddenColumns */ for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (end < region[0] - 1) { /* * insert discontiguous preceding range */ - hiddenColumns.insertElementAt(new int[] { start, end }, i); + hiddenColumns.add(i, new int[] { start, end }); return; } @@ -569,15 +576,15 @@ public class HiddenColumns } return; } - } + } - /* - * remaining case is that the new range follows everything else - */ - hiddenColumns.addElement(new int[] { start, end }); + /* + * remaining case is that the new range follows everything else + */ + hiddenColumns.add(new int[] { start, end }); } finally { - if (!alreadyLocked) + if (!wasAlreadyLocked) { LOCK.writeLock().unlock(); } @@ -590,82 +597,38 @@ public class HiddenColumns { LOCK.readLock().lock(); - if (hiddenColumns != null) - { - for (int[] region : hiddenColumns) + if (hiddenColumns != null) { - if (column >= region[0] && column <= region[1]) + for (int[] region : hiddenColumns) { - return false; + if (column >= region[0] && column <= region[1]) + { + return false; + } } } - } - return true; + return true; } finally { LOCK.readLock().unlock(); } } - /** - * ColumnSelection - */ - public HiddenColumns() - { - } - - /** - * Copy constructor - * - * @param copy - */ - public HiddenColumns(HiddenColumns copy) + private ArrayList copyHiddenRegionsToArrayList() { - try - { - - LOCK.readLock().lock(); - if (copy != null) - { - if (copy.hiddenColumns != null) - { - hiddenColumns = copy.copyHiddenRegions(); - } - } - } - finally + int size = 0; + if (hiddenColumns != null) { - LOCK.readLock().unlock(); + size = hiddenColumns.size(); } - } + ArrayList copy = new ArrayList<>(size); - private Vector copyHiddenRegions() - { - Vector copy = new Vector<>(hiddenColumns.size()); - for (int i = 0, j = hiddenColumns.size(); i < j; i++) + for (int i = 0, j = size; i < j; i++) { int[] rh; int[] cp; - rh = hiddenColumns.elementAt(i); - if (rh != null) - { - cp = new int[rh.length]; - System.arraycopy(rh, 0, cp, 0, rh.length); - copy.addElement(cp); - } - } - return copy; - } - - private ArrayList copyHiddenRegionsToArrayList() - { - ArrayList copy = new ArrayList<>(hiddenColumns.size()); - for (int i = 0, j = hiddenColumns.size(); i < j; i++) - { - int[] rh; - int[] cp; - rh = hiddenColumns.elementAt(i); + rh = hiddenColumns.get(i); if (rh != null) { cp = new int[rh.length]; @@ -673,26 +636,8 @@ public class HiddenColumns copy.add(cp); } } - return copy; - } - /** - * Returns a copy of the vector of hidden regions, as a vector. Before using - * this method please consider if you really need access to the hidden regions - * - a new (or existing!) method on HiddenColumns might be more appropriate. - * - * @return hidden regions as vector of [start,end] pairs - */ - public Vector getHiddenColumnsCopy() - { - try - { - LOCK.readLock().lock(); - return copyHiddenRegions(); - } finally - { - LOCK.readLock().unlock(); - } + return copy; } /** @@ -703,7 +648,7 @@ public class HiddenColumns * * @return hidden regions as an ArrayList of [start,end] pairs */ - public ArrayList getHiddenColumnsCopyAsList() + public ArrayList getHiddenColumnsCopy() { try { @@ -737,12 +682,12 @@ public class HiddenColumns int hSize = hiddenColumns.size(); for (int i = 0; i < hSize; i++) { - int[] region = hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (region[0] > start && start + change > region[1]) { deletedHiddenColumns.add(region); - hiddenColumns.removeElementAt(i); + hiddenColumns.remove(i); i--; hSize--; continue; @@ -789,7 +734,7 @@ public class HiddenColumns { for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (region[0] >= start) { region[0] -= change; @@ -800,7 +745,7 @@ public class HiddenColumns } if (region[1] < region[0]) { - hiddenColumns.removeElementAt(i--); + hiddenColumns.remove(i--); } if (region[0] < 0) @@ -813,8 +758,7 @@ public class HiddenColumns } } } - } - finally + } finally { LOCK.writeLock().unlock(); } @@ -881,8 +825,7 @@ public class HiddenColumns { return new int[] { start, end - 1 }; } - } - finally + } finally { LOCK.readLock().unlock(); } @@ -895,7 +838,7 @@ public class HiddenColumns { LOCK.readLock().lock(); int iSize = seqs.length; - String selections[] = new String[iSize]; + String[] selections = new String[iSize]; if (hiddenColumns != null && hiddenColumns.size() > 0) { for (int i = 0; i < iSize; i++) @@ -951,8 +894,7 @@ public class HiddenColumns } return selections; - } - finally + } finally { LOCK.readLock().unlock(); } @@ -1045,8 +987,7 @@ public class HiddenColumns } // otherwise, sequence was completely hidden return new int[] { visPrev, visNext, 0, 0, firstP, lastP }; - } - finally + } finally { LOCK.readLock().unlock(); } @@ -1167,8 +1108,7 @@ public class HiddenColumns { alignmentAnnotation.restrict(start, end); } - } - finally + } finally { LOCK.readLock().unlock(); } @@ -1220,7 +1160,7 @@ public class HiddenColumns List inserts = sr.getInsertions(); for (int[] r : inserts) { - hideColumns(r[0], r[1], true); + hideColumns(r[0], r[1]); } } finally { @@ -1240,7 +1180,7 @@ public class HiddenColumns { for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); for (int j = region[0]; j < region[1] + 1; j++) { sel.addElement(j); @@ -1249,8 +1189,7 @@ public class HiddenColumns } hiddenColumns = null; - } - finally + } finally { LOCK.writeLock().unlock(); } @@ -1269,7 +1208,7 @@ public class HiddenColumns LOCK.writeLock().lock(); for (int i = 0; i < hiddenColumns.size(); i++) { - int[] region = hiddenColumns.elementAt(i); + int[] region = hiddenColumns.get(i); if (start == region[0]) { for (int j = region[0]; j < region[1] + 1; j++) @@ -1277,7 +1216,7 @@ public class HiddenColumns sel.addElement(j); } - hiddenColumns.removeElement(region); + hiddenColumns.remove(region); break; } } @@ -1285,8 +1224,7 @@ public class HiddenColumns { hiddenColumns = null; } - } - finally + } finally { LOCK.writeLock().unlock(); } @@ -1300,16 +1238,16 @@ public class HiddenColumns * @param intervals * @return */ - private boolean pruneIntervalVector(final List shifts, - Vector intervals) + private boolean pruneIntervalList(final List shifts, + ArrayList intervals) { boolean pruned = false; int i = 0; int j = intervals.size() - 1; int s = 0; int t = shifts.size() - 1; - int hr[] = intervals.elementAt(i); - int sr[] = shifts.get(s); + int[] hr = intervals.get(i); + int[] sr = shifts.get(s); while (i <= j && s <= t) { boolean trailinghn = hr[1] >= sr[0]; @@ -1317,7 +1255,7 @@ public class HiddenColumns { if (i < j) { - hr = intervals.elementAt(++i); + hr = intervals.get(++i); } else { @@ -1345,12 +1283,12 @@ public class HiddenColumns { if (trailinghc) { // deleted hidden region. - intervals.removeElementAt(i); + intervals.remove(i); pruned = true; j--; if (i <= j) { - hr = intervals.elementAt(i); + hr = intervals.get(i); } continue; } @@ -1404,14 +1342,13 @@ public class HiddenColumns // delete any intervals intersecting. if (hiddenColumns != null) { - pruneIntervalVector(shifts, hiddenColumns); + pruneIntervalList(shifts, hiddenColumns); if (hiddenColumns != null && hiddenColumns.size() == 0) { hiddenColumns = null; } } - } - finally + } finally { LOCK.writeLock().unlock(); } @@ -1460,8 +1397,7 @@ public class HiddenColumns // recover mapping between sequence's non-gap positions and positions // mapping to view. pruneDeletions(ShiftList.parseMap(origseq.gapMap())); - int[] viscontigs = al.getHiddenColumns().getVisibleContigs(0, - profileseq.getLength()); + int[] viscontigs = getVisibleContigs(0, profileseq.getLength()); int spos = 0; int offset = 0; @@ -1510,9 +1446,8 @@ public class HiddenColumns } else { - al.getSequenceAt(s).setSequence( - sq.substring(0, spos + offset) + sb.toString() - + sq.substring(spos + offset)); + al.getSequenceAt(s).setSequence(sq.substring(0, spos + offset) + + sb.toString() + sq.substring(spos + offset)); } } } @@ -1524,7 +1459,8 @@ public class HiddenColumns { // pad the final region with gaps. StringBuffer sb = new StringBuffer(); - for (int s = 0, ns = profileseq.getLength() - spos - offset; s < ns; s++) + for (int s = 0, ns = profileseq.getLength() - spos + - offset; s < ns; s++) { sb.append(gc); } @@ -1626,8 +1562,7 @@ public class HiddenColumns } } return hashCode; - } - finally + } finally { LOCK.readLock().unlock(); } @@ -1649,7 +1584,7 @@ public class HiddenColumns .nextSetBit(lastSet)) { lastSet = inserts.nextClearBit(firstSet); - hideColumns(firstSet, lastSet - 1, true); + hideColumns(firstSet, lastSet - 1); } } finally { @@ -1675,8 +1610,7 @@ public class HiddenColumns { inserts.set(range[0], range[1] + 1); } - } - finally + } finally { LOCK.readLock().unlock(); }