From 5ef61dcb1cc4a94ac6f88e90fc186521ce7224c1 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Tue, 24 Sep 2019 11:24:02 +0100 Subject: [PATCH] JAL-3383 tidy up NCList and alternatives --- src/intervalstore/nonc/IntervalStore.java | 17 +- src/intervalstore/nonc/IntervalStore0.java | 17 +- src/intervalstore/nonc/IntervalStore0Impl.java | 80 -- src/intervalstore/nonc/IntervalStoreImpl.java | 77 -- src/jalview/analysis/CrossRef.java | 13 +- src/jalview/datamodel/SequenceFeature.java | 14 +- src/jalview/datamodel/features/FeatureStore.java | 104 +-- src/jalview/gui/AlignFrame.java | 34 +- test/intervalstore/nonc/IntervalStore0Test.java | 50 +- test/intervalstore/nonc/IntervalStoreTest.java | 48 +- .../datamodel/features/FeatureStoreJSTest.java | 925 -------------------- .../datamodel/features/FeatureStoreLinkedTest.java | 8 +- .../features/FeatureStoreNCListBufferTest.java | 8 +- ...ureStoreJavaTest.java => FeatureStoreTest.java} | 2 +- 14 files changed, 105 insertions(+), 1292 deletions(-) delete mode 100644 src/intervalstore/nonc/IntervalStore0Impl.java delete mode 100644 src/intervalstore/nonc/IntervalStoreImpl.java delete mode 100644 test/jalview/datamodel/features/FeatureStoreJSTest.java rename test/jalview/datamodel/features/{FeatureStoreJavaTest.java => FeatureStoreTest.java} (99%) diff --git a/src/intervalstore/nonc/IntervalStore.java b/src/intervalstore/nonc/IntervalStore.java index effbb55..b010340 100644 --- a/src/intervalstore/nonc/IntervalStore.java +++ b/src/intervalstore/nonc/IntervalStore.java @@ -401,7 +401,7 @@ public class IntervalStore int pt0 = pt; while (--pt >= 0 && offsets[pt] == 0) { - ; + } if (pt < 0) { @@ -1350,26 +1350,15 @@ public class IntervalStore } /** - * CAUTION! This presumes that equalsInterval does check descriptions. Note - * that bartongroup.IntervalStoreJ does NOT do this and - * jalview.datamodel.features.SequenceFeature does not, either. But - * nonc.SimpleFeature in test DOES, because it overrides equalsInterval. - * - * The reason we do it this way is to avoid an unnecessary and costly test for - * obj instanceof IntervalI. - * - * Added by Mungo to use equals, but that requires use of instance checking, - * which is not significant in Java (apparently), but is a bigger deal in - * JavaScript. So here we have to hack - * bobhanson.IntervalStoreJ.nonc.InervalStore to bypass equals. + * Tests for instance equality without using {@code instanceof} * * @param i1 * @param i2 * @return + * @throws ClassCastException */ protected boolean sameInterval(IntervalI i1, IntervalI i2) { - // avoiding equals() for JavaScript performance return ((SequenceFeature) i1).equals((SequenceFeature) i2, false); } diff --git a/src/intervalstore/nonc/IntervalStore0.java b/src/intervalstore/nonc/IntervalStore0.java index c998dc1..980383c 100644 --- a/src/intervalstore/nonc/IntervalStore0.java +++ b/src/intervalstore/nonc/IntervalStore0.java @@ -358,7 +358,7 @@ public class IntervalStore0 int pt0 = pt; while (--pt >= 0 && offsets[pt] == 0) { - ; + } if (pt < 0) { @@ -1047,26 +1047,15 @@ public class IntervalStore0 } /** - * CAUTION! This presumes that equalsInterval does check descriptions. Note - * that bartongroup.IntervalStoreJ does NOT do this and - * jalview.datamodel.features.SequenceFeature does not, either. But - * nonc.SimpleFeature in test DOES, because it overrides equalsInterval. - * - * The reason we do it this way is to avoid an unnecessary and costly test for - * obj instanceof IntervalI. - * - * Added by Mungo to use equals, but that requires use of instance checking, - * which is not significant in Java (apparently), but is a bigger deal in - * JavaScript. So here we have to hack - * bobhanson.IntervalStoreJ.nonc.InervalStore to bypass equals. + * Tests for instance equality without using {@code instanceof} * * @param i1 * @param i2 * @return + * @throws ClassCastException */ boolean sameInterval(IntervalI i1, IntervalI i2) { - // avoiding equals() for JavaScript performance return ((SequenceFeature) i1).equals((SequenceFeature) i2, false); } diff --git a/src/intervalstore/nonc/IntervalStore0Impl.java b/src/intervalstore/nonc/IntervalStore0Impl.java deleted file mode 100644 index ffcb722..0000000 --- a/src/intervalstore/nonc/IntervalStore0Impl.java +++ /dev/null @@ -1,80 +0,0 @@ -/* -BSD 3-Clause License - -Copyright (c) 2018, Mungo Carstairs -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -package intervalstore.nonc; - -import jalview.datamodel.SequenceFeature; - -import intervalstore.api.IntervalI; - -/** - * extend intervalstore.nonc.IntervalStore to account for the fact that - * SequenceFeature.equalsInterval only checks ranges - */ -@SuppressWarnings("rawtypes") -public class IntervalStore0Impl extends IntervalStore0 -{ - - - /** - * Constructor - */ - public IntervalStore0Impl() - { - super(); - } - - /** - * CAUTION! This presumes that equalsInterval does check descriptions. Note - * that bartongroup.IntervalStoreJ does NOT do this and - * jalview.datamodel.features.SequenceFeature does not, either. But - * nonc.SimpleFeature in test DOES, because it overrides equalsInterval. - * - * The reason we do it this way is to avoid an unnecessary and costly test for - * obj instanceof IntervalI. - * - * Added by Mungo to use equals, but that requires use of instance checking, - * which is not significant in Java (apparently), but is a bigger deal in - * JavaScript. So here we have to hack - * bobhanson.IntervalStoreJ.nonc.InervalStore to bypass equals. - * - * @param i1 - * @param i2 - * @return - */ - @Override - boolean sameInterval(IntervalI i1, IntervalI i2) - { - // avoiding equals() for JavaScript performance - return ((SequenceFeature) i1).equalsWithParent((SequenceFeature) i2); - } - -} diff --git a/src/intervalstore/nonc/IntervalStoreImpl.java b/src/intervalstore/nonc/IntervalStoreImpl.java deleted file mode 100644 index 8456b7f..0000000 --- a/src/intervalstore/nonc/IntervalStoreImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -/* -BSD 3-Clause License - -Copyright (c) 2018, Mungo Carstairs -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -package intervalstore.nonc; - -import jalview.datamodel.SequenceFeature; - -import intervalstore.api.IntervalI; - -/** - * extend intervalstore.nonc.IntervalStore to account for the fact that - * SequenceFeature.equalsInterval only checks ranges - */ -@SuppressWarnings("rawtypes") -public class IntervalStoreImpl extends IntervalStore -{ - - public IntervalStoreImpl() - { - super(); - } - - /** - * CAUTION! This presumes that equalsInterval does check descriptions. Note - * that bartongroup.IntervalStoreJ does NOT do this and - * jalview.datamodel.features.SequenceFeature does not, either. But - * nonc.SimpleFeature in test DOES, because it overrides equalsInterval. - * - * The reason we do it this way is to avoid an unnecessary and costly test for - * obj instanceof IntervalI. - * - * Added by Mungo to use equals, but that requires use of instance checking, - * which is not significant in Java (apparently), but is a bigger deal in - * JavaScript. So here we have to hack - * bobhanson.IntervalStoreJ.nonc.InervalStore to bypass equals. - * - * @param i1 - * @param i2 - * @return - */ - @Override - protected boolean sameInterval(IntervalI i1, IntervalI i2) - { - // avoiding equals() for JavaScript performance - // could be CrossRef with ignoreParent==true - return ((SequenceFeature) i1).equalsWithParent((SequenceFeature) i2); - } - -} diff --git a/src/jalview/analysis/CrossRef.java b/src/jalview/analysis/CrossRef.java index ed87f05..080f3e2 100644 --- a/src/jalview/analysis/CrossRef.java +++ b/src/jalview/analysis/CrossRef.java @@ -637,22 +637,11 @@ public class CrossRef */ SequenceFeature newFeature = new SequenceFeature(feat) { - // BH 2019.08.15 We must override equalsInterval, not - // equals, because that is part of the IntervalI interface, - // and IntervalStore may need that for proper, faster - // processing. - // But SequenceFeature changes were reverted... @Override public boolean equals(Object o) { return o instanceof SequenceFeature - && equalsWithParent((SequenceFeature) o); - } - - @Override - public boolean equalsWithParent(SequenceFeature sf) - { - return sf != null && equals(sf, true); + && equals((SequenceFeature) o, true); } }; matched.addSequenceFeature(newFeature); diff --git a/src/jalview/datamodel/SequenceFeature.java b/src/jalview/datamodel/SequenceFeature.java index 1af23a4..1f2e639 100755 --- a/src/jalview/datamodel/SequenceFeature.java +++ b/src/jalview/datamodel/SequenceFeature.java @@ -218,19 +218,7 @@ public class SequenceFeature implements FeatureLocationI public boolean equals(Object o) { return (o instanceof SequenceFeature - && equalsWithParent((SequenceFeature) o)); - } - - /** - * BH 2019.09.22 required due to subclassing by CrossRef and used by - * intervalstore.nonc.IntervalStoreImpl - * - * @param sf - * @return - */ - public boolean equalsWithParent(SequenceFeature sf) - { - return equals(sf, false); + && equals((SequenceFeature) o, false)); } /** diff --git a/src/jalview/datamodel/features/FeatureStore.java b/src/jalview/datamodel/features/FeatureStore.java index 5c0336a..fff7127 100644 --- a/src/jalview/datamodel/features/FeatureStore.java +++ b/src/jalview/datamodel/features/FeatureStore.java @@ -21,7 +21,6 @@ package jalview.datamodel.features; import jalview.datamodel.SequenceFeature; -import jalview.util.Platform; import java.util.ArrayList; import java.util.Collection; @@ -36,12 +35,30 @@ import intervalstore.impl.BinarySearcher.Compare; public class FeatureStore { + public enum IntervalStoreType + { + /** + * original NCList-based IntervalStore + */ + INTERVAL_STORE_NCLIST, + + /** + * linked-list IntervalStore + */ + INTERVAL_STORE_LINKED_LIST, + + /** + * NCList as array buffer IntervalStore + */ + INTERVAL_STORE_NCARRAY + } + /* - * track last start for quick insertion of ordered features + * track largest start for quick insertion of ordered features */ - protected int lastStart = -1; + protected int maxStart = -1; - protected int lastContactStart = -1; + protected int maxContactStart = -1; /* * Non-positional features have no (zero) start/end position. @@ -91,38 +108,6 @@ public class FeatureStore float nonPositionalMaxScore; - public final static int INTERVAL_STORE_DEFAULT = -1; - - /** - * original NCList-based IntervalStore - */ - public final static int INTERVAL_STORE_NCLIST_OBJECT = 0; - - /** - * linked-list IntervalStore - */ - public final static int INTERVAL_STORE_LINKED_LIST = 1; - - /** - * NCList as array buffer IntervalStore - */ - public final static int INTERVAL_STORE_NCARRAY = 3; - - static final int intervalStoreJavaOption = INTERVAL_STORE_NCLIST_OBJECT; - - private final static boolean useJSOption = false; - - private final static boolean isJSLinkedTest = true; - - static final int intervalStoreJSOption = (!useJSOption - ? intervalStoreJavaOption - : isJSLinkedTest - ? INTERVAL_STORE_LINKED_LIST - : INTERVAL_STORE_NCARRAY); - - // TODO: compare performance in real situations using - // INTERVAL_STORE_LINKED_LIST; - /** * Answers the 'length' of the feature, counting 0 for non-positional features * and 1 for contact features @@ -152,7 +137,7 @@ public class FeatureStore * @param feature * @return */ - public boolean listContains(List list, + public static boolean listContains(List list, SequenceFeature feature) { if (list == null || feature == null) @@ -223,23 +208,20 @@ public class FeatureStore } /** - * standard constructor + * Constructor that defaults to using NCList IntervalStore */ public FeatureStore() { - this(INTERVAL_STORE_DEFAULT); + this(IntervalStoreType.INTERVAL_STORE_NCLIST); } /** - * constructor for testing only + * Constructor that allows an alternative IntervalStore implementation to be + * chosen */ - public FeatureStore(int intervalStoreType) + public FeatureStore(IntervalStoreType intervalStoreType) { - features = - // Platform.isJS() - // ? new intervalstore.nonc.IntervalStore<>(true) - // : new intervalstore.impl.IntervalStore<>(); - getIntervalStore(intervalStoreType); + features = getIntervalStore(intervalStoreType); positionalFeatureGroups = new HashSet<>(); nonPositionalFeatureGroups = new HashSet<>(); positionalMinScore = Float.NaN; @@ -247,24 +229,21 @@ public class FeatureStore nonPositionalMinScore = Float.NaN; nonPositionalMaxScore = Float.NaN; - // we only construct nonPositionalFeatures, contactFeatures if we need to + // only construct nonPositionalFeatures or contactFeatures if needed } - private IntervalStoreI getIntervalStore(int type) + private IntervalStoreI getIntervalStore( + IntervalStoreType type) { - switch (type != INTERVAL_STORE_DEFAULT ? type : // - Platform.isJS() // - ? intervalStoreJSOption - : intervalStoreJavaOption) + switch (type) { default: - case INTERVAL_STORE_NCLIST_OBJECT: + case INTERVAL_STORE_NCLIST: return new intervalstore.impl.IntervalStore<>(); case INTERVAL_STORE_NCARRAY: - // TODO: Couldn't figure out how to get rid of this warning - return new intervalstore.nonc.IntervalStoreImpl<>(); + return new intervalstore.nonc.IntervalStore<>(); case INTERVAL_STORE_LINKED_LIST: - return new intervalstore.nonc.IntervalStore0Impl<>(); + return new intervalstore.nonc.IntervalStore0<>(); } } @@ -319,9 +298,9 @@ public class FeatureStore return false; } positionalFeatureGroups.add(feature.getFeatureGroup()); - if (feature.begin > lastContactStart) + if (feature.begin > maxContactStart) { - lastContactStart = feature.begin; + maxContactStart = feature.begin; } addContactFeature(feature); } @@ -341,9 +320,9 @@ public class FeatureStore return false; } positionalFeatureGroups.add(feature.getFeatureGroup()); - if (feature.begin > lastStart) + if (feature.begin > maxStart) { - lastStart = feature.begin; + maxStart = feature.begin; } } @@ -437,12 +416,11 @@ public class FeatureStore } return containsPositionalFeature(feature); - } private boolean containsPositionalFeature(SequenceFeature feature) { - return features == null || feature.begin > lastStart ? false + return features == null || feature.begin > maxStart ? false : features.contains(feature); } @@ -455,7 +433,7 @@ public class FeatureStore */ private boolean containsContactFeature(SequenceFeature feature) { - return contactFeatureStarts != null && feature.begin <= lastContactStart + return contactFeatureStarts != null && feature.begin <= maxContactStart && listContains(contactFeatureStarts, feature); } diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index 4d29919..597eb5b 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -851,25 +851,23 @@ public class AlignFrame extends GAlignFrame private PropertyChangeListener addServiceListeners() { PropertyChangeListener serviceListener = new PropertyChangeListener() - { - @Override - public void propertyChange(PropertyChangeEvent evt) - { - { - SwingUtilities.invokeLater(new Runnable() - { - - @Override - public void run() - { - System.err.println( - "Rebuild WS Menu for service change"); - BuildWebServiceMenu(); - } + { + @Override + public void propertyChange(PropertyChangeEvent evt) + { + { + SwingUtilities.invokeLater(new Runnable() + { - }); - } - } + @Override + public void run() + { + System.err.println("Rebuild WS Menu for service change"); + BuildWebServiceMenu(); + } + }); + } + } }; Desktop.getInstance().addJalviewPropertyChangeListener("services", diff --git a/test/intervalstore/nonc/IntervalStore0Test.java b/test/intervalstore/nonc/IntervalStore0Test.java index c3dfb17..c2d7864 100644 --- a/test/intervalstore/nonc/IntervalStore0Test.java +++ b/test/intervalstore/nonc/IntervalStore0Test.java @@ -60,7 +60,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testFindOverlaps_nonNested() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = add(store, 10, 20); // same range different description SimpleFeature sf2 = new SimpleFeature(10, 20, "desc"); @@ -100,7 +100,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testFindOverlaps_nested() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = add(store, 10, 50); SimpleFeature sf2 = add(store, 10, 40); SimpleFeature sf3 = add(store, 20, 30); @@ -138,7 +138,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testFindOverlaps_mixed() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = add(store, 10, 50); SimpleFeature sf2 = add(store, 1, 15); SimpleFeature sf3 = add(store, 20, 30); @@ -195,7 +195,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testRemove() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = add(store, 10, 20); assertTrue(store.contains(sf1)); @@ -261,31 +261,10 @@ public class IntervalStore0Test assertTrue(store.isEmpty()); } - /** - * A helper method to test whether a list contains a specific object (by - * object identity, not equality test as used by List.contains()) - * - * @param list - * @param o - * @return - */ - private static boolean containsObject(List list, - Object o) - { - for (Object i : list) - { - if (i == o) - { - return true; - } - } - return false; - } - @Test(groups = "Functional") public void testAdd() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); assertFalse(store.add(null)); @@ -315,7 +294,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testAdd_noDuplicates() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = new SimpleFeature(10, 20, "Cath"); SimpleFeature sf2 = new SimpleFeature(10, 20, "Cath"); @@ -331,7 +310,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testIsEmpty() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); assertTrue(store.isEmpty()); assertEquals(store.size(), 0); @@ -384,7 +363,7 @@ public class IntervalStore0Test /* * add a feature and a nested feature */ - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = add(store, 10, 20); // sf2 is nested in sf1 so will be stored in nestedFeatures SimpleFeature sf2 = add(store, 12, 14); @@ -410,7 +389,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testContains() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = new SimpleFeature(10, 20, "Cath"); SimpleFeature sf2 = new SimpleFeature(10, 20, "Pfam"); @@ -447,7 +426,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testFindOverlaps_resultsArg_mixed() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = add(store, 10, 50); SimpleFeature sf2 = add(store, 1, 15); SimpleFeature sf3 = add(store, 20, 30); @@ -510,7 +489,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testFindOverlaps_resultsArg_nested() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = add(store, 10, 50); SimpleFeature sf2 = add(store, 10, 40); SimpleFeature sf3 = add(store, 20, 30); @@ -552,7 +531,7 @@ public class IntervalStore0Test @Test(groups = "Functional") public void testFindOverlaps_resultsArg_nonNested() { - IntervalStore0 store = new IntervalStore0Impl(); + IntervalStore0 store = new IntervalStore0<>(); SimpleFeature sf1 = add(store, 10, 20); // same range different description SimpleFeature sf2 = new SimpleFeature(10, 20, "desc"); @@ -622,7 +601,7 @@ public class IntervalStore0Test + start + " " + end); StringBuffer sb = new StringBuffer(); IntervalStoreI store; - store = new intervalstore.nonc.IntervalStore0Impl(); + store = new IntervalStore0<>(); testAddAndQueryTiming(store, false, sb, addstart, addend, start, end); store = new intervalstore.impl.IntervalStore<>(); @@ -669,7 +648,8 @@ public class IntervalStore0Test } if (!isNCList) { - ((intervalstore.nonc.IntervalStore0) store).revalidate(); + ((intervalstore.nonc.IntervalStore0) store) + .revalidate(); } String line = "time to load " + (isNCList ? "NClist " : "NCArray ") + (System.nanoTime() - ntimeLoad) / K / K + " ms scale " diff --git a/test/intervalstore/nonc/IntervalStoreTest.java b/test/intervalstore/nonc/IntervalStoreTest.java index 581f5f4..2c4e14b 100644 --- a/test/intervalstore/nonc/IntervalStoreTest.java +++ b/test/intervalstore/nonc/IntervalStoreTest.java @@ -60,7 +60,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testFindOverlaps_nonNested() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = add(store, 10, 20); // same range different description SimpleFeature sf2 = new SimpleFeature(10, 20, "desc"); @@ -100,7 +100,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testFindOverlaps_nested() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = add(store, 10, 50); SimpleFeature sf2 = add(store, 10, 40); SimpleFeature sf3 = add(store, 20, 30); @@ -138,7 +138,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testFindOverlaps_mixed() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = add(store, 10, 50); SimpleFeature sf2 = add(store, 1, 15); SimpleFeature sf3 = add(store, 20, 30); @@ -195,7 +195,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testRemove() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = add(store, 10, 20); assertTrue(store.contains(sf1)); @@ -261,31 +261,10 @@ public class IntervalStoreTest assertTrue(store.isEmpty()); } - /** - * A helper method to test whether a list contains a specific object (by - * object identity, not equality test as used by List.contains()) - * - * @param list - * @param o - * @return - */ - private static boolean containsObject(List list, - Object o) - { - for (Object i : list) - { - if (i == o) - { - return true; - } - } - return false; - } - @Test(groups = "Functional") public void testAdd() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); assertFalse(store.add(null)); @@ -315,7 +294,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testAdd_noDuplicates() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = new SimpleFeature(10, 20, "Cath"); SimpleFeature sf2 = new SimpleFeature(10, 20, "Cath"); @@ -331,7 +310,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testIsEmpty() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); assertTrue(store.isEmpty()); assertEquals(store.size(), 0); @@ -384,7 +363,7 @@ public class IntervalStoreTest /* * add a feature and a nested feature */ - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = add(store, 10, 20); // sf2 is nested in sf1 so will be stored in nestedFeatures SimpleFeature sf2 = add(store, 12, 14); @@ -410,7 +389,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testContains() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = new SimpleFeature(10, 20, "Cath"); SimpleFeature sf2 = new SimpleFeature(10, 20, "Pfam"); @@ -447,7 +426,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testFindOverlaps_resultsArg_mixed() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = add(store, 10, 50); SimpleFeature sf2 = add(store, 1, 15); SimpleFeature sf3 = add(store, 20, 30); @@ -510,7 +489,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testFindOverlaps_resultsArg_nested() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = add(store, 10, 50); SimpleFeature sf2 = add(store, 10, 40); SimpleFeature sf3 = add(store, 20, 30); @@ -552,7 +531,7 @@ public class IntervalStoreTest @Test(groups = "Functional") public void testFindOverlaps_resultsArg_nonNested() { - IntervalStore store = new IntervalStoreImpl(); + IntervalStore store = new IntervalStore<>(); SimpleFeature sf1 = add(store, 10, 20); // same range different description SimpleFeature sf2 = new SimpleFeature(10, 20, "desc"); @@ -669,7 +648,8 @@ public class IntervalStoreTest } if (!isNCList) { - ((intervalstore.nonc.IntervalStore) store).revalidate(); + ((intervalstore.nonc.IntervalStore) store) + .revalidate(); } String line = "time to load " + (isNCList ? "NClist " : "NCArray ") + (System.nanoTime() - ntimeLoad) / K / K + " ms scale " diff --git a/test/jalview/datamodel/features/FeatureStoreJSTest.java b/test/jalview/datamodel/features/FeatureStoreJSTest.java deleted file mode 100644 index 489ac38..0000000 --- a/test/jalview/datamodel/features/FeatureStoreJSTest.java +++ /dev/null @@ -1,925 +0,0 @@ -package jalview.datamodel.features; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertSame; -import static org.testng.Assert.assertTrue; - -import jalview.datamodel.SequenceFeature; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.testng.annotations.Test; - -public class FeatureStoreJSTest -{ - - private int intervalStoreOption = FeatureStore.intervalStoreJSOption; - - @Test(groups = "Functional") - public void testFindFeatures_nonNested() - { - FeatureStore fs = newFeatureStore(); - fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN, - null)); - // same range different description - fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null)); - fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null)); - fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null)); - - List overlaps = fs.findOverlappingFeatures(1, 9); - assertTrue(overlaps.isEmpty()); - - overlaps = fs.findOverlappingFeatures(8, 10); - assertEquals(overlaps.size(), 2); - assertEquals(overlaps.get(0).getEnd(), 20); - assertEquals(overlaps.get(1).getEnd(), 20); - - overlaps = fs.findOverlappingFeatures(12, 16); - - assertEquals(overlaps.size(), 3); - assertEquals(overlaps.get(2).getEnd(), 25); - assertEquals(overlaps.get(1).getEnd(), 20); - assertEquals(overlaps.get(0).getEnd(), 20); - - overlaps = fs.findOverlappingFeatures(33, 33); - assertEquals(overlaps.size(), 1); - assertEquals(overlaps.get(0).getEnd(), 35); - } - - private FeatureStore newFeatureStore() - { - return new FeatureStore(intervalStoreOption); - } - - @Test(groups = "Functional") - public void testFindFeatures_nested() - { - FeatureStore fs = newFeatureStore(); - SequenceFeature sf1 = addFeature(fs, 10, 50); - SequenceFeature sf2 = addFeature(fs, 10, 40); - SequenceFeature sf3 = addFeature(fs, 20, 30); - // fudge feature at same location but different group (so is added) - SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN, - "different group"); - fs.addFeature(sf4); - SequenceFeature sf5 = addFeature(fs, 35, 36); - - List overlaps = fs.findOverlappingFeatures(1, 9); - assertTrue(overlaps.isEmpty()); - - overlaps = fs.findOverlappingFeatures(10, 15); - assertEquals(overlaps.size(), 2); - assertTrue(overlaps.contains(sf1)); - assertTrue(overlaps.contains(sf2)); - - overlaps = fs.findOverlappingFeatures(45, 60); - assertEquals(overlaps.size(), 1); - assertTrue(overlaps.contains(sf1)); - - overlaps = fs.findOverlappingFeatures(32, 38); - assertEquals(overlaps.size(), 3); - assertTrue(overlaps.contains(sf1)); - assertTrue(overlaps.contains(sf2)); - assertTrue(overlaps.contains(sf5)); - - overlaps = fs.findOverlappingFeatures(15, 25); - assertEquals(overlaps.size(), 4); - assertTrue(overlaps.contains(sf1)); - assertTrue(overlaps.contains(sf2)); - assertTrue(overlaps.contains(sf3)); - assertTrue(overlaps.contains(sf4)); - } - - private void testFind() - { - FeatureStore fs1 = newFeatureStore(); - - SequenceFeature sf = addFeature(fs1, 1, 3000); - - for (int i = 1; i < 1000; i++) - - { - - addFeature(fs1, 1 + i, 1000 + i); - - } - - // 1.......3000 - // 2....1001 - // 3....1002 - // 4....1003 - // ... - // 1000..1999 - - List overlaps1 = fs1.findOverlappingFeatures(2000, - 2001); - - assertEquals(overlaps1.size(), 1); - - assertTrue(overlaps1.contains(sf)); - - } - - @Test(groups = "Functional") - public void testFindFeatures_mixed() - { - testFind(); - - FeatureStore fs = newFeatureStore(); - SequenceFeature sf1 = addFeature(fs, 10, 50); - SequenceFeature sf2 = addFeature(fs, 1, 15); - SequenceFeature sf3 = addFeature(fs, 20, 30); - SequenceFeature sf4 = addFeature(fs, 40, 100); - SequenceFeature sf5 = addFeature(fs, 60, 100); - SequenceFeature sf6 = addFeature(fs, 70, 70); - - List overlaps = fs.findOverlappingFeatures(200, 200); - assertTrue(overlaps.isEmpty()); - - overlaps = fs.findOverlappingFeatures(1, 9); - assertEquals(overlaps.size(), 1); - assertTrue(overlaps.contains(sf2)); - - overlaps = fs.findOverlappingFeatures(5, 18); - assertEquals(overlaps.size(), 2); - assertTrue(overlaps.contains(sf1)); - assertTrue(overlaps.contains(sf2)); - - overlaps = fs.findOverlappingFeatures(30, 40); - assertEquals(overlaps.size(), 3); - assertTrue(overlaps.contains(sf1)); - assertTrue(overlaps.contains(sf3)); - assertTrue(overlaps.contains(sf4)); - - overlaps = fs.findOverlappingFeatures(80, 90); - assertEquals(overlaps.size(), 2); - assertTrue(overlaps.contains(sf4)); - assertTrue(overlaps.contains(sf5)); - - overlaps = fs.findOverlappingFeatures(68, 70); - assertEquals(overlaps.size(), 3); - assertTrue(overlaps.contains(sf4)); - assertTrue(overlaps.contains(sf5)); - assertTrue(overlaps.contains(sf6)); - } - - /** - * Helper method to add a feature of no particular type - * - * @param fs - * @param from - * @param to - * @return - */ - SequenceFeature addFeature(FeatureStore fs, int from, int to) - { - SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN, - null); - fs.addFeature(sf1); - return sf1; - } - - @Test(groups = "Functional") - public void testFindFeatures_contactFeatures() - { - FeatureStore fs = newFeatureStore(); - - SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10, - 20, Float.NaN, null); - fs.addFeature(sf); - - /* - * neither contact point in range - */ - List overlaps = fs.findOverlappingFeatures(1, 9); - assertTrue(overlaps.isEmpty()); - - /* - * neither contact point in range - */ - overlaps = fs.findOverlappingFeatures(11, 19); - assertTrue(overlaps.isEmpty()); - - /* - * first contact point in range - */ - overlaps = fs.findOverlappingFeatures(5, 15); - assertEquals(overlaps.size(), 1); - assertTrue(overlaps.contains(sf)); - - /* - * second contact point in range - */ - overlaps = fs.findOverlappingFeatures(15, 25); - assertEquals(overlaps.size(), 1); - assertTrue(overlaps.contains(sf)); - - /* - * both contact points in range - */ - overlaps = fs.findOverlappingFeatures(5, 25); - assertEquals(overlaps.size(), 1); - assertTrue(overlaps.contains(sf)); - } - - @Test(groups = "Functional") - public void testGetPositionalFeatures() - { - FeatureStore store = newFeatureStore(); - SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20, - Float.NaN, null); - store.addFeature(sf1); - // same range, different description - SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20, - Float.NaN, null); - store.addFeature(sf2); - // discontiguous range - SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40, - Float.NaN, null); - store.addFeature(sf3); - // overlapping range - SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35, - Float.NaN, null); - store.addFeature(sf4); - // enclosing range - SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50, - Float.NaN, null); - store.addFeature(sf5); - // non-positional feature - SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0, - Float.NaN, null); - store.addFeature(sf6); - // contact feature - SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc", - 18, 45, Float.NaN, null); - store.addFeature(sf7); - - List features = store.getPositionalFeatures(); - assertEquals(features.size(), 6); - assertTrue(features.contains(sf1)); - assertTrue(features.contains(sf2)); - assertTrue(features.contains(sf3)); - assertTrue(features.contains(sf4)); - assertTrue(features.contains(sf5)); - assertFalse(features.contains(sf6)); - assertTrue(features.contains(sf7)); - - features = store.getNonPositionalFeatures(); - assertEquals(features.size(), 1); - assertTrue(features.contains(sf6)); - } - - @Test(groups = "Functional") - public void testDelete() - { - FeatureStore store = newFeatureStore(); - SequenceFeature sf1 = addFeature(store, 10, 20); - assertTrue(store.getPositionalFeatures().contains(sf1)); - - /* - * simple deletion - */ - assertTrue(store.delete(sf1)); - assertTrue(store.getPositionalFeatures().isEmpty()); - - /* - * non-positional feature deletion - */ - SequenceFeature sf2 = addFeature(store, 0, 0); - assertFalse(store.getPositionalFeatures().contains(sf2)); - assertTrue(store.getNonPositionalFeatures().contains(sf2)); - assertTrue(store.delete(sf2)); - assertTrue(store.getNonPositionalFeatures().isEmpty()); - - /* - * contact feature deletion - */ - SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11, - 23, Float.NaN, null); - store.addFeature(sf3); - assertEquals(store.getPositionalFeatures().size(), 1); - assertTrue(store.getPositionalFeatures().contains(sf3)); - assertTrue(store.delete(sf3)); - assertTrue(store.getPositionalFeatures().isEmpty()); - - /* - * nested feature deletion - */ - SequenceFeature sf4 = addFeature(store, 20, 30); - SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList - SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5 - SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6 - SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6 - SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6 - assertEquals(store.getPositionalFeatures().size(), 6); - - // delete a node with children - they take its place - assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5 - assertEquals(store.getPositionalFeatures().size(), 5); - assertFalse(store.getPositionalFeatures().contains(sf6)); - - // delete a node with no children - assertTrue(store.delete(sf7)); - assertEquals(store.getPositionalFeatures().size(), 4); - assertFalse(store.getPositionalFeatures().contains(sf7)); - - // delete root of NCList - assertTrue(store.delete(sf5)); - assertEquals(store.getPositionalFeatures().size(), 3); - assertFalse(store.getPositionalFeatures().contains(sf5)); - - // continue the killing fields - assertTrue(store.delete(sf4)); - assertEquals(store.getPositionalFeatures().size(), 2); - assertFalse(store.getPositionalFeatures().contains(sf4)); - - assertTrue(store.delete(sf9)); - assertEquals(store.getPositionalFeatures().size(), 1); - assertFalse(store.getPositionalFeatures().contains(sf9)); - - assertTrue(store.delete(sf8)); - assertTrue(store.getPositionalFeatures().isEmpty()); - } - - @Test(groups = "Functional") - public void testAddFeature() - { - FeatureStore fs = newFeatureStore(); - - SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20, - Float.NaN, null); - SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20, - Float.NaN, null); - - assertTrue(fs.addFeature(sf1)); - assertEquals(fs.getFeatureCount(true), 1); // positional - assertEquals(fs.getFeatureCount(false), 0); // non-positional - - /* - * re-adding the same or an identical feature should fail - */ - assertFalse(fs.addFeature(sf1)); - assertEquals(fs.getFeatureCount(true), 1); - assertFalse(fs.addFeature(sf2)); - assertEquals(fs.getFeatureCount(true), 1); - - /* - * add non-positional - */ - SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, - null); - assertTrue(fs.addFeature(sf3)); - assertEquals(fs.getFeatureCount(true), 1); // positional - assertEquals(fs.getFeatureCount(false), 1); // non-positional - SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, - null); - assertFalse(fs.addFeature(sf4)); // already stored - assertEquals(fs.getFeatureCount(true), 1); // positional - assertEquals(fs.getFeatureCount(false), 1); // non-positional - - /* - * add contact - */ - SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20, - Float.NaN, null); - assertTrue(fs.addFeature(sf5)); - assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact - assertEquals(fs.getFeatureCount(false), 1); // non-positional - SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20, - Float.NaN, null); - assertFalse(fs.addFeature(sf6)); // already stored - assertEquals(fs.getFeatureCount(true), 2); // no change - assertEquals(fs.getFeatureCount(false), 1); // no change - } - - @Test(groups = "Functional") - public void testIsEmpty() - { - FeatureStore fs = newFeatureStore(); - assertTrue(fs.isEmpty()); - assertEquals(fs.getFeatureCount(true), 0); - - /* - * non-nested feature - */ - SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20, - Float.NaN, null); - fs.addFeature(sf1); - assertFalse(fs.isEmpty()); - assertEquals(fs.getFeatureCount(true), 1); - fs.delete(sf1); - assertTrue(fs.isEmpty()); - assertEquals(fs.getFeatureCount(true), 0); - - /* - * non-positional feature - */ - sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null); - fs.addFeature(sf1); - assertFalse(fs.isEmpty()); - assertEquals(fs.getFeatureCount(false), 1); // non-positional - assertEquals(fs.getFeatureCount(true), 0); // positional - fs.delete(sf1); - assertTrue(fs.isEmpty()); - assertEquals(fs.getFeatureCount(false), 0); - - /* - * contact feature - */ - sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null); - fs.addFeature(sf1); - assertFalse(fs.isEmpty()); - assertEquals(fs.getFeatureCount(true), 1); - fs.delete(sf1); - assertTrue(fs.isEmpty()); - assertEquals(fs.getFeatureCount(true), 0); - - /* - * sf2, sf3 added as nested features - */ - sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null); - SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40, - Float.NaN, null); - SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35, - Float.NaN, null); - fs.addFeature(sf1); - fs.addFeature(sf2); - fs.addFeature(sf3); - assertEquals(fs.getFeatureCount(true), 3); - assertTrue(fs.delete(sf1)); - assertEquals(fs.getFeatureCount(true), 2); - assertEquals(fs.getFeatures().size(), 2); - assertFalse(fs.isEmpty()); - assertTrue(fs.delete(sf2)); - assertEquals(fs.getFeatureCount(true), 1); - assertFalse(fs.isEmpty()); - assertTrue(fs.delete(sf3)); - assertEquals(fs.getFeatureCount(true), 0); - assertTrue(fs.isEmpty()); // all gone - } - - @Test(groups = "Functional") - public void testGetFeatureGroups() - { - FeatureStore fs = newFeatureStore(); - assertTrue(fs.getFeatureGroups(true).isEmpty()); - assertTrue(fs.getFeatureGroups(false).isEmpty()); - - SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1"); - fs.addFeature(sf1); - Set groups = fs.getFeatureGroups(true); - assertEquals(groups.size(), 1); - assertTrue(groups.contains("group1")); - - /* - * add another feature of the same group, delete one, delete both - */ - SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1"); - fs.addFeature(sf2); - groups = fs.getFeatureGroups(true); - assertEquals(groups.size(), 1); - assertTrue(groups.contains("group1")); - fs.delete(sf2); - groups = fs.getFeatureGroups(true); - assertEquals(groups.size(), 1); - assertTrue(groups.contains("group1")); - fs.delete(sf1); - groups = fs.getFeatureGroups(true); - assertTrue(fs.getFeatureGroups(true).isEmpty()); - - SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2"); - fs.addFeature(sf3); - SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2"); - fs.addFeature(sf4); - SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null); - fs.addFeature(sf5); - groups = fs.getFeatureGroups(true); - assertEquals(groups.size(), 3); - assertTrue(groups.contains("group2")); - assertTrue(groups.contains("Group2")); // case sensitive - assertTrue(groups.contains(null)); // null allowed - assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional - - fs.delete(sf3); - groups = fs.getFeatureGroups(true); - assertEquals(groups.size(), 2); - assertFalse(groups.contains("group2")); - fs.delete(sf4); - groups = fs.getFeatureGroups(true); - assertEquals(groups.size(), 1); - assertFalse(groups.contains("Group2")); - fs.delete(sf5); - groups = fs.getFeatureGroups(true); - assertTrue(groups.isEmpty()); - - /* - * add non-positional feature - */ - SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f, - "CathGroup"); - fs.addFeature(sf6); - groups = fs.getFeatureGroups(false); - assertEquals(groups.size(), 1); - assertTrue(groups.contains("CathGroup")); - assertTrue(fs.delete(sf6)); - assertTrue(fs.getFeatureGroups(false).isEmpty()); - } - - @Test(groups = "Functional") - public void testGetTotalFeatureLength() - { - FeatureStore fs = newFeatureStore(); - assertEquals(fs.getTotalFeatureLength(), 0); - - addFeature(fs, 10, 20); // 11 - assertEquals(fs.getTotalFeatureLength(), 11); - addFeature(fs, 17, 37); // 21 - SequenceFeature sf1 = addFeature(fs, 14, 74); // 61 - assertEquals(fs.getTotalFeatureLength(), 93); - - // non-positional features don't count - SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f, - "group1"); - fs.addFeature(sf2); - assertEquals(fs.getTotalFeatureLength(), 93); - - // contact features count 1 - SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc", - 15, 35, 1f, "group1"); - fs.addFeature(sf3); - assertEquals(fs.getTotalFeatureLength(), 94); - - assertTrue(fs.delete(sf1)); - assertEquals(fs.getTotalFeatureLength(), 33); - assertFalse(fs.delete(sf1)); - assertEquals(fs.getTotalFeatureLength(), 33); - assertTrue(fs.delete(sf2)); - assertEquals(fs.getTotalFeatureLength(), 33); - assertTrue(fs.delete(sf3)); - assertEquals(fs.getTotalFeatureLength(), 32); - } - - @Test(groups = "Functional") - public void testGetFeatureLength() - { - /* - * positional feature - */ - SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1"); - assertEquals(FeatureStore.getFeatureLength(sf1), 11); - - /* - * non-positional feature - */ - SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f, - "CathGroup"); - assertEquals(FeatureStore.getFeatureLength(sf2), 0); - - /* - * contact feature counts 1 - */ - SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc", - 14, 28, 1f, "AGroup"); - assertEquals(FeatureStore.getFeatureLength(sf3), 1); - } - - @Test(groups = "Functional") - public void testMin() - { - assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN); - assertEquals(FeatureStore.min(Float.NaN, 2f), 2f); - assertEquals(FeatureStore.min(-2f, Float.NaN), -2f); - assertEquals(FeatureStore.min(2f, -3f), -3f); - } - - @Test(groups = "Functional") - public void testMax() - { - assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN); - assertEquals(FeatureStore.max(Float.NaN, 2f), 2f); - assertEquals(FeatureStore.max(-2f, Float.NaN), -2f); - assertEquals(FeatureStore.max(2f, -3f), 2f); - } - - @Test(groups = "Functional") - public void testGetMinimumScore_getMaximumScore() - { - FeatureStore fs = newFeatureStore(); - assertEquals(fs.getMinimumScore(true), Float.NaN); // positional - assertEquals(fs.getMaximumScore(true), Float.NaN); - assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional - assertEquals(fs.getMaximumScore(false), Float.NaN); - - // add features with no score - SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0, - Float.NaN, "group"); - fs.addFeature(sf1); - SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20, - Float.NaN, "group"); - fs.addFeature(sf2); - assertEquals(fs.getMinimumScore(true), Float.NaN); - assertEquals(fs.getMaximumScore(true), Float.NaN); - assertEquals(fs.getMinimumScore(false), Float.NaN); - assertEquals(fs.getMaximumScore(false), Float.NaN); - - // add positional features with score - SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f, - "group"); - fs.addFeature(sf3); - SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f, - "group"); - fs.addFeature(sf4); - assertEquals(fs.getMinimumScore(true), 1f); - assertEquals(fs.getMaximumScore(true), 4f); - assertEquals(fs.getMinimumScore(false), Float.NaN); - assertEquals(fs.getMaximumScore(false), Float.NaN); - - // add non-positional features with score - SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f, - "group"); - fs.addFeature(sf5); - SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f, - "group"); - fs.addFeature(sf6); - assertEquals(fs.getMinimumScore(true), 1f); - assertEquals(fs.getMaximumScore(true), 4f); - assertEquals(fs.getMinimumScore(false), -7f); - assertEquals(fs.getMaximumScore(false), 11f); - - // delete one positional and one non-positional - // min-max should be recomputed - assertTrue(fs.delete(sf6)); - assertTrue(fs.delete(sf3)); - assertEquals(fs.getMinimumScore(true), 4f); - assertEquals(fs.getMaximumScore(true), 4f); - assertEquals(fs.getMinimumScore(false), 11f); - assertEquals(fs.getMaximumScore(false), 11f); - - // delete remaining features with score - assertTrue(fs.delete(sf4)); - assertTrue(fs.delete(sf5)); - assertEquals(fs.getMinimumScore(true), Float.NaN); - assertEquals(fs.getMaximumScore(true), Float.NaN); - assertEquals(fs.getMinimumScore(false), Float.NaN); - assertEquals(fs.getMaximumScore(false), Float.NaN); - - // delete all features - assertTrue(fs.delete(sf1)); - assertTrue(fs.delete(sf2)); - assertTrue(fs.isEmpty()); - assertEquals(fs.getMinimumScore(true), Float.NaN); - assertEquals(fs.getMaximumScore(true), Float.NaN); - assertEquals(fs.getMinimumScore(false), Float.NaN); - assertEquals(fs.getMaximumScore(false), Float.NaN); - } - - @Test(groups = "Functional") - public void testListContains() - { - FeatureStore featureStore = newFeatureStore(); - assertFalse(featureStore.listContains(null, null)); - List features = new ArrayList<>(); - assertFalse(featureStore.listContains(features, null)); - - SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f, - "group1"); - assertFalse(featureStore.listContains(null, sf1)); - assertFalse(featureStore.listContains(features, sf1)); - - features.add(sf1); - SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f, - "group1"); - SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f, - "group1"); - - // sf2.equals(sf1) so contains should return true - assertTrue(featureStore.listContains(features, sf2)); - assertFalse(featureStore.listContains(features, sf3)); - } - - @Test(groups = "Functional") - public void testGetFeaturesForGroup() - { - FeatureStore fs = newFeatureStore(); - - /* - * with no features - */ - assertTrue(fs.getFeaturesForGroup(true, null).isEmpty()); - assertTrue(fs.getFeaturesForGroup(false, null).isEmpty()); - assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty()); - assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty()); - - /* - * sf1: positional feature in the null group - */ - SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f, - null); - fs.addFeature(sf1); - assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty()); - assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty()); - assertTrue(fs.getFeaturesForGroup(false, null).isEmpty()); - List features = fs.getFeaturesForGroup(true, null); - assertEquals(features.size(), 1); - assertTrue(features.contains(sf1)); - - /* - * sf2: non-positional feature in the null group - * sf3: positional feature in a non-null group - * sf4: non-positional feature in a non-null group - */ - SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f, - null); - SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f, - "Uniprot"); - SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f, - "Rfam"); - fs.addFeature(sf2); - fs.addFeature(sf3); - fs.addFeature(sf4); - - features = fs.getFeaturesForGroup(true, null); - assertEquals(features.size(), 1); - assertTrue(features.contains(sf1)); - - features = fs.getFeaturesForGroup(false, null); - assertEquals(features.size(), 1); - assertTrue(features.contains(sf2)); - - features = fs.getFeaturesForGroup(true, "Uniprot"); - assertEquals(features.size(), 1); - assertTrue(features.contains(sf3)); - - features = fs.getFeaturesForGroup(false, "Rfam"); - assertEquals(features.size(), 1); - assertTrue(features.contains(sf4)); - } - - @Test(groups = "Functional") - public void testShiftFeatures() - { - FeatureStore fs = newFeatureStore(); - assertFalse(fs.shiftFeatures(0, 1)); // nothing to do - - SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null); - fs.addFeature(sf1); - // nested feature: - SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null); - fs.addFeature(sf2); - // contact feature: - SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32, - 0f, null); - fs.addFeature(sf3); - // non-positional feature: - SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null); - fs.addFeature(sf4); - - /* - * shift all features right by 5 - */ - assertTrue(fs.shiftFeatures(0, 5)); - - // non-positional features untouched: - List nonPos = fs.getNonPositionalFeatures(); - assertEquals(nonPos.size(), 1); - assertTrue(nonPos.contains(sf4)); - - // positional features are replaced - List pos = fs.getPositionalFeatures(); - assertEquals(pos.size(), 3); - assertFalse(pos.contains(sf1)); - assertFalse(pos.contains(sf2)); - assertFalse(pos.contains(sf3)); - SequenceFeatures.sortFeatures(pos, true); // ascending start pos - assertEquals(pos.get(0).getBegin(), 7); - assertEquals(pos.get(0).getEnd(), 10); - assertEquals(pos.get(1).getBegin(), 13); - assertEquals(pos.get(1).getEnd(), 19); - assertEquals(pos.get(2).getBegin(), 28); - assertEquals(pos.get(2).getEnd(), 37); - - /* - * now shift left by 15 - * feature at [7-10] should be removed - * feature at [13-19] should become [1-4] - */ - assertTrue(fs.shiftFeatures(0, -15)); - pos = fs.getPositionalFeatures(); - assertEquals(pos.size(), 2); - SequenceFeatures.sortFeatures(pos, true); - assertEquals(pos.get(0).getBegin(), 1); - assertEquals(pos.get(0).getEnd(), 4); - assertEquals(pos.get(1).getBegin(), 13); - assertEquals(pos.get(1).getEnd(), 22); - - /* - * shift right by 4 from position 2 onwards - * feature at [1-4] unchanged, feature at [13-22] shifts - */ - assertTrue(fs.shiftFeatures(2, 4)); - pos = fs.getPositionalFeatures(); - assertEquals(pos.size(), 2); - SequenceFeatures.sortFeatures(pos, true); - assertEquals(pos.get(0).getBegin(), 1); - assertEquals(pos.get(0).getEnd(), 4); - assertEquals(pos.get(1).getBegin(), 17); - assertEquals(pos.get(1).getEnd(), 26); - - /* - * shift right by 4 from position 18 onwards - * should be no change - */ - SequenceFeature f1 = pos.get(0); - SequenceFeature f2 = pos.get(1); - assertFalse(fs.shiftFeatures(18, 4)); // no update - pos = fs.getPositionalFeatures(); - assertEquals(pos.size(), 2); - SequenceFeatures.sortFeatures(pos, true); - assertSame(pos.get(0), f1); - assertSame(pos.get(1), f2); - } - - @Test(groups = "Functional") - public void testDelete_readd() - { - /* - * add a feature and a nested feature - */ - FeatureStore store = newFeatureStore(); - SequenceFeature sf1 = addFeature(store, 10, 20); - // sf2 is nested in sf1 so will be stored in nestedFeatures - SequenceFeature sf2 = addFeature(store, 12, 14); - List features = store.getPositionalFeatures(); - assertEquals(features.size(), 2); - assertTrue(features.contains(sf1)); - assertTrue(features.contains(sf2)); - assertTrue(store.getFeatures().contains(sf1)); - assertTrue(store.getFeatures().contains(sf2)); - - /* - * delete the first feature - */ - assertTrue(store.delete(sf1)); - features = store.getPositionalFeatures(); - assertFalse(features.contains(sf1)); - assertTrue(features.contains(sf2)); - - /* - * re-add the 'nested' feature; is it now duplicated? - */ - store.addFeature(sf2); - features = store.getPositionalFeatures(); - assertEquals(features.size(), 1); - assertTrue(features.contains(sf2)); - } - - @Test(groups = "Functional") - public void testContains() - { - FeatureStore fs = newFeatureStore(); - SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20, - Float.NaN, "group1"); - SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20, - Float.NaN, "group2"); - SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, - "group1"); - SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, - "group1"); - SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15, - Float.NaN, "group1"); - SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15, - Float.NaN, "group2"); - - fs.addFeature(sf1); - fs.addFeature(sf3); - fs.addFeature(sf5); - assertTrue(fs.contains(sf1)); // positional feature - assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature - assertFalse(fs.contains(sf2)); // different group - assertTrue(fs.contains(sf3)); // non-positional - assertTrue(fs.contains(new SequenceFeature(sf3))); - assertFalse(fs.contains(sf4)); // different score - assertTrue(fs.contains(sf5)); // contact feature - assertTrue(fs.contains(new SequenceFeature(sf5))); - assertFalse(fs.contains(sf6)); // different group - - /* - * add a nested feature - */ - SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16, - Float.NaN, "group1"); - fs.addFeature(sf7); - assertTrue(fs.contains(sf7)); - assertTrue(fs.contains(new SequenceFeature(sf7))); - - /* - * delete the outer (enclosing, non-nested) feature - */ - fs.delete(sf1); - assertFalse(fs.contains(sf1)); - assertTrue(fs.contains(sf7)); - } -} diff --git a/test/jalview/datamodel/features/FeatureStoreLinkedTest.java b/test/jalview/datamodel/features/FeatureStoreLinkedTest.java index 74c413f..e53ae3c 100644 --- a/test/jalview/datamodel/features/FeatureStoreLinkedTest.java +++ b/test/jalview/datamodel/features/FeatureStoreLinkedTest.java @@ -6,6 +6,7 @@ import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; import jalview.datamodel.SequenceFeature; +import jalview.datamodel.features.FeatureStore.IntervalStoreType; import java.util.ArrayList; import java.util.List; @@ -13,13 +14,14 @@ import java.util.Set; import org.testng.annotations.Test; +/** + * Tests that exercise the 'linked list' version of IntervalStore + */ public class FeatureStoreLinkedTest { - private FeatureStore newFeatureStore() { - return new FeatureStore( - FeatureStore.INTERVAL_STORE_LINKED_LIST); + return new FeatureStore(IntervalStoreType.INTERVAL_STORE_LINKED_LIST); } @Test(groups = "Functional") diff --git a/test/jalview/datamodel/features/FeatureStoreNCListBufferTest.java b/test/jalview/datamodel/features/FeatureStoreNCListBufferTest.java index 66cd892..527beb8 100644 --- a/test/jalview/datamodel/features/FeatureStoreNCListBufferTest.java +++ b/test/jalview/datamodel/features/FeatureStoreNCListBufferTest.java @@ -6,6 +6,7 @@ import static org.testng.Assert.assertSame; import static org.testng.Assert.assertTrue; import jalview.datamodel.SequenceFeature; +import jalview.datamodel.features.FeatureStore.IntervalStoreType; import java.util.ArrayList; import java.util.List; @@ -13,13 +14,14 @@ import java.util.Set; import org.testng.annotations.Test; +/** + * Tests that exercise the 'NC array' implementation of IntervalStore + */ public class FeatureStoreNCListBufferTest { - private FeatureStore newFeatureStore() { - return new FeatureStore( - FeatureStore.INTERVAL_STORE_NCARRAY); + return new FeatureStore(IntervalStoreType.INTERVAL_STORE_NCARRAY); } @Test(groups = "Functional") diff --git a/test/jalview/datamodel/features/FeatureStoreJavaTest.java b/test/jalview/datamodel/features/FeatureStoreTest.java similarity index 99% rename from test/jalview/datamodel/features/FeatureStoreJavaTest.java rename to test/jalview/datamodel/features/FeatureStoreTest.java index efcef68..2eba1c3 100644 --- a/test/jalview/datamodel/features/FeatureStoreJavaTest.java +++ b/test/jalview/datamodel/features/FeatureStoreTest.java @@ -13,7 +13,7 @@ import java.util.Set; import org.testng.annotations.Test; -public class FeatureStoreJavaTest +public class FeatureStoreTest { private FeatureStore newFeatureStore() { -- 1.7.10.2