From: kiramt Date: Mon, 2 Oct 2017 12:58:45 +0000 (+0100) Subject: JAL-2674 iterator for visible blocks with absolute positions X-Git-Tag: Release_2_10_4~55^2~1^2~93 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=6bf9f7b283833371960b59d7cf6c893b4169eff7;p=jalview.git JAL-2674 iterator for visible blocks with absolute positions --- diff --git a/src/jalview/datamodel/HiddenColumns.java b/src/jalview/datamodel/HiddenColumns.java index aa34461..b6e6ce3 100644 --- a/src/jalview/datamodel/HiddenColumns.java +++ b/src/jalview/datamodel/HiddenColumns.java @@ -660,26 +660,12 @@ public class HiddenColumns { StringBuffer visibleSeq = new StringBuffer(); - int blockStart = start; - int blockEnd = end; - - Iterator regions = new BoundedHiddenColsIterator(start, + Iterator blocks = new VisibleBlocksIterator(start, end, false); - while (regions.hasNext()) - { - int[] region = regions.next(); - blockStart = Math.min(blockStart, region[1] + 1); - blockEnd = Math.min(blockEnd, region[0]); - - visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd)); - - blockStart = region[1] + 1; - blockEnd = end; - } - - if (end > blockStart) + while (blocks.hasNext()) { - visibleSeq.append(seqs[i].getSequence(blockStart, end)); + int[] block = blocks.next(); + visibleSeq.append(seqs[i].getSequence(block[0], block[1])); } selections[i] = visibleSeq.toString(); @@ -845,48 +831,45 @@ public class HiddenColumns // mangle the alignmentAnnotation annotation array Vector annels = new Vector<>(); Annotation[] els = null; - int blockStart = start; - int blockEnd = end; - int w = 0; - Iterator regions = new BoundedHiddenColsIterator(start, end, + int w = 0; + + Iterator blocks = new VisibleBlocksIterator(start, end, false); - while (regions.hasNext()) - { - int[] region = regions.next(); - blockStart = Math.min(blockStart, region[1] + 1); - blockEnd = Math.min(blockEnd, region[0]); - - els = new Annotation[blockEnd - blockStart]; - annels.addElement(els); - System.arraycopy(alignmentAnnotation.annotations, blockStart, els, 0, - els.length); - w += els.length; - - blockStart = region[1] + 1; - blockEnd = end; - } - - if (end > blockStart) + int copylength; + int annotationLength; + while (blocks.hasNext()) { - els = new Annotation[end - blockStart + 1]; - annels.addElement(els); - if ((els.length - + blockStart) <= alignmentAnnotation.annotations.length) + int[] block = blocks.next(); + + if (blocks.hasNext()) { + annotationLength = block[1] - block[0]; // copy just the visible segment of the annotation row - System.arraycopy(alignmentAnnotation.annotations, blockStart, els, - 0, els.length); + copylength = annotationLength; } else { - // copy to the end of the annotation row - System.arraycopy(alignmentAnnotation.annotations, blockStart, els, - 0, (alignmentAnnotation.annotations.length - blockStart)); + annotationLength = block[1] - block[0] + 1; + if (annotationLength + block[0] <= alignmentAnnotation.annotations.length) + { + // copy just the visible segment of the annotation row + copylength = annotationLength; + } + else + { + // copy to the end of the annotation row + copylength = alignmentAnnotation.annotations.length - block[0]; + } } - w += els.length; + + els = new Annotation[annotationLength]; + annels.addElement(els); + System.arraycopy(alignmentAnnotation.annotations, block[0], els, 0, + copylength); + w += annotationLength; } - + if (w != 0) { alignmentAnnotation.annotations = new Annotation[w]; @@ -1822,4 +1805,90 @@ public class HiddenColumns return result; } } + + /** + * An iterator which iterates over visible regions in a range. + */ + private class VisibleBlocksIterator implements Iterator + { + private List vcontigs = new ArrayList<>(); + + private int currentPosition = 0; + + VisibleBlocksIterator(int start, int end, boolean usecopy) + { + try + { + if (usecopy) + { + LOCK.readLock().lock(); + } + + if (hiddenColumns != null && hiddenColumns.size() > 0) + { + int blockStart = start; + int blockEnd = end; + + // iterate until a region overlaps with [start,end] + int i = 0; + while ((i < hiddenColumns.size()) + && (hiddenColumns.get(i)[1] < start)) + { + i++; + } + + // iterate from start to end, adding each hidden region. Positions are + // absolute, and all regions which *overlap* [start,end] are used. + while (i < hiddenColumns.size() + && (hiddenColumns.get(i)[0] <= end)) + { + int[] region = hiddenColumns.get(i); + + blockStart = Math.min(blockStart, region[1] + 1); + blockEnd = Math.min(blockEnd, region[0]); + + int[] contig = new int[] { blockStart, blockEnd }; + vcontigs.add(contig); + + blockStart = region[1] + 1; + blockEnd = end; + + i++; + } + + if (end > blockStart) + { + int[] contig = new int[] { blockStart, end }; + vcontigs.add(contig); + } + } + else + { + int[] contig = new int[] { start, end }; + vcontigs.add(contig); + } + } finally + { + if (usecopy) + { + LOCK.readLock().unlock(); + } + } + } + + @Override + public boolean hasNext() + { + return (currentPosition < vcontigs.size()); + } + + @Override + public int[] next() + { + int[] result = vcontigs.get(currentPosition); + currentPosition++; + return result; + } + } + }