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