package org.apache.lucene.search.function;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import org.apache.lucene.util.ReaderUtil;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Explanation;
/** This class wraps another ValueSource, but protects
* against accidental double RAM usage in FieldCache when
* a composite reader is passed to {@link #getValues}.
*
* <p><b>NOTE</b>: this class adds a CPU penalty to every
* lookup, as it must resolve the incoming document to the
* right sub-reader using a binary search.</p>
*
* @deprecated This class is temporary, to ease the
* migration to segment-based searching. Please change your
* code to not pass composite readers to these APIs. */
@Deprecated
public final class MultiValueSource extends ValueSource {
final ValueSource other;
public MultiValueSource(ValueSource other) {
this.other = other;
}
@Override
public DocValues getValues(IndexReader reader) throws IOException {
IndexReader[] subReaders = reader.getSequentialSubReaders();
if (subReaders != null) {
// This is a composite reader
return new MultiDocValues(subReaders);
} else {
// Already an atomic reader -- just delegate
return other.getValues(reader);
}
}
@Override
public String description() {
return other.description();
}
@Override
public boolean equals(Object o) {
if (o instanceof MultiValueSource) {
return ((MultiValueSource) o).other.equals(other);
} else {
return false;
}
}
@Override
public int hashCode() {
return 31 * other.hashCode();
}
private final class MultiDocValues extends DocValues {
final DocValues[] docValues;
final int[] docStarts;
MultiDocValues(IndexReader[] subReaders) throws IOException {
docValues = new DocValues[subReaders.length];
docStarts = new int[subReaders.length];
int base = 0;
for(int i=0;i<subReaders.length;i++) {
docValues[i] = other.getValues(subReaders[i]);
docStarts[i] = base;
base += subReaders[i].maxDoc();
}
}
@Override
public float floatVal(int doc) {
final int n = ReaderUtil.subIndex(doc, docStarts);
return docValues[n].floatVal(doc-docStarts[n]);
}
@Override
public int intVal(int doc) {
final int n = ReaderUtil.subIndex(doc, docStarts);
return docValues[n].intVal(doc-docStarts[n]);
}
@Override
public long longVal(int doc) {
final int n = ReaderUtil.subIndex(doc, docStarts);
return docValues[n].longVal(doc-docStarts[n]);
}
@Override
public double doubleVal(int doc) {
final int n = ReaderUtil.subIndex(doc, docStarts);
return docValues[n].doubleVal(doc-docStarts[n]);
}
@Override
public String strVal(int doc) {
final int n = ReaderUtil.subIndex(doc, docStarts);
return docValues[n].strVal(doc-docStarts[n]);
}
@Override
public String toString(int doc) {
final int n = ReaderUtil.subIndex(doc, docStarts);
return docValues[n].toString(doc-docStarts[n]);
}
@Override
public Explanation explain(int doc) {
final int n = ReaderUtil.subIndex(doc, docStarts);
return docValues[n].explain(doc-docStarts[n]);
}
}
}