JAL-3383 tidy up NCList and alternatives
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 24 Sep 2019 10:24:02 +0000 (11:24 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 24 Sep 2019 10:24:02 +0000 (11:24 +0100)
14 files changed:
src/intervalstore/nonc/IntervalStore.java
src/intervalstore/nonc/IntervalStore0.java
src/intervalstore/nonc/IntervalStore0Impl.java [deleted file]
src/intervalstore/nonc/IntervalStoreImpl.java [deleted file]
src/jalview/analysis/CrossRef.java
src/jalview/datamodel/SequenceFeature.java
src/jalview/datamodel/features/FeatureStore.java
src/jalview/gui/AlignFrame.java
test/intervalstore/nonc/IntervalStore0Test.java
test/intervalstore/nonc/IntervalStoreTest.java
test/jalview/datamodel/features/FeatureStoreJSTest.java [deleted file]
test/jalview/datamodel/features/FeatureStoreLinkedTest.java
test/jalview/datamodel/features/FeatureStoreNCListBufferTest.java
test/jalview/datamodel/features/FeatureStoreTest.java [moved from test/jalview/datamodel/features/FeatureStoreJavaTest.java with 99% similarity]

index effbb55..b010340 100644 (file)
@@ -401,7 +401,7 @@ public class IntervalStore<T extends IntervalI>
       int pt0 = pt;
       while (--pt >= 0 && offsets[pt] == 0)
       {
-        ;
+        
       }
       if (pt < 0)
       {
@@ -1350,26 +1350,15 @@ public class IntervalStore<T extends IntervalI>
   }
 
   /**
-   * 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);
   }
 
index c998dc1..980383c 100644 (file)
@@ -358,7 +358,7 @@ public class IntervalStore0<T extends IntervalI>
       int pt0 = pt;
       while (--pt >= 0 && offsets[pt] == 0)
       {
-        ;
+        
       }
       if (pt < 0)
       {
@@ -1047,26 +1047,15 @@ public class IntervalStore0<T extends IntervalI>
   }
 
   /**
-   * 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 (file)
index ffcb722..0000000
+++ /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<T> 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 (file)
index 8456b7f..0000000
+++ /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<T> 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);
-  }
-
-}
index ed87f05..080f3e2 100644 (file)
@@ -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);
index 1af23a4..1f2e639 100755 (executable)
@@ -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));
   }
 
   /**
index 5c0336a..fff7127 100644 (file)
@@ -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<SequenceFeature> list,
+  public static boolean listContains(List<SequenceFeature> 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<SequenceFeature> getIntervalStore(int type)
+  private IntervalStoreI<SequenceFeature> 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);
   }
 
index 4d29919..597eb5b 100644 (file)
@@ -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",
index c3dfb17..c2d7864 100644 (file)
@@ -60,7 +60,7 @@ public class IntervalStore0Test
   @Test(groups = "Functional")
   public void testFindOverlaps_nonNested()
   {
-    IntervalStore0<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<? extends Object> list,
-          Object o)
-  {
-    for (Object i : list)
-    {
-      if (i == o)
-      {
-        return true;
-      }
-    }
-    return false;
-  }
-
   @Test(groups = "Functional")
   public void testAdd()
   {
-    IntervalStore0<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> store = new IntervalStore0<>();
 
     assertFalse(store.add(null));
 
@@ -315,7 +294,7 @@ public class IntervalStore0Test
   @Test(groups = "Functional")
   public void testAdd_noDuplicates()
   {
-    IntervalStore0<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> store = new IntervalStore0Impl();
+    IntervalStore0<SimpleFeature> 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<SimpleFeature> 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<SimpleFeature>) store)
+                .revalidate();
       }
       String line = "time to load " + (isNCList ? "NClist " : "NCArray ")
               + (System.nanoTime() - ntimeLoad) / K / K + " ms scale "
index 581f5f4..2c4e14b 100644 (file)
@@ -60,7 +60,7 @@ public class IntervalStoreTest
   @Test(groups = "Functional")
   public void testFindOverlaps_nonNested()
   {
-    IntervalStore<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<? extends Object> list,
-          Object o)
-  {
-    for (Object i : list)
-    {
-      if (i == o)
-      {
-        return true;
-      }
-    }
-    return false;
-  }
-
   @Test(groups = "Functional")
   public void testAdd()
   {
-    IntervalStore<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> store = new IntervalStore<>();
 
     assertFalse(store.add(null));
 
@@ -315,7 +294,7 @@ public class IntervalStoreTest
   @Test(groups = "Functional")
   public void testAdd_noDuplicates()
   {
-    IntervalStore<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature> store = new IntervalStoreImpl();
+    IntervalStore<SimpleFeature> 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<SimpleFeature>) 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 (file)
index 489ac38..0000000
+++ /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<SequenceFeature> 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<SequenceFeature> 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<SequenceFeature> 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<SequenceFeature> 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<SequenceFeature> 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<SequenceFeature> 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<String> 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<SequenceFeature> 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<SequenceFeature> 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<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
-    assertEquals(nonPos.size(), 1);
-    assertTrue(nonPos.contains(sf4));
-
-    // positional features are replaced
-    List<SequenceFeature> 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<SequenceFeature> 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));
-  }
-}
index 74c413f..e53ae3c 100644 (file)
@@ -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")
index 66cd892..527beb8 100644 (file)
@@ -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")
@@ -13,7 +13,7 @@ import java.util.Set;
 
 import org.testng.annotations.Test;
 
-public class FeatureStoreJavaTest
+public class FeatureStoreTest
 {
   private FeatureStore newFeatureStore()
   {