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 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 <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() && _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 <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 termEnumthrows 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 }