All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.lucene.facet.taxonomy.SearcherTaxonomyManager Maven / Gradle / Ivy

There is a newer version: 10.0.0
Show newest version
/*
 * 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.taxonomy;

import java.io.IOException;
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ReferenceManager;
import org.apache.lucene.search.SearcherFactory;
import org.apache.lucene.search.SearcherManager;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.IOUtils;

/**
 * Manages near-real-time reopen of both an IndexSearcher and a TaxonomyReader.
 *
 * 

NOTE: If you call {@link DirectoryTaxonomyWriter#replaceTaxonomy} then you must open a * new {@code SearcherTaxonomyManager} afterwards. */ public class SearcherTaxonomyManager extends ReferenceManager { /** Holds a matched pair of {@link IndexSearcher} and {@link TaxonomyReader} */ public static class SearcherAndTaxonomy { /** Point-in-time {@link IndexSearcher}. */ public final IndexSearcher searcher; /** Matching point-in-time {@link DirectoryTaxonomyReader}. */ public final DirectoryTaxonomyReader taxonomyReader; /** Create a SearcherAndTaxonomy */ public SearcherAndTaxonomy(IndexSearcher searcher, DirectoryTaxonomyReader taxonomyReader) { this.searcher = searcher; this.taxonomyReader = taxonomyReader; } } private final SearcherFactory searcherFactory; private final long taxoEpoch; private final DirectoryTaxonomyWriter taxoWriter; /** Creates near-real-time searcher and taxonomy reader from the corresponding writers. */ public SearcherTaxonomyManager( IndexWriter writer, SearcherFactory searcherFactory, DirectoryTaxonomyWriter taxoWriter) throws IOException { this(writer, true, searcherFactory, taxoWriter); } /** * Expert: creates near-real-time searcher and taxonomy reader from the corresponding writers, * controlling whether deletes should be applied. */ public SearcherTaxonomyManager( IndexWriter writer, boolean applyAllDeletes, SearcherFactory searcherFactory, DirectoryTaxonomyWriter taxoWriter) throws IOException { if (searcherFactory == null) { searcherFactory = new SearcherFactory(); } this.searcherFactory = searcherFactory; this.taxoWriter = taxoWriter; DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoWriter); current = new SearcherAndTaxonomy( SearcherManager.getSearcher( searcherFactory, DirectoryReader.open(writer, applyAllDeletes, false), null), taxoReader); this.taxoEpoch = taxoWriter.getTaxonomyEpoch(); } /** * Creates search and taxonomy readers over the corresponding directories. * *

NOTE: you should only use this constructor if you commit and call {@link * #maybeRefresh()} in the same thread. Otherwise it could lead to an unsync'd {@link * IndexSearcher} and {@link TaxonomyReader} pair. */ public SearcherTaxonomyManager( Directory indexDir, Directory taxoDir, SearcherFactory searcherFactory) throws IOException { if (searcherFactory == null) { searcherFactory = new SearcherFactory(); } this.searcherFactory = searcherFactory; DirectoryTaxonomyReader taxoReader = new DirectoryTaxonomyReader(taxoDir); current = new SearcherAndTaxonomy( SearcherManager.getSearcher(searcherFactory, DirectoryReader.open(indexDir), null), taxoReader); this.taxoWriter = null; taxoEpoch = -1; } /** * Creates this from already opened {@link IndexReader} and {@link DirectoryTaxonomyReader} * instances. Note that the incoming readers will be closed when you call {@link #close}. */ public SearcherTaxonomyManager( IndexReader reader, DirectoryTaxonomyReader taxoReader, SearcherFactory searcherFactory) throws IOException { if (searcherFactory == null) { searcherFactory = new SearcherFactory(); } this.searcherFactory = searcherFactory; current = new SearcherAndTaxonomy( SearcherManager.getSearcher(searcherFactory, reader, null), taxoReader); this.taxoWriter = null; taxoEpoch = -1; } @Override protected void decRef(SearcherAndTaxonomy ref) throws IOException { ref.searcher.getIndexReader().decRef(); // This decRef can fail, and then in theory we should // tryIncRef the searcher to put back the ref count // ... but 1) the below decRef should only fail because // it decRef'd to 0 and closed and hit some IOException // during close, in which case 2) very likely the // searcher was also just closed by the above decRef and // a tryIncRef would fail: ref.taxonomyReader.decRef(); } @Override protected boolean tryIncRef(SearcherAndTaxonomy ref) throws IOException { if (ref.searcher.getIndexReader().tryIncRef()) { if (ref.taxonomyReader.tryIncRef()) { return true; } else { ref.searcher.getIndexReader().decRef(); } } return false; } @Override protected SearcherAndTaxonomy refreshIfNeeded(SearcherAndTaxonomy ref) throws IOException { // Must re-open searcher first, otherwise we may get a // new reader that references ords not yet known to the // taxonomy reader: final IndexReader r = ref.searcher.getIndexReader(); final IndexReader newReader = DirectoryReader.openIfChanged((DirectoryReader) r); if (newReader == null) { return null; } else { DirectoryTaxonomyReader tr; try { tr = TaxonomyReader.openIfChanged(ref.taxonomyReader); } catch (Throwable t1) { try { IOUtils.close(newReader); } catch (Throwable t2) { t2.addSuppressed(t2); } throw t1; } if (tr == null) { ref.taxonomyReader.incRef(); tr = ref.taxonomyReader; } else if (taxoWriter != null && taxoWriter.getTaxonomyEpoch() != taxoEpoch) { IOUtils.close(newReader, tr); throw new IllegalStateException( "DirectoryTaxonomyWriter.replaceTaxonomy was called, which is not allowed when using SearcherTaxonomyManager"); } return new SearcherAndTaxonomy( SearcherManager.getSearcher(searcherFactory, newReader, r), tr); } } @Override protected int getRefCount(SearcherAndTaxonomy reference) { return reference.searcher.getIndexReader().getRefCount(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy