Skip to content

Commit

Permalink
HSEARCH-3314 Replace the ReaderProvider SPI with an object-oriented one
Browse files Browse the repository at this point in the history
If we have a set of objects that require specific behavior when closing,
then let's use a dedicated object to represent them and this closing
behavior: the IndexReaderHolder.
  • Loading branch information
yrodiere committed Aug 5, 2019
1 parent 2d71831 commit 1e0769b
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 206 deletions.
Expand Up @@ -36,8 +36,6 @@
import org.hibernate.search.util.common.impl.Closer;
import org.hibernate.search.util.common.logging.impl.LoggerFactory;

import org.apache.lucene.index.IndexReader;

public class LuceneIndexManagerImpl
implements IndexManagerImplementor<LuceneRootDocumentBuilder>, LuceneIndexManager,
LuceneScopeIndexManagerContext, WorkExecutionIndexManagerContext {
Expand Down Expand Up @@ -146,26 +144,10 @@ public void addTo(IndexScopeBuilder builder) {
}

@Override
public IndexReader openIndexReader() {
try {
return indexAccessor.openDirectoryIndexReader();
}
catch (IOException e) {
throw log.unableToCreateIndexReader( getBackendAndIndexEventContext(), e );
}
public IndexReaderHolder openIndexReader() throws IOException {
return IndexReaderHolder.of( indexAccessor.openDirectoryIndexReader() );
}

@Override
public void closeIndexReader(IndexReader reader) {
try {
reader.close();
}
catch (IOException e) {
log.unableToCloseIndexReader( getBackendAndIndexEventContext(), e );
}
}


@Override
public IndexManager toAPI() {
return this;
Expand Down

This file was deleted.

Expand Up @@ -74,11 +74,6 @@ public interface Log extends BasicLogger {
// -----------------------------------
int ID_OFFSET_1 = MessageConstants.ENGINE_ID_RANGE_MIN;

@LogMessage(level = Level.WARN)
@Message(id = ID_OFFSET_1 + 35,
value = "Could not close resource.")
void couldNotCloseResource(@Cause Exception e);

@LogMessage(level = WARN)
@Message(id = ID_OFFSET_1 + 49,
value = "'%s' was interrupted while waiting for index activity to finish. Index might be inconsistent or have a stale lock")
Expand Down Expand Up @@ -120,8 +115,8 @@ public interface Log extends BasicLogger {
SearchException illegalLuceneVersionFormat(String property, String luceneErrorMessage, @Cause Exception e);

@Message(id = ID_OFFSET_1 + 284,
value = "An IOException happened while opening multiple indexes." )
SearchException ioExceptionOnMultiReaderRefresh(@Param EventContext context, @Cause IOException e);
value = "An exception occurred while opening multiple indexes." )
SearchException failureOnMultiReaderRefresh(@Param EventContext context, @Cause Exception e);

@Message(id = ID_OFFSET_1 + 320,
value = "Could not normalize value for field '%1$s'.")
Expand Down
@@ -0,0 +1,102 @@
/*
* Hibernate Search, full-text search for your domain model
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.search.backend.lucene.lowlevel.reader.impl;

import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;

import org.hibernate.search.backend.lucene.logging.impl.Log;
import org.hibernate.search.backend.lucene.lowlevel.reader.spi.IndexReaderHolder;
import org.hibernate.search.engine.reporting.spi.EventContexts;
import org.hibernate.search.util.common.impl.Closer;
import org.hibernate.search.util.common.impl.SuppressingCloser;
import org.hibernate.search.util.common.logging.impl.LoggerFactory;

/**
* A {@link MultiReader} keeping references to {@link IndexReaderHolder}s to eventually close them.
* <p>
* Ported from Search 5: {@code org.hibernate.search.reader.impl.ManagedMultiReader},
* {@code org.hibernate.search.reader.impl.MultiReaderFactory}.
*
* @author Emmanuel Bernard
* @author Sanne Grinovero (C) 2011 Red Hat Inc.
*/
public class HolderMultiReader extends MultiReader {

private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() );

public static HolderMultiReader open(Set<String> indexNames,
Set<? extends ReadIndexManagerContext> indexManagerContexts) {
if ( indexManagerContexts.isEmpty() ) {
return null;
}
else {
List<IndexReaderHolder> indexReaderHolders = new ArrayList<>();
try {
for ( ReadIndexManagerContext indexManagerContext : indexManagerContexts ) {
indexReaderHolders.add( indexManagerContext.openIndexReader() );
}
return new HolderMultiReader( indexReaderHolders );
}
catch (IOException | RuntimeException e) {
new SuppressingCloser( e )
.pushAll( indexReaderHolders );
throw log.failureOnMultiReaderRefresh(
EventContexts.fromIndexNames( indexNames ), e
);
}
}
}

private final List<IndexReaderHolder> indexReaderHolders;

HolderMultiReader(List<IndexReaderHolder> indexReaderHolders) throws IOException {
// If this flag isn't set to true, the MultiReader will increase the usage counter!
super( toReaderArray( indexReaderHolders ), true );
this.indexReaderHolders = indexReaderHolders;
}

@Override
public String toString() {
return HolderMultiReader.class.getSimpleName() + " [subReaders=" + getSequentialSubReaders()
+ ", indexReaderHolders=" + indexReaderHolders + "]";
}

@Override
protected synchronized void doClose() throws IOException {
/*
* Important: we don't really close the sub readers but we delegate to the
* close method of the managing IndexReaderHolder.
* This method may decrement a usage counter instead of actually closing the reader,
* in cases where the reader is shared.
*/
final boolean debugEnabled = log.isDebugEnabled();
if ( debugEnabled ) {
log.debugf( "Closing MultiReader: %s", this );
}
try ( Closer<IOException> closer = new Closer<>() ) {
closer.pushAll( IndexReaderHolder::close, indexReaderHolders );
}
if ( debugEnabled ) {
log.trace( "MultiReader closed." );
}
}

private static IndexReader[] toReaderArray(List<IndexReaderHolder> indexReaderHolders) {
IndexReader[] indexReaders = new IndexReader[indexReaderHolders.size()];
for ( int i = 0; i < indexReaderHolders.size(); i++ ) {
indexReaders[i] = indexReaderHolders.get( i ).get();
}
return indexReaders;
}
}

This file was deleted.

This file was deleted.

Expand Up @@ -6,12 +6,16 @@
*/
package org.hibernate.search.backend.lucene.lowlevel.reader.impl;

import org.hibernate.search.backend.lucene.index.spi.ReaderProvider;
import java.io.IOException;

import org.hibernate.search.backend.lucene.lowlevel.reader.spi.IndexReaderHolder;

/**
* An interface with knowledge of the index manager internals,
* able to retrieve components related to index reading.
*/
public interface ReadIndexManagerContext extends ReaderProvider {
public interface ReadIndexManagerContext {

IndexReaderHolder openIndexReader() throws IOException;

}
Expand Up @@ -8,12 +8,12 @@

import java.util.Set;

import org.hibernate.search.backend.lucene.index.spi.ReaderProvider;
import org.hibernate.search.backend.lucene.lowlevel.reader.impl.ReadIndexManagerContext;
import org.hibernate.search.backend.lucene.work.impl.LuceneReadWork;


public interface LuceneReadWorkOrchestrator {

<T> T submit(Set<String> indexNames, Set<? extends ReaderProvider> indexManagerContexts, LuceneReadWork<T> work);
<T> T submit(Set<String> indexNames, Set<? extends ReadIndexManagerContext> indexManagerContexts, LuceneReadWork<T> work);

}

0 comments on commit 1e0769b

Please sign in to comment.