import intervalstore.api.IntervalI;
import intervalstore.api.IntervalStoreI;
+import intervalstore.impl.BinarySearcher.Compare;
/**
* A collection class to store interval-associated data, with O(log N)
}
/**
- * Adds one interval to the store.
+ * Adds one interval to the store. Answers true unless the feature is a
+ * duplicate (already contained), in which case it is not added.
*
* @param interval
*/
@Override
public boolean add(T interval)
{
+ return add(interval, true);
+ }
+
+ @Override
+ public boolean add(T interval, boolean allowDuplicates)
+ {
if (interval == null)
{
return false;
}
+ if (!allowDuplicates && contains(interval))
+ {
+ return false;
+ }
+
if (!addNonNestedInterval(interval))
{
/*
/*
* find the first stored interval which doesn't precede the new one
*/
- int insertPosition = BinarySearcher.findFirst(nonNested,
- val -> val.getBegin() >= entry.getBegin());
+ int insertPosition = BinarySearcher.findFirst(nonNested, true,
+ Compare.GE, entry.getBegin());
/*
* fail if we detect interval enclosure
* - of the new interval by the one before or after it
@Override
public List<T> findOverlaps(long from, long to)
{
- List<T> result = new ArrayList<>();
+ return findOverlaps(from, to, new ArrayList<>());
+ }
+
+ @Override
+ public List<T> findOverlaps(long from, long to, List<T> result)
+ {
+ if (result == null)
+ {
+ result = new ArrayList<>();
+ }
findNonNestedOverlaps(from, to, result);
if (nested != null)
{
- result.addAll(nested.findOverlaps(from, to));
+ nested.findOverlaps(from, to, result);
}
return result;
return pp;
}
- @Override
+ /**
+ * Inspects the data store and answers true if it is validly constructed, else
+ * false. Provided for use in verification by test classes. *
+ *
+ * @return
+ */
public boolean isValid()
{
for (int i = 0; i < nonNested.size() - 1; i++)
* start position is not less than the target range start
* (NB inequality test ensures the first match if any is found)
*/
- int startIndex = BinarySearcher.findFirst(nonNested,
- val -> val.getBegin() >= entry.getBegin());
+ int startIndex = BinarySearcher.findFirst(nonNested, true, Compare.GE,
+ entry.getBegin());
/*
* traverse intervals to look for a match
return false;
}
+ /**
+ * Answers 0 if the store is empty, 1 if there are only top level intervals,
+ * else 1 plus the depth of the nested intervals (NCList)
+ */
@Override
public int getDepth()
{
/*
* locate the first entry in the list which does not precede the interval
*/
- int pos = BinarySearcher.findFirst(intervals,
- val -> val.getBegin() >= interval.getBegin());
+ int pos = BinarySearcher.findFirst(intervals, true, Compare.GE,
+ interval.getBegin());
int len = intervals.size();
while (pos < len)
{
* find the first interval whose end position is
* after the target range start
*/
- int startIndex = BinarySearcher.findFirst(nonNested,
- val -> val.getEnd() >= from);
+ int startIndex = BinarySearcher.findFirst(nonNested, false, Compare.GE,
+ (int) from);
final int startIndex1 = startIndex;
int i = startIndex1;