Close the CachedIndexSearcher automatically

This commit is contained in:
Andrea Cavalli 2021-09-06 18:23:47 +02:00
parent 7230e96343
commit 5a79d2d7cb
3 changed files with 47 additions and 43 deletions

View File

@ -1,16 +1,25 @@
package it.cavallium.dbengine.database.disk;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.SearcherManager;
import org.jetbrains.annotations.Nullable;
public class CachedIndexSearcher {
private final IndexSearcher indexSearcher;
private final SearcherManager associatedSearcherManager;
private final Runnable afterFinalization;
private boolean inCache = true;
private int usages = 0;
public CachedIndexSearcher(IndexSearcher indexSearcher) {
public CachedIndexSearcher(IndexSearcher indexSearcher,
@Nullable SearcherManager associatedSearcherManager,
@Nullable Runnable afterFinalization) {
this.indexSearcher = indexSearcher;
this.associatedSearcherManager = associatedSearcherManager;
this.afterFinalization = afterFinalization;
}
public void incUsage() {
@ -19,30 +28,40 @@ public class CachedIndexSearcher {
}
}
/**
*
* @return true if closed
*/
public boolean decUsage() {
public void decUsage() throws IOException {
synchronized (this) {
usages--;
return isClosed();
if (mustClose()) {
try {
close();
} finally {
if (afterFinalization != null) afterFinalization.run();
}
}
}
}
/**
*
* @return true if closed
*/
public boolean removeFromCache() {
public void removeFromCache() throws IOException {
synchronized (this) {
inCache = false;
return isClosed();
if (mustClose()) {
try {
close();
} finally {
if (afterFinalization != null) afterFinalization.run();
}
}
}
}
private boolean isClosed() {
return this.inCache || this.usages > 0;
private void close() throws IOException {
if (associatedSearcherManager != null) {
associatedSearcherManager.release(indexSearcher);
}
}
private boolean mustClose() {
return !this.inCache && this.usages == 0;
}
public IndexReader getIndexReader() {

View File

@ -374,7 +374,7 @@ public class LLLocalLuceneIndex implements LLLuceneIndex {
return getMoreLikeThisQuery(snapshot, LuceneUtils.toLocalQueryParams(queryParams), mltDocumentFieldsFlux)
.flatMap(modifiedLocalQuery -> searcherManager.captureIndexSearcher(snapshot)
.flatMap(indexSearcher -> {
Mono<Void> releaseMono = searcherManager.releaseUsedIndexSearcher(snapshot, indexSearcher);
Mono<Void> releaseMono = searcherManager.releaseUsedIndexSearcher(indexSearcher);
return localSearcher
.collect(indexSearcher.getIndexSearcher(), releaseMono, modifiedLocalQuery, keyFieldName)
.map(result -> new LLSearchResultShard(result.results(), result.totalHitsCount(), result.release()))
@ -390,7 +390,7 @@ public class LLLocalLuceneIndex implements LLLuceneIndex {
return getMoreLikeThisQuery(snapshot, LuceneUtils.toLocalQueryParams(queryParams), mltDocumentFieldsFlux)
.flatMap(modifiedLocalQuery -> searcherManager.captureIndexSearcher(snapshot)
.flatMap(indexSearcher -> {
Mono<Void> releaseMono = searcherManager.releaseUsedIndexSearcher(snapshot, indexSearcher);
Mono<Void> releaseMono = searcherManager.releaseUsedIndexSearcher(indexSearcher);
return shardSearcher
.searchOn(indexSearcher.getIndexSearcher(), releaseMono, modifiedLocalQuery)
.onErrorResume(ex -> releaseMono.then(Mono.error(ex)));
@ -467,7 +467,7 @@ public class LLLocalLuceneIndex implements LLLuceneIndex {
public Mono<LLSearchResultShard> search(@Nullable LLSnapshot snapshot, QueryParams queryParams, String keyFieldName) {
LocalQueryParams localQueryParams = LuceneUtils.toLocalQueryParams(queryParams);
return searcherManager.captureIndexSearcher(snapshot).flatMap(indexSearcher -> {
Mono<Void> releaseMono = searcherManager.releaseUsedIndexSearcher(snapshot, indexSearcher);
Mono<Void> releaseMono = searcherManager.releaseUsedIndexSearcher(indexSearcher);
return localSearcher
.collect(indexSearcher.getIndexSearcher(), releaseMono, localQueryParams, keyFieldName)
.map(result -> new LLSearchResultShard(result.results(), result.totalHitsCount(), result.release()))
@ -481,7 +481,7 @@ public class LLLocalLuceneIndex implements LLLuceneIndex {
LocalQueryParams localQueryParams = LuceneUtils.toLocalQueryParams(queryParams);
return searcherManager.captureIndexSearcher(snapshot)
.flatMap(indexSearcher -> {
Mono<Void> releaseMono = searcherManager.releaseUsedIndexSearcher(snapshot, indexSearcher);
Mono<Void> releaseMono = searcherManager.releaseUsedIndexSearcher(indexSearcher);
return shardSearcher.searchOn(indexSearcher.getIndexSearcher(), releaseMono, localQueryParams)
.onErrorResume(ex -> releaseMono.then(Mono.error(ex)));
});

View File

@ -78,13 +78,16 @@ public class PooledIndexSearcherManager {
private Mono<CachedIndexSearcher> generateCachedSearcher(@Nullable LLSnapshot snapshot) {
return Mono.fromCallable(() -> {
IndexSearcher indexSearcher;
SearcherManager associatedSearcherManager;
if (snapshot == null) {
indexSearcher = searcherManager.acquire();
indexSearcher.setSimilarity(similarity);
associatedSearcherManager = searcherManager;
} else {
indexSearcher = snapshotsManager.resolveSnapshot(snapshot).getIndexSearcher();
associatedSearcherManager = null;
}
return new CachedIndexSearcher(indexSearcher);
return new CachedIndexSearcher(indexSearcher, associatedSearcherManager, activeSearchers::decrementAndGet);
})
.cacheInvalidateWhen(indexSearcher -> Mono
.firstWithSignal(
@ -94,16 +97,7 @@ public class PooledIndexSearcherManager {
indexSearcher -> {
try {
// Mark as removed from cache
if (indexSearcher.removeFromCache()) {
// Close
try {
if (snapshot == null) {
searcherManager.release(indexSearcher.getIndexSearcher());
}
} finally {
activeSearchers.decrementAndGet();
}
}
indexSearcher.removeFromCache();
} catch (IOException e) {
e.printStackTrace();
}
@ -142,7 +136,7 @@ public class PooledIndexSearcherManager {
return Flux.usingWhen(
this.captureIndexSearcher(snapshot),
indexSearcher -> searcherFunction.apply(indexSearcher.getIndexSearcher()),
indexSearcher -> this.releaseUsedIndexSearcher(snapshot, indexSearcher)
this::releaseUsedIndexSearcher
);
}
@ -150,7 +144,7 @@ public class PooledIndexSearcherManager {
return Mono.usingWhen(
this.captureIndexSearcher(snapshot),
indexSearcher -> searcherFunction.apply(indexSearcher.getIndexSearcher()),
indexSearcher -> this.releaseUsedIndexSearcher(snapshot, indexSearcher)
this::releaseUsedIndexSearcher
);
}
@ -172,20 +166,11 @@ public class PooledIndexSearcherManager {
}
}
public Mono<Void> releaseUsedIndexSearcher(@Nullable LLSnapshot snapshot, CachedIndexSearcher indexSearcher) {
public Mono<Void> releaseUsedIndexSearcher(CachedIndexSearcher indexSearcher) {
return Mono.fromRunnable(() -> {
try {
// Decrement reference count
if (indexSearcher.decUsage()) {
// Close
try {
if (snapshot == null) {
searcherManager.release(indexSearcher.getIndexSearcher());
}
} finally {
activeSearchers.decrementAndGet();
}
}
indexSearcher.decUsage();
} catch (IOException e) {
e.printStackTrace();
}