blob: 6672d648151ce75c6baa0505c36f765dc7e86c53 [file] [log] [blame]
/*
* 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.
*/
package org.apache.lucene.index;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.util.BytesRef;
/**
* Exposes flex API, merged from flex API of sub-segments,
* remapping docIDs (this is used for segment merging).
*
* @lucene.experimental
*/
final class MappingMultiPostingsEnum extends PostingsEnum {
MultiPostingsEnum multiDocsAndPositionsEnum;
final String field;
final DocIDMerger<MappingPostingsSub> docIDMerger;
private MappingPostingsSub current;
private final MappingPostingsSub[] allSubs;
private final List<MappingPostingsSub> subs = new ArrayList<>();
private static class MappingPostingsSub extends DocIDMerger.Sub {
public PostingsEnum postings;
public MappingPostingsSub(MergeState.DocMap docMap) {
super(docMap);
}
@Override
public int nextDoc() {
try {
return postings.nextDoc();
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
}
/** Sole constructor. */
public MappingMultiPostingsEnum(String field, MergeState mergeState) throws IOException {
this.field = field;
allSubs = new MappingPostingsSub[mergeState.fieldsProducers.length];
for(int i=0;i<allSubs.length;i++) {
allSubs[i] = new MappingPostingsSub(mergeState.docMaps[i]);
}
this.docIDMerger = DocIDMerger.of(subs, allSubs.length, mergeState.needsIndexSort);
}
MappingMultiPostingsEnum reset(MultiPostingsEnum postingsEnum) throws IOException {
this.multiDocsAndPositionsEnum = postingsEnum;
MultiPostingsEnum.EnumWithSlice[] subsArray = postingsEnum.getSubs();
int count = postingsEnum.getNumSubs();
subs.clear();
for(int i=0;i<count;i++) {
MappingPostingsSub sub = allSubs[subsArray[i].slice.readerIndex];
sub.postings = subsArray[i].postingsEnum;
subs.add(sub);
}
docIDMerger.reset();
return this;
}
@Override
public int freq() throws IOException {
return current.postings.freq();
}
@Override
public int docID() {
if (current == null) {
return -1;
} else {
return current.mappedDocID;
}
}
@Override
public int advance(int target) {
throw new UnsupportedOperationException();
}
@Override
public int nextDoc() throws IOException {
current = docIDMerger.next();
if (current == null) {
return NO_MORE_DOCS;
} else {
return current.mappedDocID;
}
}
@Override
public int nextPosition() throws IOException {
int pos = current.postings.nextPosition();
if (pos < 0) {
throw new CorruptIndexException("position=" + pos + " is negative, field=\"" + field + " doc=" + current.mappedDocID,
current.postings.toString());
} else if (pos > IndexWriter.MAX_POSITION) {
throw new CorruptIndexException("position=" + pos + " is too large (> IndexWriter.MAX_POSITION=" + IndexWriter.MAX_POSITION + "), field=\"" + field + "\" doc=" + current.mappedDocID,
current.postings.toString());
}
return pos;
}
@Override
public int startOffset() throws IOException {
return current.postings.startOffset();
}
@Override
public int endOffset() throws IOException {
return current.postings.endOffset();
}
@Override
public BytesRef getPayload() throws IOException {
return current.postings.getPayload();
}
@Override
public long cost() {
long cost = 0;
for (MappingPostingsSub sub : subs) {
cost += sub.postings.cost();
}
return cost;
}
}