JAL-3383 JAL-3397 JAL-3253-applet IntervalStore options
[jalview.git] / src / jalview / datamodel / features / FeatureStore.java
index ccd8b66..8db35a3 100644 (file)
@@ -57,38 +57,52 @@ public abstract class FeatureStore implements FeatureStoreI
    * optimised for the condition that the list is sorted on feature start
    * position ascending, and will give unreliable results if this does not hold.
    * 
-   * @param features
+   * @param list
    * @param feature
    * @return
    */
   @Override
-  public boolean listContains(List<SequenceFeature> features,
+  public boolean listContains(List<SequenceFeature> list,
           SequenceFeature feature)
   {
-    if (features == null || feature == null)
+    if (list == null || feature == null)
     {
       return false;
     }
 
+    return (getEquivalentFeatureIndex(list, feature) >= 0);
+  }
+
+  /**
+   * Binary search for the index (&gt;= 0) of a feature in a list.
+   * 
+   * @param list
+   * @param feature
+   * @return index if found; -1 if not
+   */
+  protected int getEquivalentFeatureIndex(List<SequenceFeature> list,
+          SequenceFeature feature)
+  {
+
     /*
      * locate the first entry in the list which does not precede the feature
      */
-    int pos = findFirstBegin(features, feature.begin);
-    int len = features.size();
+    int pos = findFirstBegin(list, feature.begin);
+    int len = list.size();
     while (pos < len)
     {
-      SequenceFeature sf = features.get(pos);
-      if (sf.getBegin() > feature.getBegin())
+      SequenceFeature sf = list.get(pos);
+      if (sf.begin > feature.begin)
       {
-        return false; // no match found
+        return -1; // no match found
       }
       if (sf.equals(feature))
       {
-        return true;
+        return pos;
       }
       pos++;
     }
-    return false;
+    return -1;
   }
 
   /**
@@ -262,7 +276,7 @@ public abstract class FeatureStore implements FeatureStoreI
     }
     else
     {
-      addNestedFeature(feature);
+      addPositionalFeature(feature);
     }
 
     /*
@@ -316,7 +330,7 @@ public abstract class FeatureStore implements FeatureStoreI
    * Adds one feature to the IntervalStore that can manage nested features
    * (creating the IntervalStore if necessary)
    */
-  abstract protected void addNestedFeature(SequenceFeature feature);
+  abstract protected void addPositionalFeature(SequenceFeature feature);
 
   /**
    * Adds the feature to the list of non-positional features (with lazy
@@ -396,15 +410,12 @@ public abstract class FeatureStore implements FeatureStoreI
       }
     }
 
-    boolean removedNonPositional = false;
-
     /*
      * if not found, try non-positional features
      */
     if (!removed && nonPositionalFeatures != null)
     {
-      removedNonPositional = nonPositionalFeatures.remove(sf);
-      removed = removedNonPositional;
+      removed = nonPositionalFeatures.remove(sf);
     }
 
     /*
@@ -412,7 +423,7 @@ public abstract class FeatureStore implements FeatureStoreI
      */
     if (!removed && features != null)
     {
-      removed = features.remove(sf);
+      removed = findAndRemoveNonContactFeature(sf);
     }
 
     if (removed)
@@ -423,6 +434,8 @@ public abstract class FeatureStore implements FeatureStoreI
     return removed;
   }
 
+  abstract protected boolean findAndRemoveNonContactFeature(SequenceFeature sf);
+
   abstract protected void findContactFeatures(long from, long to,
           List<SequenceFeature> result);
 
@@ -690,8 +703,10 @@ public abstract class FeatureStore implements FeatureStoreI
      */
     if (nonPositionalFeatures != null)
     {
-      for (SequenceFeature sf : nonPositionalFeatures)
+      List<SequenceFeature> list = nonPositionalFeatures;
+      for (int i = 0, n = list.size(); i < n; i++)
       {
+        SequenceFeature sf = list.get(i);
         nonPositionalFeatureGroups.add(sf.getFeatureGroup());
         float score = sf.getScore();
         nonPositionalMinScore = min(nonPositionalMinScore, score);
@@ -742,8 +757,10 @@ public abstract class FeatureStore implements FeatureStoreI
      * (Although a simple shift of all values would preserve data integrity!)
      */
     boolean modified = false;
-    for (SequenceFeature sf : getPositionalFeatures())
+    List<SequenceFeature> list = getPositionalFeatures();
+    for (int i = 0, n = list.size(); i < n; i++)
     {
+      SequenceFeature sf = list.get(i);
       if (sf.getBegin() >= fromPosition)
       {
         modified = true;