JAL-3397 final update
[jalview.git] / src / jalview / datamodel / features / FeatureStore.java
index 1451892..75ec45a 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.datamodel.features;
 
 import jalview.datamodel.SequenceFeature;
+import jalview.util.Platform;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -29,13 +30,96 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import intervalstore.api.IntervalStoreI;
+
 public abstract class FeatureStore implements FeatureStoreI
 {
 
   /**
    * track last start for quick insertion of ordered features
    */
-  protected int lastStart = -1, lastContactStart = -1;
+  protected int lastStart = -1;
+
+  protected int lastContactStart = -1;
+
+  /*
+   * Non-positional features have no (zero) start/end position.
+   * Kept as a separate list in case this criterion changes in future.
+   */
+  List<SequenceFeature> nonPositionalFeatures;
+
+  /*
+   * contact features ordered by first contact position
+   */
+  List<SequenceFeature> contactFeatureStarts;
+
+  /*
+   * contact features ordered by second contact position
+   */
+  List<SequenceFeature> contactFeatureEnds;
+
+  /*
+   * IntervalStore holds remaining features and provides efficient
+   * query for features overlapping any given interval
+   */
+  IntervalStoreI<SequenceFeature> features;
+
+  /*
+   * Feature groups represented in stored positional features 
+   * (possibly including null)
+   */
+  Set<String> positionalFeatureGroups;
+
+  /*
+   * Feature groups represented in stored non-positional features 
+   * (possibly including null)
+   */
+  Set<String> nonPositionalFeatureGroups;
+
+  /*
+   * the total length of all positional features; contact features count 1 to
+   * the total and 1 to size(), consistent with an average 'feature length' of 1
+   */
+  int totalExtent;
+
+  float positionalMinScore;
+
+  float positionalMaxScore;
+
+  float nonPositionalMinScore;
+
+  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_PRESORT = 1;
+
+  /**
+   * linked-list IntervalStore
+   */
+  public final static int INTERVAL_STORE_LINKED_LIST_NO_PRESORT = 2;
+
+  /**
+   * NCList as array buffer IntervalStore
+   */
+  public final static int INTERVAL_STORE_NCLIST_BUFFER_PRESORT = 3;
+
+  /**
+   * NCList as array buffer IntervalStore
+   */
+  public final static int INTERVAL_STORE_NCLIST_BUFFER_NO_PRESORT = 4;
+
+  static final int intervalStoreJavaOption = INTERVAL_STORE_NCLIST_OBJECT;
+
+  static final int intervalStoreJSOption = INTERVAL_STORE_NCLIST_BUFFER_PRESORT;
 
   /**
    * Answers the 'length' of the feature, counting 0 for non-positional features
@@ -151,59 +235,20 @@ public abstract class FeatureStore implements FeatureStoreI
     }
   }
 
-  /*
-   * Non-positional features have no (zero) start/end position.
-   * Kept as a separate list in case this criterion changes in future.
-   */
-  List<SequenceFeature> nonPositionalFeatures;
-
-  /*
-   * contact features ordered by first contact position
-   */
-  List<SequenceFeature> contactFeatureStarts;
-
-  /*
-   * contact features ordered by second contact position
-   */
-  List<SequenceFeature> contactFeatureEnds;
-
-  /*
-   * IntervalStore holds remaining features and provides efficient
-   * query for features overlapping any given interval
-   */
-  Collection<SequenceFeature> features;
-
-  /*
-   * Feature groups represented in stored positional features 
-   * (possibly including null)
-   */
-  Set<String> positionalFeatureGroups;
-
-  /*
-   * Feature groups represented in stored non-positional features 
-   * (possibly including null)
-   */
-  Set<String> nonPositionalFeatureGroups;
-
-  /*
-   * the total length of all positional features; contact features count 1 to
-   * the total and 1 to size(), consistent with an average 'feature length' of 1
+  /**
+   * standard constructor
    */
-  int totalExtent;
-
-  float positionalMinScore;
-
-  float positionalMaxScore;
-
-  float nonPositionalMinScore;
-
-  float nonPositionalMaxScore;
+  public FeatureStore()
+  {
+    this(INTERVAL_STORE_DEFAULT);
+  }
 
   /**
-   * Constructor
+   * constructor for testing only
    */
-  public FeatureStore()
+  public FeatureStore(int intervalStoreType)
   {
+    features = getIntervalStore(intervalStoreType);
     positionalFeatureGroups = new HashSet<>();
     nonPositionalFeatureGroups = new HashSet<>();
     positionalMinScore = Float.NaN;
@@ -214,6 +259,27 @@ public abstract class FeatureStore implements FeatureStoreI
     // we only construct nonPositionalFeatures, contactFeatures if we need to
   }
 
+  private IntervalStoreI<SequenceFeature> getIntervalStore(int type)
+  {
+    switch (type != INTERVAL_STORE_DEFAULT ? type : //
+    Platform.isJS() //
+            ? intervalStoreJSOption
+            : intervalStoreJavaOption)
+    {
+    default:
+    case INTERVAL_STORE_NCLIST_OBJECT:
+      return new intervalstore.impl.IntervalStore<>();
+    case INTERVAL_STORE_NCLIST_BUFFER_PRESORT:
+      return new intervalstore.nonc.IntervalStore<>(true);
+    case INTERVAL_STORE_NCLIST_BUFFER_NO_PRESORT:
+      return new intervalstore.nonc.IntervalStore<>(false);
+    case INTERVAL_STORE_LINKED_LIST_PRESORT:
+      return new intervalstore.nonc.IntervalStore0<>(true);
+    case INTERVAL_STORE_LINKED_LIST_NO_PRESORT:
+      return new intervalstore.nonc.IntervalStore0<>(false);
+    }
+  }
+
   /**
    * Add a contact feature to the lists that hold them ordered by start (first
    * contact) and by end (second contact) position, ensuring the lists remain
@@ -303,7 +369,6 @@ public abstract class FeatureStore implements FeatureStoreI
         return false;
       }
       positionalFeatureGroups.add(feature.getFeatureGroup());
-      // addPositionalFeature(feature);
       if (feature.begin > lastStart)
       {
         lastStart = feature.begin;