diff --git a/src/main/java/it/cavallium/dbengine/database/disk/CachedIndexSearcherManager.java b/src/main/java/it/cavallium/dbengine/database/disk/CachedIndexSearcherManager.java index 343e8c8..0c6f050 100644 --- a/src/main/java/it/cavallium/dbengine/database/disk/CachedIndexSearcherManager.java +++ b/src/main/java/it/cavallium/dbengine/database/disk/CachedIndexSearcherManager.java @@ -140,18 +140,18 @@ public class CachedIndexSearcherManager implements IndexSearcherManager { return Mono.fromCallable(() -> { activeSearchers.register(); IndexSearcher indexSearcher; + boolean decRef; if (snapshot == null) { indexSearcher = searcherManager.acquire(); + decRef = true; } else { indexSearcher = snapshotsManager.resolveSnapshot(snapshot).getIndexSearcher(); + decRef = false; } indexSearcher.setSimilarity(similarity); assert indexSearcher.getIndexReader().getRefCount() > 0; - return indexSearcher; + return new LLIndexSearcher(indexSearcher, decRef, this::dropCachedIndexSearcher).send(); }) - // todo: re-enable caching if needed - //.cacheInvalidateWhen(tuple -> onInvalidateCache) - .map(indexSearcher -> new LLIndexSearcher(indexSearcher, this::dropCachedIndexSearcher).send()) .takeUntilOther(onClose) .doOnDiscard(Send.class, Send::close); }); diff --git a/src/main/java/it/cavallium/dbengine/database/disk/LLIndexSearcher.java b/src/main/java/it/cavallium/dbengine/database/disk/LLIndexSearcher.java index 19ee489..289c922 100644 --- a/src/main/java/it/cavallium/dbengine/database/disk/LLIndexSearcher.java +++ b/src/main/java/it/cavallium/dbengine/database/disk/LLIndexSearcher.java @@ -2,23 +2,24 @@ package it.cavallium.dbengine.database.disk; import io.net5.buffer.api.Drop; import io.net5.buffer.api.Owned; -import io.net5.buffer.api.internal.ResourceSupport; import it.cavallium.dbengine.database.LiveResourceSupport; 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; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LLIndexSearcher extends LiveResourceSupport { - private IndexSearcher indexSearcher; + private static final Logger logger = LoggerFactory.getLogger(LLIndexSearcher.class); - public LLIndexSearcher(IndexSearcher indexSearcher, Drop drop) { - super(drop); + private IndexSearcher indexSearcher; + private final boolean decRef; + + public LLIndexSearcher(IndexSearcher indexSearcher, boolean decRef, Drop drop) { + super(new CloseOnDrop(drop)); this.indexSearcher = indexSearcher; + this.decRef = decRef; } public IndexReader getIndexReader() { @@ -43,10 +44,33 @@ public class LLIndexSearcher extends LiveResourceSupport prepareSend() { var indexSearcher = this.indexSearcher; - return drop -> new LLIndexSearcher(indexSearcher, drop); + return drop -> new LLIndexSearcher(indexSearcher, decRef, drop); } protected void makeInaccessible() { this.indexSearcher = null; } + + private static class CloseOnDrop implements Drop { + + private final Drop delegate; + + public CloseOnDrop(Drop drop) { + if (drop instanceof CloseOnDrop closeOnDrop) { + this.delegate = closeOnDrop.delegate; + } else { + this.delegate = drop; + } + } + + @Override + public void drop(LLIndexSearcher obj) { + try { + obj.indexSearcher.getIndexReader().decRef(); + } catch (IOException ex) { + logger.error("Failed to drop IndexReader", ex); + } + delegate.drop(obj); + } + } } diff --git a/src/main/java/it/cavallium/dbengine/lucene/searcher/SimpleUnsortedUnscoredLuceneMultiSearcher.java b/src/main/java/it/cavallium/dbengine/lucene/searcher/SimpleUnsortedUnscoredLuceneMultiSearcher.java index ad2b99c..d5e497f 100644 --- a/src/main/java/it/cavallium/dbengine/lucene/searcher/SimpleUnsortedUnscoredLuceneMultiSearcher.java +++ b/src/main/java/it/cavallium/dbengine/lucene/searcher/SimpleUnsortedUnscoredLuceneMultiSearcher.java @@ -43,7 +43,7 @@ public class SimpleUnsortedUnscoredLuceneMultiSearcher implements LuceneMultiSea indexSearchers -> Flux .fromIterable(indexSearchers.shards()) .flatMap(searcher -> { - var llSearcher = Mono.fromCallable(() -> new LLIndexSearcher(searcher, d -> {}).send()); + var llSearcher = Mono.fromCallable(() -> new LLIndexSearcher(searcher, false, d -> {}).send()); return localSearcher.collect(llSearcher, localQueryParams, keyFieldName, transformer); }) .collectList()