package org.netxilia.api.impl.utils.intervals; import java.util.ArrayList; import java.util.List; import java.util.Map; public class IntervalTree<V> extends TreeMap<Interval, V> { private static final long serialVersionUID = 1L; public void recalculate() { if (getRoot() != null) { recalculate(getRoot()); } } private void recalculate(Entry<Interval, V> entry) { int min = entry.getKey().getStart(); int max = entry.getKey().getEnd(); if (entry.left != null) { recalculate(entry.left); max = Math.max(max, entry.left.key.getMax()); min = Math.min(min, entry.left.key.getMin()); } if (entry.right != null) { recalculate(entry.right); max = Math.max(max, entry.right.key.getMax()); min = Math.min(min, entry.right.key.getMin()); } entry.getKey().setMin(min); entry.getKey().setMax(max); } public List<Interval> searchIntervals(Interval search) { List<Map.Entry<Interval, V>> results = new ArrayList<Map.Entry<Interval, V>>(); search(getRoot(), search, results); List<Interval> intervals = new ArrayList<Interval>(results.size()); for (Map.Entry<Interval, V> entry : results) { intervals.add(entry.getKey()); } return intervals; } public List<Map.Entry<Interval, V>> searchEntries(Interval search) { List<Map.Entry<Interval, V>> results = new ArrayList<Map.Entry<Interval, V>>(); search(getRoot(), search, results); return results; } private void search(Entry<Interval, V> entry, Interval search, List<Map.Entry<Interval, V>> result) { // Don't search nodes that don't exist if (entry == null) { return; } // Search left children if (entry.left != null && entry.left.key.getMax() >= search.getStart()) { search(entry.left, search, result); } // Check this node if (entry.key.intersects(search)) { result.add(entry); } // Otherwise, search right children if (entry.right != null && entry.right.key.getMin() <= search.getEnd()) { search(entry.right, search, result); } } }