diff --git a/lucene/core/src/java/org/apache/lucene/search/ReferenceManager.java b/lucene/core/src/java/org/apache/lucene/search/ReferenceManager.java index 699da549d0e..443f70bf1dc 100644 --- a/lucene/core/src/java/org/apache/lucene/search/ReferenceManager.java +++ b/lucene/core/src/java/org/apache/lucene/search/ReferenceManager.java @@ -219,6 +219,36 @@ public abstract class ReferenceManager implements Closeable { return doTryRefresh; } + /** Compute some state of the reference using a parameter. */ + @FunctionalInterface + public interface StateCalculator { + R calculate(G current, P param); + } + + /** + * If you need to compute something after the refresh, you can use this method instead of {@link + * #maybeRefresh()}. + * + * @throws IOException if refreshing the resource causes an {@link IOException} + */ + public final R maybeRefreshAndReturnState( + StateCalculator refreshedStateCalculator, P param) throws IOException { + ensureOpen(); + + // Ensure only 1 thread does refresh at once; other threads just return immediately: + final boolean doTryRefresh = refreshLock.tryLock(); + if (doTryRefresh) { + try { + doMaybeRefresh(); + return refreshedStateCalculator.calculate(current, param); + } finally { + refreshLock.unlock(); + } + } + + return null; + } + /** * You must call this (or {@link #maybeRefresh()}), periodically, if you want that {@link * #acquire()} will return refreshed instances. diff --git a/lucene/facet/src/java/org/apache/lucene/facet/sortedset/SSDVReaderStatesCalculator.java b/lucene/facet/src/java/org/apache/lucene/facet/sortedset/SSDVReaderStatesCalculator.java new file mode 100644 index 00000000000..bd06cae9379 --- /dev/null +++ b/lucene/facet/src/java/org/apache/lucene/facet/sortedset/SSDVReaderStatesCalculator.java @@ -0,0 +1,51 @@ +/* + * 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.facet.sortedset; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; +import org.apache.lucene.facet.FacetsConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.ReferenceManager; + +/** + * Get reader states after a refresh. Example call: readerStates = + * searcherManager.maybeRefreshAndReturnState(new SSDVReaderStatesCalculator(), config); + */ +public class SSDVReaderStatesCalculator + implements ReferenceManager.StateCalculator< + List, IndexSearcher, FacetsConfig> { + + /** No arguments needed */ + public SSDVReaderStatesCalculator() {} + + @Override + public List calculate(IndexSearcher current, FacetsConfig config) { + return config.getDimConfigs().keySet().stream() + .map( + field -> { + try { + return new DefaultSortedSetDocValuesReaderState( + current.getIndexReader(), field, config); + } catch (IOException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + } +}