add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / index / MultipleTermPositions.java
1 package org.apache.lucene.index;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21 import java.util.Arrays;
22 import java.util.LinkedList;
23 import java.util.List;
24
25 import org.apache.lucene.util.PriorityQueue;
26 import org.apache.lucene.util.ArrayUtil;
27
28 /**
29  * Allows you to iterate over the {@link TermPositions} for multiple {@link Term}s as
30  * a single {@link TermPositions}.
31  *
32  */
33 public class MultipleTermPositions implements TermPositions {
34
35   private static final class TermPositionsQueue extends PriorityQueue<TermPositions> {
36     TermPositionsQueue(List<TermPositions> termPositions) throws IOException {
37       initialize(termPositions.size());
38
39       for (TermPositions tp : termPositions) {
40         if (tp.next())
41           add(tp);
42       }
43     }
44
45     final TermPositions peek() {
46       return top();
47     }
48
49     @Override
50     public final boolean lessThan(TermPositions a, TermPositions b) {
51       return a.doc() < b.doc();
52     }
53   }
54
55   private static final class IntQueue {
56     private int _arraySize = 16;
57     private int _index = 0;
58     private int _lastIndex = 0;
59     private int[] _array = new int[_arraySize];
60
61     final void add(int i) {
62       if (_lastIndex == _arraySize)
63         growArray();
64
65       _array[_lastIndex++] = i;
66     }
67
68     final int next() {
69       return _array[_index++];
70     }
71
72     final void sort() {
73       Arrays.sort(_array, _index, _lastIndex);
74     }
75
76     final void clear() {
77       _index = 0;
78       _lastIndex = 0;
79     }
80
81     final int size() {
82       return (_lastIndex - _index);
83     }
84
85     private void growArray() {
86       _array = ArrayUtil.grow(_array, _arraySize+1);
87       _arraySize = _array.length;
88     }
89   }
90
91   private int _doc;
92   private int _freq;
93   private TermPositionsQueue _termPositionsQueue;
94   private IntQueue _posList;
95
96   /**
97    * Creates a new <code>MultipleTermPositions</code> instance.
98    * 
99    * @exception IOException
100    */
101   public MultipleTermPositions(IndexReader indexReader, Term[] terms) throws IOException {
102     List<TermPositions> termPositions = new LinkedList<TermPositions>();
103
104     for (int i = 0; i < terms.length; i++)
105       termPositions.add(indexReader.termPositions(terms[i]));
106
107     _termPositionsQueue = new TermPositionsQueue(termPositions);
108     _posList = new IntQueue();
109   }
110
111   public final boolean next() throws IOException {
112     if (_termPositionsQueue.size() == 0)
113       return false;
114
115     _posList.clear();
116     _doc = _termPositionsQueue.peek().doc();
117
118     TermPositions tp;
119     do {
120       tp = _termPositionsQueue.peek();
121
122       for (int i = 0; i < tp.freq(); i++) {
123         // NOTE: this can result in dup positions being added!
124         _posList.add(tp.nextPosition());
125       }
126
127       if (tp.next())
128         _termPositionsQueue.updateTop();
129       else {
130         _termPositionsQueue.pop();
131         tp.close();
132       }
133     } while (_termPositionsQueue.size() > 0 && _termPositionsQueue.peek().doc() == _doc);
134
135     _posList.sort();
136     _freq = _posList.size();
137
138     return true;
139   }
140
141   public final int nextPosition() {
142     // NOTE: this may return the same position more than
143     // once (see TestMultiPhraseQuery.testZeroPosIncr)
144     return _posList.next();
145   }
146
147   public final boolean skipTo(int target) throws IOException {
148     while (_termPositionsQueue.peek() != null && target > _termPositionsQueue.peek().doc()) {
149       TermPositions tp =  _termPositionsQueue.pop();
150       if (tp.skipTo(target))
151         _termPositionsQueue.add(tp);
152       else
153         tp.close();
154     }
155     return next();
156   }
157
158   public final int doc() {
159     return _doc;
160   }
161
162   public final int freq() {
163     return _freq;
164   }
165
166   public final void close() throws IOException {
167     while (_termPositionsQueue.size() > 0)
168       _termPositionsQueue.pop().close();
169   }
170
171   /**
172    * Not implemented.
173    * @throws UnsupportedOperationException
174    */
175   public void seek(Term arg0) throws IOException {
176     throw new UnsupportedOperationException();
177   }
178
179   /**
180    * Not implemented.
181    * @throws UnsupportedOperationException
182    */
183   public void seek(TermEnum termEnum) throws IOException {
184     throw new UnsupportedOperationException();
185   }
186
187   /**
188    * Not implemented.
189    * @throws UnsupportedOperationException
190    */
191   public int read(int[] arg0, int[] arg1) throws IOException {
192     throw new UnsupportedOperationException();
193   }
194   
195   
196   /**
197    * Not implemented.
198    * @throws UnsupportedOperationException
199    */
200   public int getPayloadLength() {
201     throw new UnsupportedOperationException();
202   }
203    
204   /**
205    * Not implemented.
206    * @throws UnsupportedOperationException
207    */
208   public byte[] getPayload(byte[] data, int offset) throws IOException {
209     throw new UnsupportedOperationException();
210   }
211
212   /**
213    *
214    * @return false
215    */
216   // TODO: Remove warning after API has been finalized
217   public boolean isPayloadAvailable() {
218     return false;
219   }
220 }