package org.apache.lucene.facet.util; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.lucene.facet.search.CategoryListIterator; /* * 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. */ /** * Iterates over multiple {@link CategoryListIterator}s, consuming the provided * iterators in order. * * @lucene.experimental */ public class MultiCategoryListIterator implements CategoryListIterator { private final CategoryListIterator[] iterators; private final List<CategoryListIterator> validIterators; private final List<CategoryListIterator> perDocValidIterators; /** Receives the iterators to iterate on */ public MultiCategoryListIterator(CategoryListIterator... iterators) { this.iterators = iterators; this.validIterators = new ArrayList<CategoryListIterator>(); this.perDocValidIterators = new ArrayList<CategoryListIterator>(); } /** Fails if all given iterators fail to init */ public boolean init() throws IOException { for (CategoryListIterator cli : iterators) { if (cli.init()) { validIterators.add(cli); } } return !validIterators.isEmpty(); } /** * Return a value larger than {@link Integer#MAX_VALUE} only if all * iterators are exhausted */ public long nextCategory() throws IOException { while (!perDocValidIterators.isEmpty()) { long value = perDocValidIterators.get(0).nextCategory(); if (value <= Integer.MAX_VALUE) { return value; } perDocValidIterators.remove(0); } return 0x100000000L; } /** * Fails only if skipTo on all the provided iterators returned {@code false} */ public boolean skipTo(int docId) throws IOException { perDocValidIterators.clear(); for (CategoryListIterator cli : validIterators) { if (cli.skipTo(docId)) { perDocValidIterators.add(cli); } } return !perDocValidIterators.isEmpty(); } }