1 package jalview.datamodel.features;
3 import jalview.datamodel.ContiguousI;
5 import java.util.ArrayList;
9 * Each node of the NCList tree consists of a range, and (optionally) the NCList
10 * of ranges it encloses
14 class NCNode<V extends ContiguousI> implements ContiguousI
17 * deep size (number of ranges included)
24 * null, or an object holding contained subregions of this nodes region
26 private NCList<V> subregions;
29 * Constructor given a list of ranges
33 NCNode(List<V> ranges)
39 * Constructor given a single range
45 List<V> ranges = new ArrayList<>();
50 NCNode(V entry, NCList<V> newNCList)
53 subregions = newNCList;
54 size = 1 + newNCList.size();
60 protected void build(List<V> ranges)
64 if (!ranges.isEmpty())
66 region = ranges.get(0);
68 if (ranges.size() > 1)
70 subregions = new NCList<V>(ranges.subList(1, ranges.size()));
77 return region.getBegin();
83 return region.getEnd();
87 * Formats the node as a bracketed list e.g.
90 * [1-100 [10-30 [10-20]], 15-30 [20-20]]
94 public String toString() {
95 StringBuilder sb = new StringBuilder(10 * size);
96 sb.append(region.getBegin()).append("-").append(region.getEnd());
97 if (subregions != null)
99 sb.append(" ").append(subregions.toString());
101 return sb.toString();
104 void prettyPrint(StringBuilder sb, int offset, int indent) {
105 for (int i = 0 ; i < offset ; i++) {
108 sb.append(region.getBegin()).append("-").append(region.getEnd());
109 if (subregions != null)
111 sb.append(System.lineSeparator());
112 subregions.prettyPrint(sb, offset + 2, indent);
116 * Add any ranges that overlap the from-to range to the result list
122 void findOverlaps(long from, long to, List<V> result)
124 if (region.getBegin() <= to && region.getEnd() >= from)
128 if (subregions != null)
130 subregions.findOverlaps(from, to, result);
135 * Add one range to this subrange
139 synchronized void add(V entry)
141 if (entry.getBegin() < region.getBegin() || entry.getEnd() > region.getEnd()) {
142 throw new IllegalArgumentException(String.format(
143 "adding improper subrange %d-%d to range %d-%d",
144 entry.getBegin(), entry.getEnd(), region.getBegin(),
147 if (subregions == null)
149 subregions = new NCList<V>(entry);
153 subregions.add(entry);
159 * Answers true if the data held satisfy the rules of construction of an
160 * NCList, else false.
167 * we don't handle reverse ranges
169 if (region != null && region.getBegin() > region.getEnd())
173 if (subregions == null)
177 return subregions.isValid(getBegin(), getEnd());
181 * Adds all contained entries to the given list
185 void getEntries(List<V> entries)
188 if (subregions != null)
190 subregions.getEntries(entries);
195 * Answers true if this object contains the given entry (by object equals
201 boolean contains(V entry)
207 if (entry.equals(region))
211 return subregions == null ? false : subregions.contains(entry);
215 * Answers the 'root' region modelled by this object
225 * Answers the (possibly null) contained regions within this object
229 NCList<V> getSubRegions()
235 * Nulls the subregion reference if it is empty (after a delete entry
238 void deleteSubRegionsIfEmpty()
240 if (subregions != null && subregions.size() == 0)
247 * Answers the (deep) size of this node i.e. the number of ranges it models