1 package org.apache.lucene.index;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 import java.io.IOException;
21 import java.util.Arrays;
22 import java.util.LinkedList;
23 import java.util.List;
25 import org.apache.lucene.util.PriorityQueue;
26 import org.apache.lucene.util.ArrayUtil;
29 * Allows you to iterate over the {@link TermPositions} for multiple {@link Term}s as
30 * a single {@link TermPositions}.
33 public class MultipleTermPositions implements TermPositions {
35 private static final class TermPositionsQueue extends PriorityQueue<TermPositions> {
36 TermPositionsQueue(List<TermPositions> termPositions) throws IOException {
37 initialize(termPositions.size());
39 for (TermPositions tp : termPositions) {
45 final TermPositions peek() {
50 public final boolean lessThan(TermPositions a, TermPositions b) {
51 return a.doc() < b.doc();
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];
61 final void add(int i) {
62 if (_lastIndex == _arraySize)
65 _array[_lastIndex++] = i;
69 return _array[_index++];
73 Arrays.sort(_array, _index, _lastIndex);
82 return (_lastIndex - _index);
85 private void growArray() {
86 _array = ArrayUtil.grow(_array, _arraySize+1);
87 _arraySize = _array.length;
93 private TermPositionsQueue _termPositionsQueue;
94 private IntQueue _posList;
97 * Creates a new <code>MultipleTermPositions</code> instance.
99 * @exception IOException
101 public MultipleTermPositions(IndexReader indexReader, Term[] terms) throws IOException {
102 List<TermPositions> termPositions = new LinkedList<TermPositions>();
104 for (int i = 0; i < terms.length; i++)
105 termPositions.add(indexReader.termPositions(terms[i]));
107 _termPositionsQueue = new TermPositionsQueue(termPositions);
108 _posList = new IntQueue();
111 public final boolean next() throws IOException {
112 if (_termPositionsQueue.size() == 0)
116 _doc = _termPositionsQueue.peek().doc();
120 tp = _termPositionsQueue.peek();
122 for (int i = 0; i < tp.freq(); i++) {
123 // NOTE: this can result in dup positions being added!
124 _posList.add(tp.nextPosition());
128 _termPositionsQueue.updateTop();
130 _termPositionsQueue.pop();
133 } while (_termPositionsQueue.size() > 0 && _termPositionsQueue.peek().doc() == _doc);
136 _freq = _posList.size();
141 public final int nextPosition() {
142 // NOTE: this may return the same position more than
143 // once (see TestMultiPhraseQuery.testZeroPosIncr)
144 return _posList.next();
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);
158 public final int doc() {
162 public final int freq() {
166 public final void close() throws IOException {
167 while (_termPositionsQueue.size() > 0)
168 _termPositionsQueue.pop().close();
173 * @throws UnsupportedOperationException
175 public void seek(Term arg0) throws IOException {
176 throw new UnsupportedOperationException();
181 * @throws UnsupportedOperationException
183 public void seek(TermEnum termEnum) throws IOException {
184 throw new UnsupportedOperationException();
189 * @throws UnsupportedOperationException
191 public int read(int[] arg0, int[] arg1) throws IOException {
192 throw new UnsupportedOperationException();
198 * @throws UnsupportedOperationException
200 public int getPayloadLength() {
201 throw new UnsupportedOperationException();
206 * @throws UnsupportedOperationException
208 public byte[] getPayload(byte[] data, int offset) throws IOException {
209 throw new UnsupportedOperationException();
216 // TODO: Remove warning after API has been finalized
217 public boolean isPayloadAvailable() {