JAL-3383 JAL-3253-applet
[jalview.git] / src / jalview / datamodel / features / FeatureStoreJS.java
index 3afbfb2..bd50420 100644 (file)
@@ -23,8 +23,6 @@ package jalview.datamodel.features;
 import jalview.datamodel.SequenceFeature;
 
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
 import java.util.List;
 
 /**
@@ -40,11 +38,16 @@ public class FeatureStoreJS extends FeatureStore
   boolean contactsTainted = true;
 
   /**
+   * internal reference to features as an ArrayList
+   */
+  private ArrayList<SequenceFeature> featureList;
+
+  /**
    * Constructor
    */
   public FeatureStoreJS()
   {
-    features = new ArrayList<>();
+    features = featureList = new ArrayList<>();
   }
 
   /**
@@ -72,6 +75,16 @@ public class FeatureStoreJS extends FeatureStore
   }
 
   /**
+   * Adds one feature to the IntervalStore that can manage nested features
+   * (creating the IntervalStore if necessary)
+   */
+  @Override
+  protected synchronized void addNestedFeature(SequenceFeature feature)
+  {
+    featureList.add(findFirstBegin(featureList, feature.begin), feature);
+  }
+
+  /**
    * Returns a (possibly empty) list of features whose extent overlaps the given
    * range. The returned list is not ordered. Contact features are included if
    * either of the contact points lies within the range.
@@ -103,7 +116,7 @@ public class FeatureStoreJS extends FeatureStore
         findContactFeatures(start, end, result);
       }
     }
-    if (features.size() > 0)
+    if (featureList.size() > 0)
     {
       findOverlaps(start, end, result);
     }
@@ -140,38 +153,29 @@ public class FeatureStoreJS extends FeatureStore
 
   private void rebuildArrays(int n)
   {
-    if (startComp == null)
-    {
-      startComp = new StartComparator();
-    }
-    orderedFeatureStarts = new SequenceFeature[n];
-    for (int i = n; --i >= 0;)
-    {
-      SequenceFeature sf = ((ArrayList<SequenceFeature>) features).get(i);
-      sf.index = i; // for debugging only
-      orderedFeatureStarts[i] = sf;
-    }
-    Arrays.sort(orderedFeatureStarts, startComp);
+    // Arrays.sort(orderedFeatureStarts, startComp);
+    orderedFeatureStarts = featureList
+            .toArray(new SequenceFeature[featureList.size()]);
     linkFeatures(orderedFeatureStarts);
   }
 
-  /**
-   * just a standard Comparator
-   */
-  private static StartComparator startComp;
-
-  class StartComparator implements Comparator<SequenceFeature>
-  {
-
-    @Override
-    public int compare(SequenceFeature o1, SequenceFeature o2)
-    {
-      int p1 = o1.begin;
-      int p2 = o2.begin;
-      return (p1 < p2 ? -1 : p1 > p2 ? 1 : 0);
-    }
-
-  }
+  // /**
+  // * just a standard Comparator
+  // */
+  // private static StartComparator startComp;
+  //
+  // class StartComparator implements Comparator<SequenceFeature>
+  // {
+  //
+  // @Override
+  // public int compare(SequenceFeature o1, SequenceFeature o2)
+  // {
+  // int p1 = o1.begin;
+  // int p2 = o2.begin;
+  // return (p1 < p2 ? -1 : p1 > p2 ? 1 : 0);
+  // }
+  //
+  // }
 
   /**
    * Run through the sorted sequence array once, building the containedBy linked
@@ -283,20 +287,20 @@ public class FeatureStoreJS extends FeatureStore
    * Find all overlaps; special case when there is only one feature. The
    * required array of start-sorted SequenceFeature is created lazily.
    * 
-   * @param features
-   * @param pos
+   * @param start
+   * @param end
    * @param result
    */
   private void findOverlaps(long start, long end,
           List<SequenceFeature> result)
   {
-    int n = features.size();
+    int n = featureList.size();
     switch (n)
     {
     case 0:
       return;
     case 1:
-      checkOne(((ArrayList<SequenceFeature>) features).get(0), start, end,
+      checkOne(featureList.get(0), start, end,
               result);
       return;
     default:
@@ -357,6 +361,30 @@ public class FeatureStoreJS extends FeatureStore
     return;
   }
 
+  @Override
+  protected boolean containsFeature(SequenceFeature feature)
+  {
+
+    int pos = findFirstBegin(featureList,
+            feature.begin);
+    int len = featureList.size();
+    while (pos < len)
+    {
+      SequenceFeature sf = featureList.get(pos);
+      if (sf.begin > feature.begin)
+      {
+        return false; // no match found
+      }
+      if (sf.equals(feature))
+      {
+        return true;
+      }
+      pos++;
+    }
+    return false;
+
+  }
+
   /**
    * A binary search identical to the one used for contact start/end, but here
    * we return the feature itself. Unlike Collection.BinarySearch, all we have