📄 payloadpredicatedocumentiterator.java
字号:
package it.unimi.dsi.mg4j.search;/* * MG4J: Managing Gigabytes for Java * * Copyright (C) 2007 Sebastiano Vigna * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap;import it.unimi.dsi.fastutil.objects.ReferenceSet;import it.unimi.dsi.mg4j.index.Index;import it.unimi.dsi.mg4j.index.IndexIterator;import it.unimi.dsi.mg4j.search.visitor.DocumentIteratorVisitor;import java.io.IOException;import org.apache.commons.collections.Predicate;/** A document iterator that filters an {@link IndexIterator}, returning just * documents whose payload satisfies a given predicate. * The interval iterators are computed by delegation to the underlying {@link IndexIterator}. * * <p>Besides the classic {@link #skipTo(int)} method, this class provides a {@link #skipUnconditionallyTo(int)} * method that skips to a given document <em>even if the document does not match the predicate</em>. This * feature is fundamental to implement an efficient list intersection algorithm, as {@link #skipTo(int)} is * very expensive when the argument does not satisfy the predicate (as the next valid document must be searched * for exhaustively). * * @author Sebastiano Vigna * @since 0.9 */public class PayloadPredicateDocumentIterator extends AbstractDocumentIterator implements DocumentIterator { @SuppressWarnings("unused") private final static boolean DEBUG = false; @SuppressWarnings("unused") private final static boolean ASSERTS = false; /** The underlying iterator. */ private final IndexIterator indexIterator; /** The predicate to filter payloads. */ private final Predicate payloadPredicate; /** Creates a new payload-predicate document iterator over a given index iterator. * @param indexIterator an index iterator. * @param payloadPredicate a predicate on payloads that will be used to filter the documents returned by <code>indexIterator</code>. */ protected PayloadPredicateDocumentIterator( final IndexIterator indexIterator, final Predicate payloadPredicate ) { this.indexIterator = indexIterator; this.payloadPredicate = payloadPredicate; } /** Returns a new payload-predicate document iterator over a given index iterator. * @param indexIterator an index iterator. * @param payloadPredicate a predicate on payloads that will be used to filter the documents returned by <code>indexIterator</code>. */ public static PayloadPredicateDocumentIterator getInstance( final IndexIterator indexIterator, final Predicate payloadPredicate ) { return new PayloadPredicateDocumentIterator( indexIterator, payloadPredicate ); } public ReferenceSet<Index> indices() { return indexIterator.indices(); } public int skipTo( final int n ) throws IOException { if ( last >= n ) return last; last = next = -1; final int result = indexIterator.skipTo( n ); if ( result == Integer.MAX_VALUE ) return Integer.MAX_VALUE; if ( payloadPredicate.evaluate( indexIterator.payload() ) ) return last = result; return nextDocument() == -1 ? Integer.MAX_VALUE : last; } /** Skips to the given document, even if the document does not satisfy the predicate of this document iterator. * * @param n a document pointer. * @return assuming that <code>p</code> is the first document pointer larger than or equal to <code>n</code>, * <code>p</code> if document <code>p</code> satisfies the predicate, <code>-p-1</code> otherwise; * if there is no document * pointer larger than or equal to <code>n</code>, {@link Integer#MAX_VALUE}. * @throws IOException * @see #skipTo(int) */ public int skipUnconditionallyTo( final int n ) throws IOException { if ( last < n ) { next = indexIterator.skipTo( n ); if ( next == Integer.MAX_VALUE ) return Integer.MAX_VALUE; last = next; next = -1; } return payloadPredicate.evaluate( indexIterator.payload() ) ? last : -last - 1; } public int nextDocument() throws IOException { if ( next >= 0 ) { last = next; next = -1; return last; } while( ( last = indexIterator.nextDocument() ) != -1 && ! payloadPredicate.evaluate( indexIterator.payload() ) ); return last; } public void dispose() throws IOException { indexIterator.dispose(); } public boolean accept( final DocumentIteratorVisitor visitor ) throws IOException { return visitor.visitPre( this ) && indexIterator.accept( visitor ) && visitor.visitPost( this ); } public boolean acceptOnTruePaths( final DocumentIteratorVisitor visitor ) { return visitor.visitPre( this ) && visitor.visitPost( this ); } public String toString() { return getClass().getSimpleName() + "(" + indexIterator + ")" + payloadPredicate; } public Reference2ReferenceMap<Index,IntervalIterator> intervalIterators() throws IOException { return indexIterator.intervalIterators(); } public IntervalIterator intervalIterator() throws IOException { return indexIterator.intervalIterator(); } public IntervalIterator intervalIterator( final Index index ) throws IOException { return indexIterator.intervalIterator( index ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -