Skip to content

Commit

Permalink
HSEARCH-3775 Use reference counters to close index readers
Browse files Browse the repository at this point in the history
... and consequently remove the concept of DirectoryReaderHolder:
we won't be needing it if we always use reference counters.
  • Loading branch information
yrodiere committed Feb 13, 2020
1 parent 680fd38 commit 8b8754b
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 115 deletions.
Expand Up @@ -12,13 +12,14 @@

import org.hibernate.search.backend.lucene.logging.impl.Log;
import org.hibernate.search.backend.lucene.lowlevel.index.impl.IndexAccessor;
import org.hibernate.search.backend.lucene.lowlevel.reader.spi.DirectoryReaderHolder;
import org.hibernate.search.backend.lucene.orchestration.impl.LuceneWriteWorkOrchestrator;
import org.hibernate.search.backend.lucene.orchestration.impl.LuceneWriteWorkOrchestratorImplementor;
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;

import org.apache.lucene.index.DirectoryReader;

public final class Shard {

private static final Log log = LoggerFactory.make( Log.class, MethodHandles.lookup() );
Expand Down Expand Up @@ -61,8 +62,8 @@ void stop() throws IOException {
}
}

DirectoryReaderHolder openReader() throws IOException {
return DirectoryReaderHolder.of( indexAccessor.openDirectoryIndexReader() );
DirectoryReader openReader() throws IOException {
return indexAccessor.openDirectoryIndexReader();
}

LuceneWriteWorkOrchestrator getWriteOrchestrator() {
Expand Down
Expand Up @@ -6,10 +6,10 @@
*/
package org.hibernate.search.backend.lucene.lowlevel.reader.impl;

import org.hibernate.search.backend.lucene.lowlevel.reader.spi.DirectoryReaderHolder;
import org.apache.lucene.index.DirectoryReader;

public interface DirectoryReaderCollector {

void collect(String mappedTypeName, DirectoryReaderHolder directoryReaderHolder);
void collect(String mappedTypeName, DirectoryReader directoryReader);

}
Expand Up @@ -19,26 +19,26 @@
import org.apache.lucene.index.MultiReader;

import org.hibernate.search.backend.lucene.logging.impl.Log;
import org.hibernate.search.backend.lucene.lowlevel.reader.spi.DirectoryReaderHolder;
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 DirectoryReaderHolder}s to eventually close them.
* A {@link MultiReader} keeping references to {@link DirectoryReader}s to eventually close them,
* and holding some additional metadata related to the targeted readers.
* <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 {
public class HibernateSearchMultiReader extends MultiReader {

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

public static HolderMultiReader open(Set<String> indexNames,
public static HibernateSearchMultiReader open(Set<String> indexNames,
Set<? extends ReadIndexManagerContext> indexManagerContexts, Set<String> routingKeys) {
if ( indexManagerContexts.isEmpty() ) {
return null;
Expand All @@ -53,80 +53,68 @@ public static HolderMultiReader open(Set<String> indexNames,
}
catch (IOException | RuntimeException e) {
new SuppressingCloser( e )
.pushAll( builder.directoryReaderHolders );
.pushAll( builder.directoryReaders );
throw log.failureOnMultiReaderRefresh(
EventContexts.fromIndexNames( indexNames ), e
);
}
}
}

private final List<DirectoryReaderHolder> directoryReaderHolders;
private final List<DirectoryReader> directoryReaders;
private final IndexReaderMetadataResolver metadataResolver;

HolderMultiReader(List<DirectoryReaderHolder> directoryReaderHolders, IndexReaderMetadataResolver metadataResolver) throws IOException {
HibernateSearchMultiReader(List<DirectoryReader> directoryReaders, IndexReaderMetadataResolver metadataResolver) throws IOException {
// If this flag isn't set to true, the MultiReader will increase the usage counter!
super( toReaderArray( directoryReaderHolders ), true );
this.directoryReaderHolders = directoryReaderHolders;
super( toReaderArray( directoryReaders ), true );
this.directoryReaders = directoryReaders;
this.metadataResolver = metadataResolver;
}

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

public IndexReaderMetadataResolver getMetadataResolver() {
return metadataResolver;
}

@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( DirectoryReaderHolder::close, directoryReaderHolders );
/*
* Important: we decrement a usage counter instead of directly closing the reader,
* just in case the reader is shared.
* If the reader is not shared, this is equivalent to closing the reader.
*/
closer.pushAll( DirectoryReader::decRef, directoryReaders );
}
if ( debugEnabled ) {
log.trace( "MultiReader closed." );
}
}

private static IndexReader[] toReaderArray(List<DirectoryReaderHolder> directoryReaderHolders) {
IndexReader[] indexReaders = new IndexReader[directoryReaderHolders.size()];
for ( int i = 0; i < directoryReaderHolders.size(); i++ ) {
indexReaders[i] = directoryReaderHolders.get( i ).get();
}
return indexReaders;
private static IndexReader[] toReaderArray(List<DirectoryReader> directoryReaders) {
return directoryReaders.toArray( new DirectoryReader[0] );
}

public static class Builder implements DirectoryReaderCollector {
private final List<DirectoryReaderHolder> directoryReaderHolders = new ArrayList<>();
private final List<DirectoryReader> directoryReaders = new ArrayList<>();
private final Map<DirectoryReader, String> mappedTypeNameByDirectoryReader = new HashMap<>();

private Builder() {
}

@Override
public void collect(String mappedTypeName, DirectoryReaderHolder directoryReaderHolder) {
directoryReaderHolders.add( directoryReaderHolder );
DirectoryReader reader = directoryReaderHolder.get();
mappedTypeNameByDirectoryReader.put( reader, mappedTypeName );
public void collect(String mappedTypeName, DirectoryReader directoryReader) {
directoryReaders.add( directoryReader );
mappedTypeNameByDirectoryReader.put( directoryReader, mappedTypeName );
}

HolderMultiReader build() throws IOException {
HibernateSearchMultiReader build() throws IOException {
IndexReaderMetadataResolver metadataResolver =
new IndexReaderMetadataResolver( mappedTypeNameByDirectoryReader );
return new HolderMultiReader( directoryReaderHolders, metadataResolver );
return new HibernateSearchMultiReader( directoryReaders, metadataResolver );
}
}
}

This file was deleted.

This file was deleted.

Expand Up @@ -12,7 +12,7 @@
import java.util.concurrent.CompletableFuture;

import org.hibernate.search.backend.lucene.logging.impl.Log;
import org.hibernate.search.backend.lucene.lowlevel.reader.impl.HolderMultiReader;
import org.hibernate.search.backend.lucene.lowlevel.reader.impl.HibernateSearchMultiReader;
import org.hibernate.search.backend.lucene.lowlevel.reader.impl.IndexReaderMetadataResolver;
import org.hibernate.search.backend.lucene.lowlevel.reader.impl.ReadIndexManagerContext;
import org.hibernate.search.backend.lucene.work.impl.LuceneReadWork;
Expand Down Expand Up @@ -93,15 +93,15 @@ protected void doStop() {

static class ReadTask<T> implements AutoCloseable, LuceneReadWorkExecutionContext {
private final Set<String> indexNames;
private final HolderMultiReader indexReader;
private final HibernateSearchMultiReader indexReader;
private final LuceneReadWork<T> work;

private T result;

ReadTask(Set<String> indexNames, Set<? extends ReadIndexManagerContext> indexManagerContexts,
Set<String> routingKeys, LuceneReadWork<T> work) {
this.indexNames = indexNames;
this.indexReader = HolderMultiReader.open( indexNames, indexManagerContexts, routingKeys );
this.indexReader = HibernateSearchMultiReader.open( indexNames, indexManagerContexts, routingKeys );
this.work = work;
}

Expand Down

0 comments on commit 8b8754b

Please sign in to comment.