下面列出了org.apache.lucene.search.DocIdSetIterator#advance ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
static int nextDoc(DocIdSetIterator sdv, int docId) throws IOException{
Random r = random();
if(r.nextBoolean()){
return sdv.nextDoc();
} else {
if (r.nextBoolean()) {
return sdv.advance(sdv.docID()+random().nextInt(docId-sdv.docID()-1)+1);
} else {
if (r.nextBoolean()){
final int noMatchDoc = sdv.docID()+random().nextInt(docId-sdv.docID()-1)+1;
assertFalse(advanceExact(sdv,noMatchDoc));
assertEquals(noMatchDoc, sdv.docID());
}
assertTrue(advanceExact(sdv,docId));
return sdv.docID();
}
}
}
@Override
public DocIdSetIterator iterator() {
final DocIdSetIterator in = scorer.iterator();
return new DocIdSetIterator() {
@Override
public int advance(int target) throws IOException {
profile.startTime(ProfileBreakdown.TimingType.ADVANCE);
try {
return in.advance(target);
} finally {
profile.stopAndRecordTime();
}
}
@Override
public int nextDoc() throws IOException {
profile.startTime(ProfileBreakdown.TimingType.NEXT_DOC);
try {
return in.nextDoc();
} finally {
profile.stopAndRecordTime();
}
}
@Override
public int docID() {
return in.docID();
}
@Override
public long cost() {
return in.cost();
}
};
}
void doIterate1(java.util.BitSet a, FixedBitSet b) throws IOException {
assertEquals(a.cardinality(), b.cardinality());
int aa=-1,bb=-1;
DocIdSetIterator iterator = new BitSetIterator(b, 0);
do {
aa = a.nextSetBit(aa+1);
bb = (bb < b.length() && random().nextBoolean()) ? iterator.nextDoc() : iterator.advance(bb + 1);
assertEquals(aa == -1 ? DocIdSetIterator.NO_MORE_DOCS : aa, bb);
} while (aa>=0);
}
void doIterate2(java.util.BitSet a, FixedBitSet b) throws IOException {
assertEquals(a.cardinality(), b.cardinality());
int aa=-1,bb=-1;
DocIdSetIterator iterator = new BitSetIterator(b, 0);
do {
aa = a.nextSetBit(aa+1);
bb = random().nextBoolean() ? iterator.nextDoc() : iterator.advance(bb + 1);
assertEquals(aa == -1 ? DocIdSetIterator.NO_MORE_DOCS : aa, bb);
} while (aa>=0);
}
private void countDocValues(Map<String, Map<String, Object>> stats, String field, String type, DocIdSetIterator values,
Function<DocIdSetIterator, Integer> valueLength) throws IOException {
if (values == null) {
return;
}
Map<String, Object> perField = stats.computeIfAbsent(field, n -> new HashMap<>());
SummaryStatistics lengthSummary = (SummaryStatistics)perField.computeIfAbsent("lengths_" + type, s -> new MapWriterSummaryStatistics());
while (values.advance(values.docID() + samplingStep) != DocIdSetIterator.NO_MORE_DOCS) {
int len = valueLength.apply(values);
for (int i = 0; i < samplingStep; i++) {
lengthSummary.addValue(len);
}
}
}
public void doTestIteratorEqual(DocIdSet a, DocIdSet b) throws IOException {
DocIdSetIterator ia = a.iterator();
DocIdSetIterator ib = b.iterator();
// test for next() equivalence
for(;;) {
int da = ia.nextDoc();
int db = ib.nextDoc();
assertEquals(da, db);
assertEquals(ia.docID(), ib.docID());
if (da==DocIdSetIterator.NO_MORE_DOCS) break;
}
for (int i=0; i<10; i++) {
// test random skipTo() and next()
ia = a.iterator();
ib = b.iterator();
int doc = -1;
for (;;) {
int da,db;
if (rand.nextBoolean()) {
da = ia.nextDoc();
db = ib.nextDoc();
} else {
int target = doc + rand.nextInt(10) + 1; // keep in mind future edge cases like probing (increase if necessary)
da = ia.advance(target);
db = ib.advance(target);
}
assertEquals(da, db);
assertEquals(ia.docID(), ib.docID());
if (da==DocIdSetIterator.NO_MORE_DOCS) break;
doc = da;
}
}
}
@SuppressWarnings("unchecked")
private static boolean isFiltered(int notAdjustedDocId, IndexReader reader, Filter filter) throws IOException {
if (filter == null) {
return false;
}
if (reader instanceof BaseCompositeReader) {
BaseCompositeReader<IndexReader> indexReader = (BaseCompositeReader<IndexReader>) reader;
List<? extends IndexReader> sequentialSubReaders = BaseCompositeReaderUtil.getSequentialSubReaders(indexReader);
int readerIndex = BaseCompositeReaderUtil.readerIndex(indexReader, notAdjustedDocId);
int readerBase = BaseCompositeReaderUtil.readerBase(indexReader, readerIndex);
int docId = notAdjustedDocId - readerBase;
IndexReader orgReader = sequentialSubReaders.get(readerIndex);
SegmentReader sReader = AtomicReaderUtil.getSegmentReader(orgReader);
if (sReader != null) {
SegmentReader segmentReader = (SegmentReader) sReader;
DocIdSet docIdSet = filter.getDocIdSet(segmentReader.getContext(), segmentReader.getLiveDocs());
DocIdSetIterator iterator = docIdSet.iterator();
if (iterator == null) {
return true;
}
if (iterator.advance(docId) == docId) {
return false;
}
return true;
}
throw new RuntimeException("Reader has to be a SegmentReader [" + orgReader + "]");
} else {
throw new RuntimeException("Reader has to be a BaseCompositeReader [" + reader + "]");
}
}
private static OpenBitSet getMask(DocIdSet docIdSet, int primeDocRowId, int numberOfDocsInRow) throws IOException {
OpenBitSet mask = new OpenBitSet(numberOfDocsInRow);
DocIdSetIterator iterator = docIdSet.iterator();
if (iterator == null) {
return mask;
}
int docId = iterator.advance(primeDocRowId);
int end = numberOfDocsInRow + primeDocRowId;
while (docId < end) {
mask.set(docId - primeDocRowId);
docId = iterator.nextDoc();
}
return mask;
}
@Override
public DocIdSetIterator iterator() {
if (isConstantScoreQuery) {
return scorer.iterator();
}
final DocIdSetIterator in = scorer.iterator();
return new DocIdSetIterator() {
@Override
public int advance(int target) throws IOException {
advanceTimer.start();
try {
return in.advance(target);
} finally {
advanceTimer.stop();
}
}
@Override
public int nextDoc() throws IOException {
nextDocTimer.start();
try {
return in.nextDoc();
} finally {
nextDocTimer.stop();
}
}
@Override
public int docID() {
return in.docID();
}
@Override
public long cost() {
return in.cost();
}
};
}
private InternalSearchHit.InternalNestedIdentity getInternalNestedIdentity(SearchContext context, int nestedSubDocId, LeafReaderContext subReaderContext, DocumentMapper documentMapper, ObjectMapper nestedObjectMapper) throws IOException {
int currentParent = nestedSubDocId;
ObjectMapper nestedParentObjectMapper;
ObjectMapper current = nestedObjectMapper;
String originalName = nestedObjectMapper.name();
InternalSearchHit.InternalNestedIdentity nestedIdentity = null;
do {
Query parentFilter;
nestedParentObjectMapper = documentMapper.findParentObjectMapper(current);
if (nestedParentObjectMapper != null) {
if (nestedParentObjectMapper.nested().isNested() == false) {
current = nestedParentObjectMapper;
continue;
}
parentFilter = nestedParentObjectMapper.nestedTypeFilter();
} else {
parentFilter = Queries.newNonNestedFilter();
}
Query childFilter = nestedObjectMapper.nestedTypeFilter();
if (childFilter == null) {
current = nestedParentObjectMapper;
continue;
}
final Weight childWeight = context.searcher().createNormalizedWeight(childFilter, false);
Scorer childScorer = childWeight.scorer(subReaderContext);
if (childScorer == null) {
current = nestedParentObjectMapper;
continue;
}
DocIdSetIterator childIter = childScorer.iterator();
BitSet parentBits = context.bitsetFilterCache().getBitSetProducer(parentFilter).getBitSet(subReaderContext);
int offset = 0;
int nextParent = parentBits.nextSetBit(currentParent);
for (int docId = childIter.advance(currentParent + 1); docId < nextParent && docId != DocIdSetIterator.NO_MORE_DOCS; docId = childIter.nextDoc()) {
offset++;
}
currentParent = nextParent;
current = nestedObjectMapper = nestedParentObjectMapper;
int currentPrefix = current == null ? 0 : current.name().length() + 1;
nestedIdentity = new InternalSearchHit.InternalNestedIdentity(originalName.substring(currentPrefix), offset, nestedIdentity);
if (current != null) {
originalName = current.name();
}
} while (current != null);
return nestedIdentity;
}
private void count(DoubleValuesSource valueSource, List<MatchingDocs> matchingDocs) throws IOException {
DoubleRange[] ranges = (DoubleRange[]) this.ranges;
LongRange[] longRanges = new LongRange[ranges.length];
for(int i=0;i<ranges.length;i++) {
DoubleRange range = ranges[i];
longRanges[i] = new LongRange(range.label,
NumericUtils.doubleToSortableLong(range.min), true,
NumericUtils.doubleToSortableLong(range.max), true);
}
LongRangeCounter counter = new LongRangeCounter(longRanges);
int missingCount = 0;
for (MatchingDocs hits : matchingDocs) {
DoubleValues fv = valueSource.getValues(hits.context, null);
totCount += hits.totalHits;
final DocIdSetIterator fastMatchDocs;
if (fastMatchQuery != null) {
final IndexReaderContext topLevelContext = ReaderUtil.getTopLevelContext(hits.context);
final IndexSearcher searcher = new IndexSearcher(topLevelContext);
searcher.setQueryCache(null);
final Weight fastMatchWeight = searcher.createWeight(searcher.rewrite(fastMatchQuery), ScoreMode.COMPLETE_NO_SCORES, 1);
Scorer s = fastMatchWeight.scorer(hits.context);
if (s == null) {
continue;
}
fastMatchDocs = s.iterator();
} else {
fastMatchDocs = null;
}
DocIdSetIterator docs = hits.bits.iterator();
for (int doc = docs.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; ) {
if (fastMatchDocs != null) {
int fastMatchDoc = fastMatchDocs.docID();
if (fastMatchDoc < doc) {
fastMatchDoc = fastMatchDocs.advance(doc);
}
if (doc != fastMatchDoc) {
doc = docs.advance(fastMatchDoc);
continue;
}
}
// Skip missing docs:
if (fv.advanceExact(doc)) {
counter.add(NumericUtils.doubleToSortableLong(fv.doubleValue()));
} else {
missingCount++;
}
doc = docs.nextDoc();
}
}
missingCount += counter.fillCounts(counts);
totCount -= missingCount;
}
private void count(LongValuesSource valueSource, List<MatchingDocs> matchingDocs) throws IOException {
LongRange[] ranges = (LongRange[]) this.ranges;
LongRangeCounter counter = new LongRangeCounter(ranges);
int missingCount = 0;
for (MatchingDocs hits : matchingDocs) {
LongValues fv = valueSource.getValues(hits.context, null);
totCount += hits.totalHits;
final DocIdSetIterator fastMatchDocs;
if (fastMatchQuery != null) {
final IndexReaderContext topLevelContext = ReaderUtil.getTopLevelContext(hits.context);
final IndexSearcher searcher = new IndexSearcher(topLevelContext);
searcher.setQueryCache(null);
final Weight fastMatchWeight = searcher.createWeight(searcher.rewrite(fastMatchQuery), ScoreMode.COMPLETE_NO_SCORES, 1);
Scorer s = fastMatchWeight.scorer(hits.context);
if (s == null) {
continue;
}
fastMatchDocs = s.iterator();
} else {
fastMatchDocs = null;
}
DocIdSetIterator docs = hits.bits.iterator();
for (int doc = docs.nextDoc(); doc != DocIdSetIterator.NO_MORE_DOCS; ) {
if (fastMatchDocs != null) {
int fastMatchDoc = fastMatchDocs.docID();
if (fastMatchDoc < doc) {
fastMatchDoc = fastMatchDocs.advance(doc);
}
if (doc != fastMatchDoc) {
doc = docs.advance(fastMatchDoc);
continue;
}
}
// Skip missing docs:
if (fv.advanceExact(doc)) {
counter.add(fv.longValue());
} else {
missingCount++;
}
doc = docs.nextDoc();
}
}
int x = counter.fillCounts(counts);
missingCount += x;
//System.out.println("totCount " + totCount + " x " + x + " missingCount " + missingCount);
totCount -= missingCount;
}
@Override
public Spans getSpans(final LeafReaderContext context, Postings requiredPostings) throws IOException {
Spans includeSpans = includeWeight.getSpans(context, requiredPostings);
if (includeSpans == null) {
return null;
}
Spans excludeSpans = excludeWeight.getSpans(context, requiredPostings);
if (excludeSpans == null) {
return includeSpans;
}
TwoPhaseIterator excludeTwoPhase = excludeSpans.asTwoPhaseIterator();
DocIdSetIterator excludeApproximation = excludeTwoPhase == null ? null : excludeTwoPhase.approximation();
return new FilterSpans(includeSpans) {
// last document we have checked matches() against for the exclusion, and failed
// when using approximations, so we don't call it again, and pass thru all inclusions.
int lastApproxDoc = -1;
boolean lastApproxResult = false;
@Override
protected AcceptStatus accept(Spans candidate) throws IOException {
// TODO: this logic is ugly and sneaky, can we clean it up?
int doc = candidate.docID();
if (doc > excludeSpans.docID()) {
// catch up 'exclude' to the current doc
if (excludeTwoPhase != null) {
if (excludeApproximation.advance(doc) == doc) {
lastApproxDoc = doc;
lastApproxResult = excludeTwoPhase.matches();
}
} else {
excludeSpans.advance(doc);
}
} else if (excludeTwoPhase != null && doc == excludeSpans.docID() && doc != lastApproxDoc) {
// excludeSpans already sitting on our candidate doc, but matches not called yet.
lastApproxDoc = doc;
lastApproxResult = excludeTwoPhase.matches();
}
if (doc != excludeSpans.docID() || (doc == lastApproxDoc && lastApproxResult == false)) {
return AcceptStatus.YES;
}
if (excludeSpans.startPosition() == -1) { // init exclude start position if needed
excludeSpans.nextStartPosition();
}
while (excludeSpans.endPosition() <= candidate.startPosition() - pre) {
// exclude end position is before a possible exclusion
if (excludeSpans.nextStartPosition() == NO_MORE_POSITIONS) {
return AcceptStatus.YES; // no more exclude at current doc.
}
}
// exclude end position far enough in current doc, check start position:
if (excludeSpans.startPosition() - post >= candidate.endPosition()) {
return AcceptStatus.YES;
} else {
return AcceptStatus.NO;
}
}
};
}