MultipleTermPositions.java
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 @SuppressWarnings({"rawtypes","unchecked"})
035 public class MultipleTermPositions
036     implements TermPositions
037 {
038     private static final class TermPositionsQueue
039   extends PriorityQueue
040     {
041   TermPositionsQueue(List termPositions)
042       throws IOException
043   {
044       initialize(termPositions.size());
045 
046       Iterator i = termPositions.iterator();
047       while (i.hasNext())
048       {
049     TermPositions tp = (TermPositions)i.next();
050     if (tp.next())
051         put(tp);
052       }
053   }
054 
055   final TermPositions peek()
056   {
057       return (TermPositions)top();
058   }
059 
060   @Override
061   public final boolean lessThan(Object a, Object b)
062   {
063       return ((TermPositions)a).doc() ((TermPositions)b).doc();
064   }
065     }
066 
067     private static final class IntQueue
068     {
069   private int _arraySize = 16;
070 
071   private int _index = 0;
072   private int _lastIndex = 0;
073 
074   private int[] _array = new int[_arraySize];
075 
076   final void add(int i)
077   {
078       if (_lastIndex == _arraySize)
079     growArray();
080 
081       _array[_lastIndex++= i;
082   }
083 
084   final int next()
085   {
086       return _array[_index++];
087   }
088 
089   final void sort()
090   {
091       Arrays.sort(_array, _index, _lastIndex);
092   }
093 
094   final void clear()
095   {
096       _index = 0;
097       _lastIndex = 0;
098   }
099 
100   final int size()
101   {
102       return (_lastIndex-_index);
103   }
104 
105   private void growArray()
106   {
107       int[] newArray = new int[_arraySize*2];
108       System.arraycopy(_array, 0, newArray, 0, _arraySize);
109       _array = newArray;
110       _arraySize *= 2;
111   }
112     }
113 
114     private int _doc;
115     private int _freq;
116 
117     private TermPositionsQueue _termPositionsQueue;
118     private IntQueue _posList;
119 
120     /**
121      * Creates a new <code>MultipleTermPositions</code> instance.
122      *
123      @param indexReader an <code>IndexReader</code> value
124      @param terms a <code>Term[]</code> value
125      @exception IOException if an error occurs
126      */
127     public MultipleTermPositions(IndexReader indexReader, Term[] terms)
128   throws IOException
129     {
130   List termPositions = new LinkedList();
131 
132   for (int i=0; i<terms.length; i++)
133       termPositions.add(indexReader.termPositions(terms[i]));
134 
135   _termPositionsQueue = new TermPositionsQueue(termPositions);
136   _posList = new IntQueue();
137     }
138 
139     /**
140      * Describe <code>next</code> method here.
141      *
142      @return <code>boolean</code> value
143      @exception IOException if an error occurs
144      @see TermDocs#next()
145      */
146     @Override
147     public final boolean next()
148   throws IOException
149     {
150   if (_termPositionsQueue.size() == 0)
151       return false;
152 
153   _posList.clear();
154   _doc = _termPositionsQueue.peek().doc();
155 
156   TermPositions tp;
157   do
158   {
159       tp = _termPositionsQueue.peek();
160 
161       for (int i=0; i<tp.freq(); i++)
162     _posList.add(tp.nextPosition());
163 
164       if (tp.next())
165     _termPositionsQueue.adjustTop();
166       else
167       {
168     _termPositionsQueue.pop();
169     tp.close();
170       }
171   }
172   while (_termPositionsQueue.size() && _termPositionsQueue.peek().doc() == _doc);
173 
174   _posList.sort();
175   _freq = _posList.size();
176 
177   return true;
178     }
179 
180     /**
181      * Describe <code>nextPosition</code> method here.
182      *
183      @return an <code>int</code> value
184      @exception IOException if an error occurs
185      @see TermPositions#nextPosition()
186      */
187     @Override
188     public final int nextPosition()
189   throws IOException
190     {
191   return _posList.next();
192     }
193 
194     /**
195      * Describe <code>skipTo</code> method here.
196      *
197      @param target an <code>int</code> value
198      @return <code>boolean</code> value
199      @exception IOException if an error occurs
200      @see TermDocs#skipTo(int)
201      */
202     @Override
203     public final boolean skipTo(int target)
204   throws IOException
205     {
206   while (target > _termPositionsQueue.peek().doc())
207   {
208       TermPositions tp = (TermPositions)_termPositionsQueue.pop();
209 
210       if (tp.skipTo(target))
211     _termPositionsQueue.put(tp);
212       else
213     tp.close();
214   }
215 
216   return next();
217     }
218 
219     /**
220      * Describe <code>doc</code> method here.
221      *
222      @return an <code>int</code> value
223      @see TermDocs#doc()
224      */
225     @Override
226     public final int doc()
227     {
228   return _doc;
229     }
230 
231     /**
232      * Describe <code>freq</code> method here.
233      *
234      @return an <code>int</code> value
235      @see TermDocs#freq()
236      */
237     @Override
238     public final int freq()
239     {
240   return _freq;
241     }
242 
243     /**
244      * Describe <code>close</code> method here.
245      *
246      @exception IOException if an error occurs
247      @see TermDocs#close()
248      */
249     @Override
250     public final void close()
251   throws IOException
252     {
253   while (_termPositionsQueue.size() 0)
254       ((TermPositions)_termPositionsQueue.pop()).close();
255     }
256 
257     /**
258      * Describe <code>seek</code> method here.
259      *
260      @param arg0 a <code>Term</code> value
261      @exception IOException if an error occurs
262      @see TermDocs#seek(Term)
263      */
264     @Override
265     public void seek(Term arg0)
266   throws IOException
267     {
268   throw new UnsupportedOperationException();
269     }
270 
271     @Override
272     public void seek(TermEnum termEnumthrows IOException {
273       throw new UnsupportedOperationException();
274     }
275 
276 
277     /**
278      * Describe <code>read</code> method here.
279      *
280      @param arg0 an <code>int[]</code> value
281      @param arg1 an <code>int[]</code> value
282      @return an <code>int</code> value
283      @exception IOException if an error occurs
284      @see TermDocs#read(int[], int[])
285      */
286     @Override
287     public int read(int[] arg0, int[] arg1)
288   throws IOException
289     {
290   throw new UnsupportedOperationException();
291     }
292 
293 }