001 package gate.creole.annic.apache.lucene.index;
002
003 /**
004 * Copyright 2004 The Apache Software Foundation
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 import java.io.IOException;
020 import java.util.Arrays;
021 import java.util.Iterator;
022 import java.util.LinkedList;
023 import java.util.List;
024
025 import gate.creole.annic.apache.lucene.util.PriorityQueue;
026
027
028 /**
029 * Describe class <code>MultipleTermPositions</code> here.
030 *
031 * @author Anders Nielsen
032 * @version 1.0
033 */
034 public class MultipleTermPositions
035 implements TermPositions
036 {
037 private static final class TermPositionsQueue
038 extends PriorityQueue
039 {
040 TermPositionsQueue(List termPositions)
041 throws IOException
042 {
043 initialize(termPositions.size());
044
045 Iterator i = termPositions.iterator();
046 while (i.hasNext())
047 {
048 TermPositions tp = (TermPositions)i.next();
049 if (tp.next())
050 put(tp);
051 }
052 }
053
054 final TermPositions peek()
055 {
056 return (TermPositions)top();
057 }
058
059 public final boolean lessThan(Object a, Object b)
060 {
061 return ((TermPositions)a).doc() < ((TermPositions)b).doc();
062 }
063 }
064
065 private static final class IntQueue
066 {
067 private int _arraySize = 16;
068
069 private int _index = 0;
070 private int _lastIndex = 0;
071
072 private int[] _array = new int[_arraySize];
073
074 final void add(int i)
075 {
076 if (_lastIndex == _arraySize)
077 growArray();
078
079 _array[_lastIndex++] = i;
080 }
081
082 final int next()
083 {
084 return _array[_index++];
085 }
086
087 final void sort()
088 {
089 Arrays.sort(_array, _index, _lastIndex);
090 }
091
092 final void clear()
093 {
094 _index = 0;
095 _lastIndex = 0;
096 }
097
098 final int size()
099 {
100 return (_lastIndex-_index);
101 }
102
103 private void growArray()
104 {
105 int[] newArray = new int[_arraySize*2];
106 System.arraycopy(_array, 0, newArray, 0, _arraySize);
107 _array = newArray;
108 _arraySize *= 2;
109 }
110 }
111
112 private int _doc;
113 private int _freq;
114
115 private TermPositionsQueue _termPositionsQueue;
116 private IntQueue _posList;
117
118 /**
119 * Creates a new <code>MultipleTermPositions</code> instance.
120 *
121 * @param indexReader an <code>IndexReader</code> value
122 * @param terms a <code>Term[]</code> value
123 * @exception IOException if an error occurs
124 */
125 public MultipleTermPositions(IndexReader indexReader, Term[] terms)
126 throws IOException
127 {
128 List termPositions = new LinkedList();
129
130 for (int i=0; i<terms.length; i++)
131 termPositions.add(indexReader.termPositions(terms[i]));
132
133 _termPositionsQueue = new TermPositionsQueue(termPositions);
134 _posList = new IntQueue();
135 }
136
137 /**
138 * Describe <code>next</code> method here.
139 *
140 * @return a <code>boolean</code> value
141 * @exception IOException if an error occurs
142 * @see TermDocs#next()
143 */
144 public final boolean next()
145 throws IOException
146 {
147 if (_termPositionsQueue.size() == 0)
148 return false;
149
150 _posList.clear();
151 _doc = _termPositionsQueue.peek().doc();
152
153 TermPositions tp;
154 do
155 {
156 tp = _termPositionsQueue.peek();
157
158 for (int i=0; i<tp.freq(); i++)
159 _posList.add(tp.nextPosition());
160
161 if (tp.next())
162 _termPositionsQueue.adjustTop();
163 else
164 {
165 _termPositionsQueue.pop();
166 tp.close();
167 }
168 }
169 while (_termPositionsQueue.size() > 0 && _termPositionsQueue.peek().doc() == _doc);
170
171 _posList.sort();
172 _freq = _posList.size();
173
174 return true;
175 }
176
177 /**
178 * Describe <code>nextPosition</code> method here.
179 *
180 * @return an <code>int</code> value
181 * @exception IOException if an error occurs
182 * @see TermPositions#nextPosition()
183 */
184 public final int nextPosition()
185 throws IOException
186 {
187 return _posList.next();
188 }
189
190 /**
191 * Describe <code>skipTo</code> method here.
192 *
193 * @param target an <code>int</code> value
194 * @return a <code>boolean</code> value
195 * @exception IOException if an error occurs
196 * @see TermDocs#skipTo(int)
197 */
198 public final boolean skipTo(int target)
199 throws IOException
200 {
201 while (target > _termPositionsQueue.peek().doc())
202 {
203 TermPositions tp = (TermPositions)_termPositionsQueue.pop();
204
205 if (tp.skipTo(target))
206 _termPositionsQueue.put(tp);
207 else
208 tp.close();
209 }
210
211 return next();
212 }
213
214 /**
215 * Describe <code>doc</code> method here.
216 *
217 * @return an <code>int</code> value
218 * @see TermDocs#doc()
219 */
220 public final int doc()
221 {
222 return _doc;
223 }
224
225 /**
226 * Describe <code>freq</code> method here.
227 *
228 * @return an <code>int</code> value
229 * @see TermDocs#freq()
230 */
231 public final int freq()
232 {
233 return _freq;
234 }
235
236 /**
237 * Describe <code>close</code> method here.
238 *
239 * @exception IOException if an error occurs
240 * @see TermDocs#close()
241 */
242 public final void close()
243 throws IOException
244 {
245 while (_termPositionsQueue.size() > 0)
246 ((TermPositions)_termPositionsQueue.pop()).close();
247 }
248
249 /**
250 * Describe <code>seek</code> method here.
251 *
252 * @param arg0 a <code>Term</code> value
253 * @exception IOException if an error occurs
254 * @see TermDocs#seek(Term)
255 */
256 public void seek(Term arg0)
257 throws IOException
258 {
259 throw new UnsupportedOperationException();
260 }
261
262 public void seek(TermEnum termEnum) throws IOException {
263 throw new UnsupportedOperationException();
264 }
265
266
267 /**
268 * Describe <code>read</code> method here.
269 *
270 * @param arg0 an <code>int[]</code> value
271 * @param arg1 an <code>int[]</code> value
272 * @return an <code>int</code> value
273 * @exception IOException if an error occurs
274 * @see TermDocs#read(int[], int[])
275 */
276 public int read(int[] arg0, int[] arg1)
277 throws IOException
278 {
279 throw new UnsupportedOperationException();
280 }
281
282 }
|