/* * ModeShape (http://www.modeshape.org) * * Licensed 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.modeshape.jcr.spi.index.provider; import java.util.Iterator; import org.modeshape.common.collection.EmptyIterator; import org.modeshape.jcr.cache.NodeKey; import org.modeshape.jcr.spi.index.IndexConstraints; /** * A simple filter that takes constraints as input and returns a results object that lazily returns (in batches) those nodes that * satisfy the constraints. * * @author Randall Hauch (rhauch@redhat.com) * @author Horia Chiorean (hchiorea@redhat.com) */ public interface Filter { /** * Return a {@link Results} instance from which ModeShape can obtain the nodes that satisfy the supplied constraints. This * method should return quickly, since no work (or at least very little work) should be done. All of the work should be * performed when the {@link Results#getNextBatch(int)} method is called on the results. * * @param constraints the constraints to be applied by this index; never null * @param cardinalityEstimate the total number of elements which this index reported during the planning phase * @return a {@link Results} instance; never null */ Results filter(IndexConstraints constraints, long cardinalityEstimate); /** * The results of a {@link Filter#filter(IndexConstraints, long)} operation that contains the nodes that satisfy the * {@link Filter#filter(IndexConstraints, long) supplied constraints}. * <p> * ModeShape will periodically call {@link #getNextBatch(int)} as (additional) results are needed to answer the * query. Generally, each {@link Results} instance will have enough state to execute the filtering steps. * </p> * <p> * ModeShape may call this method zero or more times, based upon whether results are actually needed and in specific batch * sizes. And every time this method is called, implementations should write the next batch of nodes that satisfies the * criteria, where the number of nodes in the batch should be roughly equal to <code>batchSize</code>. If the index * implementation is interacting with a remote system, then each method invocation might correspond to a single remote * request. * </p> * * @author Randall Hauch (rhauch@redhat.com) */ interface Results extends AutoCloseable { /** * Obtain the next batch of results for the query. * * @param batchSize the ideal number of node keys that are to be included in this batch; always positive * @return true if there are additional results after this batch is completed, or false if this batch contains the final * results of the query */ ResultBatch getNextBatch(int batchSize); /** * Close any and all resources for the operation. This will always be called by ModeShape when the operation is no longer * needed, even if {@link #getNextBatch(int)} was never called. */ @Override void close(); } /** * A batch of results as returned by {@link Results#getNextBatch(int)} */ interface ResultBatch { Iterator<?> EMPTY_ITERATOR = new EmptyIterator<>(); ResultBatch EMPTY = new ResultBatch() { @Override @SuppressWarnings( "unchecked" ) public Iterable<NodeKey> keys() { return () -> (Iterator<NodeKey>) EMPTY_ITERATOR; } @Override @SuppressWarnings( "unchecked" ) public Iterable<Float> scores() { return () -> (Iterator<Float>) EMPTY_ITERATOR; } @Override public boolean hasNext() { return false; } @Override public int size() { return 0; } }; /** * Returns an {@link Iterable} over a number of {@code NodeKey} instances representing matching nodes in an index. * This should have the same order as {@link #scores()} * * @return an iterable instance, never {@code null} */ Iterable<NodeKey> keys(); /** * Returns an {@link Iterable} over a number of {@code Float} values, representing the scores of the matched documents * from {@link #keys()}. This should have the same order as {@link #keys()} * * @return an iterable instance, never {@code null} */ Iterable<Float> scores(); /** * Checks if this batch is followed by another batch or is the last batch of the search results. * * @return {@code true} if this batch is not the last one, {@code false} otherwise. */ boolean hasNext(); /** * Returns the total number of node keys in this batch. * * @return the number of node keys; must be positive. */ int size(); } }