View Javadoc

1   /*--------------------------------------------------------------------------
2    *  Copyright 2010 utgenome.org
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *--------------------------------------------------------------------------*/
16  //--------------------------------------
17  // utgb-core Project
18  //
19  // IntervalTree.java
20  // Since: 2010/10/12
21  //
22  //--------------------------------------
23  package org.utgenome.gwt.utgb.client.canvas;
24  
25  import java.util.AbstractCollection;
26  import java.util.ArrayList;
27  import java.util.Iterator;
28  import java.util.List;
29  
30  import org.utgenome.gwt.utgb.client.bio.OnGenome;
31  import org.utgenome.gwt.utgb.client.canvas.PrioritySearchTree.ResultHandler;
32  import org.utgenome.gwt.utgb.client.util.Optional;
33  
34  /**
35   * Interval layout
36   * 
37   * @author leo
38   * 
39   */
40  public class IntervalTree<T extends OnGenome> extends AbstractCollection<T> {
41  
42  	private PrioritySearchTree<T> pst = new PrioritySearchTree<T>();
43  
44  	/**
45  	 * Add an entry [start, end)
46  	 * 
47  	 * @param elem
48  	 */
49  	@Override
50  	public boolean add(T elem) {
51  		// swap start and end when inserting to PST
52  		pst.insert(elem, elem.getEnd(), elem.getStart());
53  		return true;
54  	}
55  
56  	public boolean remove(T t) {
57  		return pst.remove(t, t.getEnd(), t.getStart());
58  	}
59  
60  	public void overlapQuery(int start, PrioritySearchTree.ResultHandler<T> handler) {
61  		overlapQuery(start, start, handler);
62  	}
63  
64  	public List<T> overlapQuery(int start) {
65  		return overlapQuery(start, start);
66  	}
67  
68  	private class OverlapCounter implements ResultHandler<T> {
69  		int count = 0;
70  
71  		public void handle(T elem) {
72  			count++;
73  		}
74  
75  		public boolean toContinue() {
76  			return true;
77  		}
78  
79  	}
80  
81  	public int countOverlap(int start) {
82  		return countOverlap(start, start);
83  	}
84  
85  	public int countOverlap(int start, int end) {
86  		OverlapCounter c = new OverlapCounter();
87  		overlapQuery(start, end, c);
88  		return c.count;
89  	}
90  
91  	/**
92  	 * Get entries overlapping with [start, end)
93  	 * 
94  	 * @param start
95  	 *            query start (inclusive)
96  	 * @param end
97  	 *            query end (exclusive)
98  	 * @return
99  	 */
100 	public List<T> overlapQuery(int start, int end) {
101 		return pst.rangeQuery(start + 1, Integer.MAX_VALUE, end - 1);
102 	}
103 
104 	/**
105 	 * Get entries overlapping with [start, end)
106 	 * 
107 	 * @param start
108 	 *            query start (inclusive)
109 	 * @param end
110 	 *            query end (exclusive)
111 	 * @param handler
112 	 */
113 	public void overlapQuery(int start, int end, PrioritySearchTree.ResultHandler<T> handler) {
114 		pst.rangeQuery(start + 1, Integer.MAX_VALUE, end - 1, handler);
115 	}
116 
117 	public void overlapQuery(OnGenome target, PrioritySearchTree.ResultHandler<T> handler) {
118 		overlapQuery(target.getStart(), target.getEnd(), handler);
119 	}
120 
121 	public List<T> overlapQuery(OnGenome target) {
122 		return overlapQuery(target.getStart(), target.getEnd());
123 	}
124 
125 	public T findOverlap(OnGenome target) {
126 		final Optional<T> result = new Optional<T>();
127 		this.overlapQuery(target, new PrioritySearchTree.ResultHandler<T>() {
128 
129 			boolean toContinue = true;
130 
131 			public void handle(T overlappedEntry) {
132 				result.set(overlappedEntry);
133 				toContinue = false;
134 			}
135 
136 			public boolean toContinue() {
137 				return toContinue;
138 			}
139 		});
140 		return result.isDefined() ? result.get() : null;
141 	}
142 
143 	@Override
144 	public boolean isEmpty() {
145 		return pst.size() == 0;
146 	}
147 
148 	@Override
149 	public void clear() {
150 		pst.clear();
151 	}
152 
153 	/**
154 	 * Removes the intervals contained in [-oo, start)
155 	 * 
156 	 * @param start
157 	 */
158 	public void removeBefore(int start) {
159 		removeBefore(start, null);
160 	}
161 
162 	public void removeBefore(int start, PrioritySearchTree.ResultHandler<T> handler) {
163 		for (T each : pst.rangeQuery(Integer.MIN_VALUE, start, start - 1)) {
164 			if (handler != null)
165 				handler.handle(each);
166 			pst.remove(each, each.getEnd(), each.getStart());
167 		}
168 	}
169 
170 	@Override
171 	public Iterator<T> iterator() {
172 		return pst.iterator();
173 	}
174 
175 	/**
176 	 * return the elements in the tree
177 	 * 
178 	 * @return
179 	 */
180 	public List<T> elementList() {
181 		List<T> r = new ArrayList<T>(pst.size());
182 		for (T each : pst) {
183 			r.add(each);
184 		}
185 		return r;
186 	}
187 
188 	@Override
189 	public int size() {
190 		return pst.size();
191 	}
192 }