X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fdatamodel%2Ffeatures%2FSequenceFeatures.java;h=2101a2f50d8eba34ea94ca6c37a9681bbbc615ce;hb=14bfc6fb57f123b815f08dbf5b35544abd33b3af;hp=6c830130b5c3ba7199018ed2410ba33ae907b4aa;hpb=b74cdec4b07000bee431a7cca86a948f44d3ffbe;p=jalview.git diff --git a/src/jalview/datamodel/features/SequenceFeatures.java b/src/jalview/datamodel/features/SequenceFeatures.java index 6c83013..2101a2f 100644 --- a/src/jalview/datamodel/features/SequenceFeatures.java +++ b/src/jalview/datamodel/features/SequenceFeatures.java @@ -27,6 +27,7 @@ import jalview.util.Platform; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -46,12 +47,11 @@ import intervalstore.api.IntervalI; */ public class SequenceFeatures implements SequenceFeaturesI { - /* * map from feature type to structured store of features for that type * null types are permitted (but not a good idea!) */ - private Map featureStore; + private Map featureStore; /** * Constructor @@ -63,7 +63,7 @@ public class SequenceFeatures implements SequenceFeaturesI * ? wrap as a synchronized map for add and delete operations */ // featureStore = Collections - // .synchronizedSortedMap(new TreeMap()); + // .synchronizedSortedMap(new TreeMap()); featureStore = new TreeMap<>(); } @@ -97,19 +97,11 @@ public class SequenceFeatures implements SequenceFeaturesI if (featureStore.get(type) == null) { - featureStore.put(type, newFeatureStore()); + featureStore.put(type, new FeatureStore()); } return featureStore.get(type).addFeature(sf); } - private FeatureStoreI newFeatureStore() - { - return (// - Platform.isJS()// - ? new FeatureStoreJS() - : new FeatureStoreImpl()); - } - /** * {@inheritDoc} */ @@ -118,13 +110,9 @@ public class SequenceFeatures implements SequenceFeaturesI String... type) { List result = new ArrayList<>(); - for (FeatureStoreI featureSet : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { - // System.err.println("SF findFeature " + System.currentTimeMillis() - // + " " + from + " " + to + " " - // + featureSet.getPositionalFeatures().get(0).type); - // - result.addAll(featureSet.findOverlappingFeatures(from, to, null)); + featureSet.findFeatures(from, to, result); } return result; } @@ -176,7 +164,7 @@ public class SequenceFeatures implements SequenceFeaturesI { int result = 0; - for (FeatureStoreI featureSet : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { result += featureSet.getFeatureCount(positional); } @@ -191,7 +179,7 @@ public class SequenceFeatures implements SequenceFeaturesI { int result = 0; - for (FeatureStoreI featureSet : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { result += featureSet.getTotalFeatureLength(); } @@ -206,7 +194,7 @@ public class SequenceFeatures implements SequenceFeaturesI { List result = new ArrayList<>(); - for (FeatureStoreI featureSet : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { featureSet.getPositionalFeatures(result); } @@ -220,7 +208,7 @@ public class SequenceFeatures implements SequenceFeaturesI * @param type * @return */ - protected Iterable varargToTypes(String... type) + protected Iterable varargToTypes(String... type) { if (type == null || type.length == 0) { @@ -230,9 +218,9 @@ public class SequenceFeatures implements SequenceFeaturesI return featureStore.values(); } - List types = new ArrayList<>(); + List types = new ArrayList<>(); List args = Arrays.asList(type); - for (Entry featureType : featureStore.entrySet()) + for (Entry featureType : featureStore.entrySet()) { if (args.contains(featureType.getKey())) { @@ -250,7 +238,7 @@ public class SequenceFeatures implements SequenceFeaturesI { List result = new ArrayList<>(); - for (FeatureStoreI featureSet : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { featureSet.getContactFeatures(result); } @@ -265,7 +253,7 @@ public class SequenceFeatures implements SequenceFeaturesI { List result = new ArrayList<>(); - for (FeatureStoreI featureSet : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { featureSet.getNonPositionalFeatures(result); } @@ -278,7 +266,7 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public boolean delete(SequenceFeature sf) { - for (FeatureStoreI featureSet : featureStore.values()) + for (FeatureStore featureSet : featureStore.values()) { if (featureSet.delete(sf)) { @@ -294,7 +282,7 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public boolean hasFeatures() { - for (FeatureStoreI featureSet : featureStore.values()) + for (FeatureStore featureSet : featureStore.values()) { if (!featureSet.isEmpty()) { @@ -311,9 +299,11 @@ public class SequenceFeatures implements SequenceFeaturesI public Set getFeatureGroups(boolean positionalFeatures, String... type) { - Set groups = new HashSet<>(); + // BH 2020.03.21 This is the set that orders the list of groups + // at the top of the FeatureSettings panel. + Set groups = Platform.getJavaOrderedHashSet(); - for (FeatureStoreI featureSet : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { groups.addAll(featureSet.getFeatureGroups(positionalFeatures)); } @@ -328,9 +318,12 @@ public class SequenceFeatures implements SequenceFeaturesI public Set getFeatureTypesForGroups(boolean positionalFeatures, String... groups) { - Set result = new HashSet<>(); + // BH 2020.03.21 This set is the one that sets the initial ordering for + // feature rendering. We set it to new HashSet<>(16,0.75) to force it to + // be backed by a Java hash-ordered HashMap instead of a JavaScript Map. + Set result = Platform.getJavaOrderedHashSet(); - for (Entry featureType : featureStore.entrySet()) + for (Entry featureType : featureStore.entrySet()) { Set featureGroups = featureType.getValue() .getFeatureGroups(positionalFeatures); @@ -356,8 +349,8 @@ public class SequenceFeatures implements SequenceFeaturesI @Override public Set getFeatureTypes(String... soTerm) { - Set types = new HashSet<>(); - for (Entry entry : featureStore.entrySet()) + Set types = new HashSet<>(15, 0.75f); + for (Entry entry : featureStore.entrySet()) { String type = entry.getKey(); if (!entry.getValue().isEmpty() && isOntologyTerm(type, soTerm)) @@ -427,7 +420,9 @@ public class SequenceFeatures implements SequenceFeaturesI public static void sortFeatures(List features, final boolean forwardStrand) { - IntervalI.sortIntervals(features, forwardStrand); + Collections.sort(features, + forwardStrand ? IntervalI.COMPARE_BEGIN_ASC + : IntervalI.COMPARE_END_DESC); } /** @@ -446,7 +441,7 @@ public class SequenceFeatures implements SequenceFeaturesI String group, String... type) { List result = new ArrayList<>(); - for (FeatureStoreI featureSet : varargToTypes(type)) + for (FeatureStore featureSet : varargToTypes(type)) { if (featureSet.getFeatureGroups(positional).contains(group)) { @@ -463,7 +458,7 @@ public class SequenceFeatures implements SequenceFeaturesI public boolean shiftFeatures(int fromPosition, int shiftBy) { boolean modified = false; - for (FeatureStoreI fs : featureStore.values()) + for (FeatureStore fs : featureStore.values()) { modified |= fs.shiftFeatures(fromPosition, shiftBy); } @@ -479,62 +474,23 @@ public class SequenceFeatures implements SequenceFeaturesI featureStore.clear(); } - /** - * Simplified find for features associated with a given position. - * - * JavaScript set to not use IntervalI, but easily testable by setting false - * to true in javadoc - * - * FeatureRenderer has checked already that featureStore does contain type. - * - * @author Bob Hanson 2019.07.30 - */ @Override public List findFeatures(int pos, String type, List list) { - FeatureStoreI fs = featureStore.get(type); - return fs.findOverlappingFeatures(pos, pos, list); + FeatureStore fs = featureStore.get(type); + if (fs == null) + { + return list == null ? new ArrayList<>() : list; + } + return fs.findFeatures(pos, pos, list); } - // Chrome; developer console closed - - // BH 2019.08.01 useIntervalStore true, redraw false: - // Platform: timer mark 13.848 0.367 overviewrender 16000 pixels row:14 - // Platform: timer mark 15.391 0.39 overviewrender 16000 pixels row:14 - // Platform: timer mark 16.498 0.39 overviewrender 16000 pixels row:14 - // Platform: timer mark 17.596 0.401 overviewrender 16000 pixels row:14 - // Platform: timer mark 18.738 0.363 overviewrender 16000 pixels row:14 - // Platform: timer mark 19.659 0.358 overviewrender 16000 pixels row:14 - // Platform: timer mark 20.737 0.359 overviewrender 16000 pixels row:14 - // Platform: timer mark 21.797 0.391 overviewrender 16000 pixels row:14 - // Platform: timer mark 22.851 0.361 overviewrender 16000 pixels row:14 - // Platform: timer mark 24.019 0.395 overviewrender 16000 pixels row:14 - - // BH 2019.08.01 useIntervalStore false, redraw false: - // Platform: timer mark 19.011 0.181 overviewrender 16000 pixels row:14 - // Platform: timer mark 20.311 0.183 overviewrender 16000 pixels row:14 - // Platform: timer mark 21.368 0.175 overviewrender 16000 pixels row:14 - // Platform: timer mark 22.347 0.178 overviewrender 16000 pixels row:14 - // Platform: timer mark 23.605 0.216 overviewrender 16000 pixels row:14 - // Platform: timer mark 24.836 0.191 overviewrender 16000 pixels row:14 - // Platform: timer mark 26.016 0.181 overviewrender 16000 pixels row:14 - // Platform: timer mark 27.278 0.178 overviewrender 16000 pixels row:14 - // Platform: timer mark 28.158 0.181 overviewrender 16000 pixels row:14 - // Platform: timer mark 29.227 0.196 overviewrender 16000 pixels row:14 - // Platform: timer mark 30.1 0.171 overviewrender 16000 pixels row:14 - // Platform: timer mark 31.684 0.196 overviewrender 16000 pixels row:14 - // Platform: timer mark 32.779 0.18 overviewrender 16000 pixels row:14 - // Platform: timer mark 52.355 0.185 overviewrender 16000 pixels row:14 - // Platform: timer mark 53.829 0.186 overviewrender 16000 pixels row:14 - - /** - * @author Bob Hanson 2019.08.01 - */ @Override public boolean hasFeatures(String type) { - return featureStore.containsKey(type); + return featureStore.containsKey(type) + && !featureStore.get(type).isEmpty(); } }