JAL-2446 FeatureStore with NCList - work in progress
[jalview.git] / src / jalview / datamodel / features / NCNode.java
1 package jalview.datamodel.features;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 /**
7  * Each node of the NCList tree consists of a range, and (optionally) the NCList
8  * of ranges it encloses
9  *
10  * @param <V>
11  */
12 class NCNode<V extends ContiguousI>
13 {
14   /*
15    * deep size (number of ranges included)
16    */
17   private int size;
18
19   private V region;
20
21   private NCList<V> subregions;
22
23   /**
24    * Constructor
25    * 
26    * @param ranges
27    */
28   NCNode(List<V> ranges)
29   {
30     build(ranges);
31   }
32
33   /**
34    * Constructo
35    * 
36    * @param range
37    */
38   NCNode(V range)
39   {
40     List<V> ranges = new ArrayList<V>();
41     ranges.add(range);
42     build(ranges);
43   }
44
45   /**
46    * @param ranges
47    */
48   protected void build(List<V> ranges)
49   {
50     size = ranges.size();
51
52     if (!ranges.isEmpty())
53     {
54       region = ranges.get(0);
55     }
56     if (ranges.size() > 1)
57     {
58       subregions = new NCList<V>(ranges.subList(1, ranges.size()));
59     }
60   }
61
62   int getStart()
63   {
64     return region.getBegin();
65   }
66
67   int getEnd()
68   {
69     return region.getEnd();
70   }
71
72   @Override
73   public String toString() {
74     StringBuilder sb = new StringBuilder(10 * size);
75     sb.append(region.getBegin()).append("-").append(region.getEnd());
76     if (subregions != null)
77     {
78       sb.append(" ").append(subregions.toString());
79     }
80     return sb.toString();
81   }
82
83   /**
84    * Add any ranges that overlap the from-to range to the result list
85    * 
86    * @param from
87    * @param to
88    * @param result
89    */
90   void addOverlaps(long from, long to, List<V> result)
91   {
92     if (region.getBegin() <= to && region.getEnd() >= from)
93     {
94       result.add(region);
95     }
96     if (subregions != null)
97     {
98       subregions.findOverlaps(from, to, result);
99     }
100   }
101
102   /**
103    * Add one range to this subrange
104    * 
105    * @param entry
106    */
107   public synchronized void add(V entry)
108   {
109     if (entry.getBegin() < region.getBegin() || entry.getEnd() > region.getEnd()) {
110       throw new IllegalArgumentException(String.format(
111               "adding improper subrange %d-%d to range %d-%d",
112               entry.getBegin(), entry.getEnd(), region.getBegin(),
113               region.getEnd()));
114     }
115     if (subregions == null)
116     {
117       subregions = new NCList<V>(entry);
118     }
119     else
120     {
121       subregions.add(entry);
122     }
123   }
124 }