Update netty
This commit is contained in:
parent
9646ddcb28
commit
818bd20ed9
9
pom.xml
9
pom.xml
@ -99,10 +99,6 @@
|
|||||||
<groupId>io.net5</groupId>
|
<groupId>io.net5</groupId>
|
||||||
<artifactId>netty-buffer</artifactId>
|
<artifactId>netty-buffer</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>io.net5.incubator</groupId>
|
|
||||||
<artifactId>netty-incubator-buffer-memseg</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.xml.bind</groupId>
|
<groupId>javax.xml.bind</groupId>
|
||||||
<artifactId>jaxb-api</artifactId>
|
<artifactId>jaxb-api</artifactId>
|
||||||
@ -275,11 +271,6 @@
|
|||||||
<artifactId>netty-buffer</artifactId>
|
<artifactId>netty-buffer</artifactId>
|
||||||
<version>5.0.0.Final-SNAPSHOT</version>
|
<version>5.0.0.Final-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>io.net5.incubator</groupId>
|
|
||||||
<artifactId>netty-incubator-buffer-memseg</artifactId>
|
|
||||||
<version>0.0.1.Final-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.xml.bind</groupId>
|
<groupId>javax.xml.bind</groupId>
|
||||||
<artifactId>jaxb-api</artifactId>
|
<artifactId>jaxb-api</artifactId>
|
||||||
|
@ -94,7 +94,7 @@ public class LuceneIndexImpl<T, U> implements LuceneIndex<T, U> {
|
|||||||
.fromCallable(signal::key)
|
.fromCallable(signal::key)
|
||||||
.map(indicizer::getKey), signal.score())),
|
.map(indicizer::getKey), signal.score())),
|
||||||
llSearchResult.totalHitsCount(),
|
llSearchResult.totalHitsCount(),
|
||||||
d -> llSearchResult.close()
|
llSearchResult::close
|
||||||
).send();
|
).send();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ public class LuceneIndexImpl<T, U> implements LuceneIndex<T, U> {
|
|||||||
return new SearchResult<>(llSearchResult.results().map(signal -> {
|
return new SearchResult<>(llSearchResult.results().map(signal -> {
|
||||||
var key = Mono.fromCallable(signal::key).map(indicizer::getKey);
|
var key = Mono.fromCallable(signal::key).map(indicizer::getKey);
|
||||||
return new SearchResultItem<>(key, key.flatMap(valueGetter::get), signal.score());
|
return new SearchResultItem<>(key, key.flatMap(valueGetter::get), signal.score());
|
||||||
}), llSearchResult.totalHitsCount(), d -> llSearchResult.close()).send();
|
}), llSearchResult.totalHitsCount(), llSearchResult::close).send();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,10 +131,7 @@ public class LuceneIndexImpl<T, U> implements LuceneIndex<T, U> {
|
|||||||
Mono.just(tuple3.getT3().orElseThrow()),
|
Mono.just(tuple3.getT3().orElseThrow()),
|
||||||
tuple3.getT1()
|
tuple3.getT1()
|
||||||
));
|
));
|
||||||
return new SearchResult<>(resultItemsFlux,
|
return new SearchResult<>(resultItemsFlux, llSearchResult.totalHitsCount(), llSearchResult::close).send();
|
||||||
llSearchResult.totalHitsCount(),
|
|
||||||
d -> llSearchResult.close()
|
|
||||||
).send();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,18 +14,39 @@ import reactor.core.publisher.Mono;
|
|||||||
|
|
||||||
public final class SearchResult<T, U> extends LiveResourceSupport<SearchResult<T, U>, SearchResult<T, U>> {
|
public final class SearchResult<T, U> extends LiveResourceSupport<SearchResult<T, U>, SearchResult<T, U>> {
|
||||||
|
|
||||||
|
private static final Drop<SearchResult<?, ?>> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(SearchResult<?, ?> obj) {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<SearchResult<?, ?>> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(SearchResult<?, ?> obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private Flux<SearchResultItem<T, U>> results;
|
private Flux<SearchResultItem<T, U>> results;
|
||||||
private TotalHitsCount totalHitsCount;
|
private TotalHitsCount totalHitsCount;
|
||||||
|
private Runnable onClose;
|
||||||
|
|
||||||
public SearchResult(Flux<SearchResultItem<T, U>> results, TotalHitsCount totalHitsCount,
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
Drop<SearchResult<T, U>> drop) {
|
public SearchResult(Flux<SearchResultItem<T, U>> results, TotalHitsCount totalHitsCount, Runnable onClose) {
|
||||||
super(drop);
|
super((Drop<SearchResult<T,U>>) (Drop) DROP);
|
||||||
this.results = results;
|
this.results = results;
|
||||||
this.totalHitsCount = totalHitsCount;
|
this.totalHitsCount = totalHitsCount;
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, U> SearchResult<T, U> empty() {
|
public static <T, U> SearchResult<T, U> empty() {
|
||||||
return new SearchResult<T, U>(Flux.empty(), TotalHitsCount.of(0, true), d -> {});
|
return new SearchResult<T, U>(Flux.empty(), TotalHitsCount.of(0, true), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Flux<SearchResultItem<T, U>> results() {
|
public Flux<SearchResultItem<T, U>> results() {
|
||||||
@ -50,11 +71,17 @@ public final class SearchResult<T, U> extends LiveResourceSupport<SearchResult<T
|
|||||||
protected Owned<SearchResult<T, U>> prepareSend() {
|
protected Owned<SearchResult<T, U>> prepareSend() {
|
||||||
var results = this.results;
|
var results = this.results;
|
||||||
var totalHitsCount = this.totalHitsCount;
|
var totalHitsCount = this.totalHitsCount;
|
||||||
return drop -> new SearchResult<>(results, totalHitsCount, drop);
|
var onClose = this.onClose;
|
||||||
|
return drop -> {
|
||||||
|
var instance = new SearchResult<>(results, totalHitsCount, onClose);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.results = null;
|
this.results = null;
|
||||||
this.totalHitsCount = null;
|
this.totalHitsCount = null;
|
||||||
|
this.onClose = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,42 +2,58 @@ package it.cavallium.dbengine.client;
|
|||||||
|
|
||||||
import io.net5.buffer.api.Drop;
|
import io.net5.buffer.api.Drop;
|
||||||
import io.net5.buffer.api.Owned;
|
import io.net5.buffer.api.Owned;
|
||||||
import io.net5.buffer.api.internal.ResourceSupport;
|
|
||||||
import it.cavallium.dbengine.client.query.current.data.TotalHitsCount;
|
import it.cavallium.dbengine.client.query.current.data.TotalHitsCount;
|
||||||
import it.cavallium.dbengine.database.LLSearchResultShard;
|
|
||||||
import it.cavallium.dbengine.database.LiveResourceSupport;
|
import it.cavallium.dbengine.database.LiveResourceSupport;
|
||||||
import it.cavallium.dbengine.database.collections.ValueGetter;
|
import it.cavallium.dbengine.database.collections.ValueGetter;
|
||||||
import java.util.Objects;
|
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
import org.warp.commonutils.log.Logger;
|
import org.warp.commonutils.log.Logger;
|
||||||
import org.warp.commonutils.log.LoggerFactory;
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class SearchResultKeys<T> extends LiveResourceSupport<SearchResultKeys<T>, SearchResultKeys<T>> {
|
public final class SearchResultKeys<T> extends LiveResourceSupport<SearchResultKeys<T>, SearchResultKeys<T>> {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SearchResultKeys.class);
|
private static final Logger logger = LoggerFactory.getLogger(SearchResultKeys.class);
|
||||||
|
|
||||||
|
private static final Drop<SearchResultKeys<?>> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(SearchResultKeys<?> obj) {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<SearchResultKeys<?>> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(SearchResultKeys<?> obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private Flux<SearchResultKey<T>> results;
|
private Flux<SearchResultKey<T>> results;
|
||||||
private TotalHitsCount totalHitsCount;
|
private TotalHitsCount totalHitsCount;
|
||||||
|
private Runnable onClose;
|
||||||
|
|
||||||
public SearchResultKeys(Flux<SearchResultKey<T>> results, TotalHitsCount totalHitsCount,
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
Drop<SearchResultKeys<T>> drop) {
|
public SearchResultKeys(Flux<SearchResultKey<T>> results, TotalHitsCount totalHitsCount, Runnable onClose) {
|
||||||
super(drop);
|
super((Drop<SearchResultKeys<T>>) (Drop) DROP);
|
||||||
this.results = results;
|
this.results = results;
|
||||||
this.totalHitsCount = totalHitsCount;
|
this.totalHitsCount = totalHitsCount;
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> SearchResultKeys<T> empty() {
|
public static <T> SearchResultKeys<T> empty() {
|
||||||
return new SearchResultKeys<T>(Flux.empty(), TotalHitsCount.of(0, true), d -> {});
|
return new SearchResultKeys<>(Flux.empty(), TotalHitsCount.of(0, true), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <U> SearchResult<T, U> withValues(ValueGetter<T, U> valuesGetter) {
|
public <U> SearchResult<T, U> withValues(ValueGetter<T, U> valuesGetter) {
|
||||||
return new SearchResult<>(results.map(item -> new SearchResultItem<>(item.key(),
|
return new SearchResult<>(results.map(item -> new SearchResultItem<>(item.key(),
|
||||||
item.key().flatMap(valuesGetter::get),
|
item.key().flatMap(valuesGetter::get),
|
||||||
item.score()
|
item.score()
|
||||||
)), totalHitsCount, d -> this.close());
|
)), totalHitsCount, this::close);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Flux<SearchResultKey<T>> results() {
|
public Flux<SearchResultKey<T>> results() {
|
||||||
@ -62,13 +78,19 @@ public final class SearchResultKeys<T> extends LiveResourceSupport<SearchResultK
|
|||||||
protected Owned<SearchResultKeys<T>> prepareSend() {
|
protected Owned<SearchResultKeys<T>> prepareSend() {
|
||||||
var results = this.results;
|
var results = this.results;
|
||||||
var totalHitsCount = this.totalHitsCount;
|
var totalHitsCount = this.totalHitsCount;
|
||||||
|
var onClose = this.onClose;
|
||||||
makeInaccessible();
|
makeInaccessible();
|
||||||
return drop -> new SearchResultKeys<>(results, totalHitsCount, drop);
|
return drop -> {
|
||||||
|
var instance = new SearchResultKeys<>(results, totalHitsCount, onClose);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.results = null;
|
this.results = null;
|
||||||
this.totalHitsCount = null;
|
this.totalHitsCount = null;
|
||||||
|
this.onClose = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,66 @@ import io.net5.buffer.api.Drop;
|
|||||||
import io.net5.buffer.api.Owned;
|
import io.net5.buffer.api.Owned;
|
||||||
import io.net5.buffer.api.Send;
|
import io.net5.buffer.api.Send;
|
||||||
import io.net5.buffer.api.internal.ResourceSupport;
|
import io.net5.buffer.api.internal.ResourceSupport;
|
||||||
|
import it.cavallium.dbengine.client.SearchResultKeys;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
|
|
||||||
public class LLDelta extends LiveResourceSupport<LLDelta, LLDelta> {
|
public class LLDelta extends LiveResourceSupport<LLDelta, LLDelta> {
|
||||||
@Nullable
|
|
||||||
private final Buffer previous;
|
|
||||||
@Nullable
|
|
||||||
private final Buffer current;
|
|
||||||
|
|
||||||
private LLDelta(@Nullable Send<Buffer> previous, @Nullable Send<Buffer> current, Drop<LLDelta> drop) {
|
private static final Logger logger = LoggerFactory.getLogger(LLDelta.class);
|
||||||
super(new LLDelta.CloseOnDrop(drop));
|
|
||||||
|
private static final Drop<LLDelta> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(LLDelta obj) {
|
||||||
|
try {
|
||||||
|
if (obj.previous != null) {
|
||||||
|
obj.previous.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close previous", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.current != null) {
|
||||||
|
obj.current.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close current", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close onDrop", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<LLDelta> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(LLDelta obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Buffer previous;
|
||||||
|
@Nullable
|
||||||
|
private Buffer current;
|
||||||
|
@Nullable
|
||||||
|
private Runnable onClose;
|
||||||
|
|
||||||
|
private LLDelta(@Nullable Send<Buffer> previous, @Nullable Send<Buffer> current, @Nullable Runnable onClose) {
|
||||||
|
super(DROP);
|
||||||
assert isAllAccessible();
|
assert isAllAccessible();
|
||||||
this.previous = previous != null ? previous.receive().makeReadOnly() : null;
|
this.previous = previous != null ? previous.receive().makeReadOnly() : null;
|
||||||
this.current = current != null ? current.receive().makeReadOnly() : null;
|
this.current = current != null ? current.receive().makeReadOnly() : null;
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAllAccessible() {
|
private boolean isAllAccessible() {
|
||||||
@ -31,7 +77,7 @@ public class LLDelta extends LiveResourceSupport<LLDelta, LLDelta> {
|
|||||||
|
|
||||||
public static LLDelta of(Send<Buffer> min, Send<Buffer> max) {
|
public static LLDelta of(Send<Buffer> min, Send<Buffer> max) {
|
||||||
assert (min == null && max == null) || (min != max);
|
assert (min == null && max == null) || (min != max);
|
||||||
return new LLDelta(min, max, d -> {});
|
return new LLDelta(min, max, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Send<Buffer> previous() {
|
public Send<Buffer> previous() {
|
||||||
@ -86,42 +132,28 @@ public class LLDelta extends LiveResourceSupport<LLDelta, LLDelta> {
|
|||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LLDelta copy() {
|
|
||||||
ensureOwned();
|
|
||||||
var prevCopy = previous != null ? previous.copy().send() : null;
|
|
||||||
Send<Buffer> curCopy = current != null ? current.copy().send() : null;
|
|
||||||
return new LLDelta(prevCopy, curCopy, d -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RuntimeException createResourceClosedException() {
|
protected RuntimeException createResourceClosedException() {
|
||||||
return new IllegalStateException("Closed");
|
return new IllegalStateException("Closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void makeInaccessible() {
|
||||||
|
this.current = null;
|
||||||
|
this.previous = null;
|
||||||
|
this.onClose = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Owned<LLDelta> prepareSend() {
|
protected Owned<LLDelta> prepareSend() {
|
||||||
Send<Buffer> minSend = this.previous != null ? this.previous.send() : null;
|
Send<Buffer> minSend = this.previous != null ? this.previous.send() : null;
|
||||||
Send<Buffer> maxSend = this.current != null ? this.current.send() : null;
|
Send<Buffer> maxSend = this.current != null ? this.current.send() : null;
|
||||||
return drop -> new LLDelta(minSend, maxSend, drop);
|
Runnable onClose = this.onClose;
|
||||||
|
return drop -> {
|
||||||
|
var instance = new LLDelta(minSend, maxSend, onClose);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CloseOnDrop implements Drop<LLDelta> {
|
|
||||||
|
|
||||||
private final Drop<LLDelta> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<LLDelta> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(LLDelta obj) {
|
|
||||||
if (obj.previous != null) obj.previous.close();
|
|
||||||
if (obj.current != null) obj.current.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,38 +5,74 @@ import io.net5.buffer.api.Drop;
|
|||||||
import io.net5.buffer.api.Owned;
|
import io.net5.buffer.api.Owned;
|
||||||
import io.net5.buffer.api.Send;
|
import io.net5.buffer.api.Send;
|
||||||
import io.net5.buffer.api.internal.ResourceSupport;
|
import io.net5.buffer.api.internal.ResourceSupport;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
|
|
||||||
public class LLEntry extends LiveResourceSupport<LLEntry, LLEntry> {
|
public class LLEntry extends LiveResourceSupport<LLEntry, LLEntry> {
|
||||||
@NotNull
|
|
||||||
private final Buffer key;
|
|
||||||
@NotNull
|
|
||||||
private final Buffer value;
|
|
||||||
|
|
||||||
private LLEntry(@NotNull Send<Buffer> key, @NotNull Send<Buffer> value, Drop<LLEntry> drop) {
|
private static final Logger logger = LoggerFactory.getLogger(LLEntry.class);
|
||||||
super(new LLEntry.CloseOnDrop(drop));
|
|
||||||
|
private static final Drop<LLEntry> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(LLEntry obj) {
|
||||||
|
try {
|
||||||
|
if (obj.key != null) {
|
||||||
|
obj.key.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close key", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.value != null) {
|
||||||
|
obj.value.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close value", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<LLEntry> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(LLEntry obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Buffer key;
|
||||||
|
@Nullable
|
||||||
|
private Buffer value;
|
||||||
|
|
||||||
|
private LLEntry(@NotNull Send<Buffer> key, @NotNull Send<Buffer> value) {
|
||||||
|
super(DROP);
|
||||||
this.key = key.receive().makeReadOnly();
|
this.key = key.receive().makeReadOnly();
|
||||||
this.value = value.receive().makeReadOnly();
|
this.value = value.receive().makeReadOnly();
|
||||||
assert isAllAccessible();
|
assert isAllAccessible();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAllAccessible() {
|
private boolean isAllAccessible() {
|
||||||
assert key.isAccessible();
|
assert key != null && key.isAccessible();
|
||||||
assert value.isAccessible();
|
assert value != null && value.isAccessible();
|
||||||
assert this.isAccessible();
|
assert this.isAccessible();
|
||||||
assert this.isOwned();
|
assert this.isOwned();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LLEntry of(@NotNull Send<Buffer> key, @NotNull Send<Buffer> value) {
|
public static LLEntry of(@NotNull Send<Buffer> key, @NotNull Send<Buffer> value) {
|
||||||
return new LLEntry(key, value, d -> {});
|
return new LLEntry(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Send<Buffer> getKey() {
|
public Send<Buffer> getKey() {
|
||||||
ensureOwned();
|
ensureOwned();
|
||||||
return key.copy().send();
|
return Objects.requireNonNull(key).copy().send();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Buffer getKeyUnsafe() {
|
public Buffer getKeyUnsafe() {
|
||||||
@ -45,7 +81,7 @@ public class LLEntry extends LiveResourceSupport<LLEntry, LLEntry> {
|
|||||||
|
|
||||||
public Send<Buffer> getValue() {
|
public Send<Buffer> getValue() {
|
||||||
ensureOwned();
|
ensureOwned();
|
||||||
return value.copy().send();
|
return Objects.requireNonNull(value).copy().send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -64,6 +100,12 @@ public class LLEntry extends LiveResourceSupport<LLEntry, LLEntry> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void makeInaccessible() {
|
||||||
|
this.key = null;
|
||||||
|
this.value = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) {
|
if (this == o) {
|
||||||
@ -91,11 +133,6 @@ public class LLEntry extends LiveResourceSupport<LLEntry, LLEntry> {
|
|||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LLEntry copy() {
|
|
||||||
ensureOwned();
|
|
||||||
return new LLEntry(key.copy().send(), value.copy().send(), d -> {});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RuntimeException createResourceClosedException() {
|
protected RuntimeException createResourceClosedException() {
|
||||||
return new IllegalStateException("Closed");
|
return new IllegalStateException("Closed");
|
||||||
@ -105,28 +142,12 @@ public class LLEntry extends LiveResourceSupport<LLEntry, LLEntry> {
|
|||||||
protected Owned<LLEntry> prepareSend() {
|
protected Owned<LLEntry> prepareSend() {
|
||||||
Send<Buffer> keySend;
|
Send<Buffer> keySend;
|
||||||
Send<Buffer> valueSend;
|
Send<Buffer> valueSend;
|
||||||
keySend = this.key.send();
|
keySend = Objects.requireNonNull(this.key).send();
|
||||||
valueSend = this.value.send();
|
valueSend = Objects.requireNonNull(this.value).send();
|
||||||
return drop -> new LLEntry(keySend, valueSend, drop);
|
return drop -> {
|
||||||
}
|
var instance = new LLEntry(keySend, valueSend);
|
||||||
|
drop.attach(instance);
|
||||||
private static class CloseOnDrop implements Drop<LLEntry> {
|
return instance;
|
||||||
|
};
|
||||||
private final Drop<LLEntry> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<LLEntry> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(LLEntry obj) {
|
|
||||||
obj.key.close();
|
|
||||||
obj.value.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,54 @@ import io.net5.buffer.api.Send;
|
|||||||
import io.net5.buffer.api.internal.ResourceSupport;
|
import io.net5.buffer.api.internal.ResourceSupport;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Range of data, from min (inclusive),to max (exclusive)
|
* Range of data, from min (inclusive),to max (exclusive)
|
||||||
*/
|
*/
|
||||||
public class LLRange extends LiveResourceSupport<LLRange, LLRange> {
|
public class LLRange extends LiveResourceSupport<LLRange, LLRange> {
|
||||||
|
|
||||||
private static final LLRange RANGE_ALL = new LLRange(null, null, null, d -> {});
|
private static final Logger logger = LoggerFactory.getLogger(LLRange.class);
|
||||||
|
|
||||||
|
private static final Drop<LLRange> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(LLRange obj) {
|
||||||
|
try {
|
||||||
|
if (obj.min != null) {
|
||||||
|
obj.min.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close min", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.max != null) {
|
||||||
|
obj.max.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close max", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.single != null) {
|
||||||
|
obj.single.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close single", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<LLRange> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(LLRange obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final LLRange RANGE_ALL = new LLRange(null, null, null);
|
||||||
@Nullable
|
@Nullable
|
||||||
private Buffer min;
|
private Buffer min;
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -23,8 +64,8 @@ public class LLRange extends LiveResourceSupport<LLRange, LLRange> {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Buffer single;
|
private Buffer single;
|
||||||
|
|
||||||
private LLRange(Send<Buffer> min, Send<Buffer> max, Send<Buffer> single, Drop<LLRange> drop) {
|
private LLRange(Send<Buffer> min, Send<Buffer> max, Send<Buffer> single) {
|
||||||
super(new CloseOnDrop(drop));
|
super(DROP);
|
||||||
assert isAllAccessible();
|
assert isAllAccessible();
|
||||||
assert single == null || (min == null && max == null);
|
assert single == null || (min == null && max == null);
|
||||||
this.min = min != null ? min.receive().makeReadOnly() : null;
|
this.min = min != null ? min.receive().makeReadOnly() : null;
|
||||||
@ -46,19 +87,19 @@ public class LLRange extends LiveResourceSupport<LLRange, LLRange> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static LLRange from(Send<Buffer> min) {
|
public static LLRange from(Send<Buffer> min) {
|
||||||
return new LLRange(min, null, null, d -> {});
|
return new LLRange(min, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LLRange to(Send<Buffer> max) {
|
public static LLRange to(Send<Buffer> max) {
|
||||||
return new LLRange(null, max, null, d -> {});
|
return new LLRange(null, max, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LLRange single(Send<Buffer> single) {
|
public static LLRange single(Send<Buffer> single) {
|
||||||
return new LLRange(null, null, single, d -> {});
|
return new LLRange(null, null, single);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LLRange of(Send<Buffer> min, Send<Buffer> max) {
|
public static LLRange of(Send<Buffer> min, Send<Buffer> max) {
|
||||||
return new LLRange(min, max, null, d -> {});
|
return new LLRange(min, max, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAll() {
|
public boolean isAll() {
|
||||||
@ -179,8 +220,7 @@ public class LLRange extends LiveResourceSupport<LLRange, LLRange> {
|
|||||||
ensureOwned();
|
ensureOwned();
|
||||||
return new LLRange(min != null ? min.copy().send() : null,
|
return new LLRange(min != null ? min.copy().send() : null,
|
||||||
max != null ? max.copy().send() : null,
|
max != null ? max.copy().send() : null,
|
||||||
single != null ? single.copy().send(): null,
|
single != null ? single.copy().send(): null
|
||||||
d -> {}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +237,11 @@ public class LLRange extends LiveResourceSupport<LLRange, LLRange> {
|
|||||||
minSend = this.min != null ? this.min.send() : null;
|
minSend = this.min != null ? this.min.send() : null;
|
||||||
maxSend = this.max != null ? this.max.send() : null;
|
maxSend = this.max != null ? this.max.send() : null;
|
||||||
singleSend = this.single != null ? this.single.send() : null;
|
singleSend = this.single != null ? this.single.send() : null;
|
||||||
return drop -> new LLRange(minSend, maxSend, singleSend, drop);
|
return drop -> {
|
||||||
|
var instance = new LLRange(minSend, maxSend, singleSend);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
@ -205,25 +249,4 @@ public class LLRange extends LiveResourceSupport<LLRange, LLRange> {
|
|||||||
this.max = null;
|
this.max = null;
|
||||||
this.single = null;
|
this.single = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CloseOnDrop implements Drop<LLRange> {
|
|
||||||
|
|
||||||
private final Drop<LLRange> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<LLRange> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(LLRange obj) {
|
|
||||||
if (obj.min != null) obj.min.close();
|
|
||||||
if (obj.max != null) obj.max.close();
|
|
||||||
if (obj.single != null) obj.single.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,38 @@ public final class LLSearchResultShard extends LiveResourceSupport<LLSearchResul
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(LLSearchResultShard.class);
|
private static final Logger logger = LoggerFactory.getLogger(LLSearchResultShard.class);
|
||||||
|
|
||||||
|
private static final Drop<LLSearchResultShard> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(LLSearchResultShard obj) {
|
||||||
|
try {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close onClose", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<LLSearchResultShard> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(LLSearchResultShard obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private Flux<LLKeyScore> results;
|
private Flux<LLKeyScore> results;
|
||||||
private TotalHitsCount totalHitsCount;
|
private TotalHitsCount totalHitsCount;
|
||||||
|
private Runnable onClose;
|
||||||
|
|
||||||
public LLSearchResultShard(Flux<LLKeyScore> results, TotalHitsCount totalHitsCount, Drop<LLSearchResultShard> drop) {
|
public LLSearchResultShard(Flux<LLKeyScore> results, TotalHitsCount totalHitsCount, Runnable onClose) {
|
||||||
super(drop);
|
super(DROP);
|
||||||
this.results = results;
|
this.results = results;
|
||||||
this.totalHitsCount = totalHitsCount;
|
this.totalHitsCount = totalHitsCount;
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Flux<LLKeyScore> results() {
|
public Flux<LLKeyScore> results() {
|
||||||
@ -65,11 +90,13 @@ public final class LLSearchResultShard extends LiveResourceSupport<LLSearchResul
|
|||||||
protected Owned<LLSearchResultShard> prepareSend() {
|
protected Owned<LLSearchResultShard> prepareSend() {
|
||||||
var results = this.results;
|
var results = this.results;
|
||||||
var totalHitsCount = this.totalHitsCount;
|
var totalHitsCount = this.totalHitsCount;
|
||||||
return drop -> new LLSearchResultShard(results, totalHitsCount, drop);
|
var onClose = this.onClose;
|
||||||
|
return drop -> new LLSearchResultShard(results, totalHitsCount, onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.results = null;
|
this.results = null;
|
||||||
this.totalHitsCount = null;
|
this.totalHitsCount = null;
|
||||||
|
this.onClose = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,8 @@ public class DatabaseEmpty {
|
|||||||
private DatabaseEmpty() {
|
private DatabaseEmpty() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DatabaseStageEntry<Nothing> create(LLDictionary dictionary,
|
public static DatabaseStageEntry<Nothing> create(LLDictionary dictionary, Send<Buffer> key, Runnable onClose) {
|
||||||
Send<Buffer> key,
|
return new DatabaseSingle<>(dictionary, key, nothingSerializer(dictionary.getAllocator()), onClose);
|
||||||
Drop<DatabaseSingle<Nothing>> drop) {
|
|
||||||
return new DatabaseSingle<>(dictionary, key, nothingSerializer(dictionary.getAllocator()), drop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Nothing {
|
public static final class Nothing {
|
||||||
|
@ -44,26 +44,26 @@ public class DatabaseMapDictionary<T, U> extends DatabaseMapDictionaryDeep<T, U,
|
|||||||
@NotNull Send<Buffer> prefixKey,
|
@NotNull Send<Buffer> prefixKey,
|
||||||
SerializerFixedBinaryLength<T> keySuffixSerializer,
|
SerializerFixedBinaryLength<T> keySuffixSerializer,
|
||||||
Serializer<U> valueSerializer,
|
Serializer<U> valueSerializer,
|
||||||
Drop<DatabaseMapDictionaryDeep<T, U, DatabaseStageEntry<U>>> drop) {
|
Runnable onClose) {
|
||||||
// Do not retain or release or use the prefixKey here
|
// Do not retain or release or use the prefixKey here
|
||||||
super(dictionary, prefixKey, keySuffixSerializer, new SubStageGetterSingle<>(valueSerializer), 0, drop);
|
super(dictionary, prefixKey, keySuffixSerializer, new SubStageGetterSingle<>(valueSerializer), 0, onClose);
|
||||||
this.valueSerializer = valueSerializer;
|
this.valueSerializer = valueSerializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, U> DatabaseMapDictionary<T, U> simple(LLDictionary dictionary,
|
public static <T, U> DatabaseMapDictionary<T, U> simple(LLDictionary dictionary,
|
||||||
SerializerFixedBinaryLength<T> keySerializer,
|
SerializerFixedBinaryLength<T> keySerializer,
|
||||||
Serializer<U> valueSerializer,
|
Serializer<U> valueSerializer,
|
||||||
Drop<DatabaseMapDictionaryDeep<T, U, DatabaseStageEntry<U>>> drop) {
|
Runnable onClose) {
|
||||||
return new DatabaseMapDictionary<>(dictionary, LLUtils.empty(dictionary.getAllocator()), keySerializer,
|
return new DatabaseMapDictionary<>(dictionary, LLUtils.empty(dictionary.getAllocator()), keySerializer,
|
||||||
valueSerializer, drop);
|
valueSerializer, onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, U> DatabaseMapDictionary<T, U> tail(LLDictionary dictionary,
|
public static <T, U> DatabaseMapDictionary<T, U> tail(LLDictionary dictionary,
|
||||||
Send<Buffer> prefixKey,
|
Send<Buffer> prefixKey,
|
||||||
SerializerFixedBinaryLength<T> keySuffixSerializer,
|
SerializerFixedBinaryLength<T> keySuffixSerializer,
|
||||||
Serializer<U> valueSerializer,
|
Serializer<U> valueSerializer,
|
||||||
Drop<DatabaseMapDictionaryDeep<T, U, DatabaseStageEntry<U>>> drop) {
|
Runnable onClose) {
|
||||||
return new DatabaseMapDictionary<>(dictionary, prefixKey, keySuffixSerializer, valueSerializer, drop);
|
return new DatabaseMapDictionary<>(dictionary, prefixKey, keySuffixSerializer, valueSerializer, onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Send<Buffer> toKey(Send<Buffer> suffixKeyToSend) {
|
private Send<Buffer> toKey(Send<Buffer> suffixKeyToSend) {
|
||||||
@ -152,7 +152,7 @@ public class DatabaseMapDictionary<T, U> extends DatabaseMapDictionaryDeep<T, U,
|
|||||||
@Override
|
@Override
|
||||||
public Mono<DatabaseStageEntry<U>> at(@Nullable CompositeSnapshot snapshot, T keySuffix) {
|
public Mono<DatabaseStageEntry<U>> at(@Nullable CompositeSnapshot snapshot, T keySuffix) {
|
||||||
return Mono.fromCallable(() ->
|
return Mono.fromCallable(() ->
|
||||||
new DatabaseSingle<>(dictionary, toKey(serializeSuffix(keySuffix)), valueSerializer, d -> {}));
|
new DatabaseSingle<>(dictionary, toKey(serializeSuffix(keySuffix)), valueSerializer, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -401,7 +401,7 @@ public class DatabaseMapDictionary<T, U> extends DatabaseMapDictionaryDeep<T, U,
|
|||||||
removePrefix(keyBuf);
|
removePrefix(keyBuf);
|
||||||
suffixKeyConsistency(keyBuf.readableBytes());
|
suffixKeyConsistency(keyBuf.readableBytes());
|
||||||
sink.next(Map.entry(deserializeSuffix(keyBuf.copy().send()),
|
sink.next(Map.entry(deserializeSuffix(keyBuf.copy().send()),
|
||||||
new DatabaseSingle<>(dictionary, toKey(keyBuf.send()), valueSerializer, d -> {})
|
new DatabaseSingle<>(dictionary, toKey(keyBuf.send()), valueSerializer, null)
|
||||||
));
|
));
|
||||||
} catch (SerializationException ex) {
|
} catch (SerializationException ex) {
|
||||||
sink.error(ex);
|
sink.error(ex);
|
||||||
|
@ -25,6 +25,8 @@ import java.util.Map.Entry;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
@ -33,6 +35,45 @@ public class DatabaseMapDictionaryDeep<T, U, US extends DatabaseStage<U>> extend
|
|||||||
LiveResourceSupport<DatabaseStage<Map<T, U>>, DatabaseMapDictionaryDeep<T, U, US>>
|
LiveResourceSupport<DatabaseStage<Map<T, U>>, DatabaseMapDictionaryDeep<T, U, US>>
|
||||||
implements DatabaseStageMap<T, U, US> {
|
implements DatabaseStageMap<T, U, US> {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DatabaseMapDictionaryDeep.class);
|
||||||
|
|
||||||
|
private static final Drop<DatabaseMapDictionaryDeep<?, ?, ?>> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(DatabaseMapDictionaryDeep<?, ?, ?> obj) {
|
||||||
|
try {
|
||||||
|
if (obj.range != null) {
|
||||||
|
obj.range.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close range", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.keyPrefix != null) {
|
||||||
|
obj.keyPrefix.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close keyPrefix", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close onClose", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<DatabaseMapDictionaryDeep<?, ?, ?>> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(DatabaseMapDictionaryDeep<?, ?, ?> obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
protected final LLDictionary dictionary;
|
protected final LLDictionary dictionary;
|
||||||
private final BufferAllocator alloc;
|
private final BufferAllocator alloc;
|
||||||
protected final SubStageGetter<U, US> subStageGetter;
|
protected final SubStageGetter<U, US> subStageGetter;
|
||||||
@ -44,6 +85,7 @@ public class DatabaseMapDictionaryDeep<T, U, US extends DatabaseStage<U>> extend
|
|||||||
|
|
||||||
protected LLRange range;
|
protected LLRange range;
|
||||||
protected Buffer keyPrefix;
|
protected Buffer keyPrefix;
|
||||||
|
protected Runnable onClose;
|
||||||
|
|
||||||
private static void incrementPrefix(Buffer prefix, int prefixLength) {
|
private static void incrementPrefix(Buffer prefix, int prefixLength) {
|
||||||
assert prefix.readableBytes() >= prefixLength;
|
assert prefix.readableBytes() >= prefixLength;
|
||||||
@ -151,29 +193,30 @@ public class DatabaseMapDictionaryDeep<T, U, US extends DatabaseStage<U>> extend
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static <T, U> DatabaseMapDictionaryDeep<T, U, DatabaseStageEntry<U>> simple(LLDictionary dictionary,
|
public static <T, U> DatabaseMapDictionaryDeep<T, U, DatabaseStageEntry<U>> simple(LLDictionary dictionary,
|
||||||
SerializerFixedBinaryLength<T> keySerializer, SubStageGetterSingle<U> subStageGetter,
|
SerializerFixedBinaryLength<T> keySerializer, SubStageGetterSingle<U> subStageGetter,
|
||||||
Drop<DatabaseMapDictionaryDeep<T, U, DatabaseStageEntry<U>>> drop) {
|
Runnable onClose) {
|
||||||
return new DatabaseMapDictionaryDeep<>(dictionary, LLUtils.empty(dictionary.getAllocator()), keySerializer,
|
return new DatabaseMapDictionaryDeep<>(dictionary, LLUtils.empty(dictionary.getAllocator()), keySerializer,
|
||||||
subStageGetter, 0, drop);
|
subStageGetter, 0, onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, U, US extends DatabaseStage<U>> DatabaseMapDictionaryDeep<T, U, US> deepTail(
|
public static <T, U, US extends DatabaseStage<U>> DatabaseMapDictionaryDeep<T, U, US> deepTail(
|
||||||
LLDictionary dictionary, SerializerFixedBinaryLength<T> keySerializer, int keyExtLength,
|
LLDictionary dictionary, SerializerFixedBinaryLength<T> keySerializer, int keyExtLength,
|
||||||
SubStageGetter<U, US> subStageGetter, Drop<DatabaseMapDictionaryDeep<T, U, US>> drop) {
|
SubStageGetter<U, US> subStageGetter, Runnable onClose) {
|
||||||
return new DatabaseMapDictionaryDeep<>(dictionary, LLUtils.empty(dictionary.getAllocator()), keySerializer,
|
return new DatabaseMapDictionaryDeep<>(dictionary, LLUtils.empty(dictionary.getAllocator()), keySerializer,
|
||||||
subStageGetter, keyExtLength, drop);
|
subStageGetter, keyExtLength, onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, U, US extends DatabaseStage<U>> DatabaseMapDictionaryDeep<T, U, US> deepIntermediate(
|
public static <T, U, US extends DatabaseStage<U>> DatabaseMapDictionaryDeep<T, U, US> deepIntermediate(
|
||||||
LLDictionary dictionary, Send<Buffer> prefixKey, SerializerFixedBinaryLength<T> keySuffixSerializer,
|
LLDictionary dictionary, Send<Buffer> prefixKey, SerializerFixedBinaryLength<T> keySuffixSerializer,
|
||||||
SubStageGetter<U, US> subStageGetter, int keyExtLength, Drop<DatabaseMapDictionaryDeep<T, U, US>> drop) {
|
SubStageGetter<U, US> subStageGetter, int keyExtLength, Runnable onClose) {
|
||||||
return new DatabaseMapDictionaryDeep<>(dictionary, prefixKey, keySuffixSerializer, subStageGetter,
|
return new DatabaseMapDictionaryDeep<>(dictionary, prefixKey, keySuffixSerializer, subStageGetter,
|
||||||
keyExtLength, drop);
|
keyExtLength, onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
protected DatabaseMapDictionaryDeep(LLDictionary dictionary, @NotNull Send<Buffer> prefixKeyToReceive,
|
protected DatabaseMapDictionaryDeep(LLDictionary dictionary, @NotNull Send<Buffer> prefixKeyToReceive,
|
||||||
SerializerFixedBinaryLength<T> keySuffixSerializer, SubStageGetter<U, US> subStageGetter, int keyExtLength,
|
SerializerFixedBinaryLength<T> keySuffixSerializer, SubStageGetter<U, US> subStageGetter, int keyExtLength,
|
||||||
Drop<DatabaseMapDictionaryDeep<T, U, US>> drop) {
|
Runnable onClose) {
|
||||||
super(new CloseOnDrop<>(drop));
|
super((Drop<DatabaseMapDictionaryDeep<T, U, US>>) (Drop) DROP);
|
||||||
try (var prefixKey = prefixKeyToReceive.receive()) {
|
try (var prefixKey = prefixKeyToReceive.receive()) {
|
||||||
this.dictionary = dictionary;
|
this.dictionary = dictionary;
|
||||||
this.alloc = dictionary.getAllocator();
|
this.alloc = dictionary.getAllocator();
|
||||||
@ -198,9 +241,11 @@ public class DatabaseMapDictionaryDeep<T, U, US extends DatabaseStage<U>> extend
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.keyPrefix = prefixKey.send().receive();
|
this.keyPrefix = prefixKey.send().receive();
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
private DatabaseMapDictionaryDeep(LLDictionary dictionary,
|
private DatabaseMapDictionaryDeep(LLDictionary dictionary,
|
||||||
BufferAllocator alloc,
|
BufferAllocator alloc,
|
||||||
SubStageGetter<U, US> subStageGetter,
|
SubStageGetter<U, US> subStageGetter,
|
||||||
@ -211,8 +256,8 @@ public class DatabaseMapDictionaryDeep<T, U, US extends DatabaseStage<U>> extend
|
|||||||
Mono<Send<LLRange>> rangeMono,
|
Mono<Send<LLRange>> rangeMono,
|
||||||
Send<LLRange> range,
|
Send<LLRange> range,
|
||||||
Send<Buffer> keyPrefix,
|
Send<Buffer> keyPrefix,
|
||||||
Drop<DatabaseMapDictionaryDeep<T, U, US>> drop) {
|
Runnable onClose) {
|
||||||
super(new CloseOnDrop<>(drop));
|
super((Drop<DatabaseMapDictionaryDeep<T,U,US>>) (Drop) DROP);
|
||||||
this.dictionary = dictionary;
|
this.dictionary = dictionary;
|
||||||
this.alloc = alloc;
|
this.alloc = alloc;
|
||||||
this.subStageGetter = subStageGetter;
|
this.subStageGetter = subStageGetter;
|
||||||
@ -224,6 +269,7 @@ public class DatabaseMapDictionaryDeep<T, U, US extends DatabaseStage<U>> extend
|
|||||||
|
|
||||||
this.range = range.receive();
|
this.range = range.receive();
|
||||||
this.keyPrefix = keyPrefix.receive();
|
this.keyPrefix = keyPrefix.receive();
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -418,34 +464,29 @@ public class DatabaseMapDictionaryDeep<T, U, US extends DatabaseStage<U>> extend
|
|||||||
protected Owned<DatabaseMapDictionaryDeep<T, U, US>> prepareSend() {
|
protected Owned<DatabaseMapDictionaryDeep<T, U, US>> prepareSend() {
|
||||||
var keyPrefix = this.keyPrefix.send();
|
var keyPrefix = this.keyPrefix.send();
|
||||||
var range = this.range.send();
|
var range = this.range.send();
|
||||||
return drop -> new DatabaseMapDictionaryDeep<>(dictionary, alloc, subStageGetter, keySuffixSerializer,
|
var onClose = this.onClose;
|
||||||
keyPrefixLength, keySuffixLength, keyExtLength, rangeMono, range, keyPrefix, drop);
|
return drop -> {
|
||||||
|
var instance = new DatabaseMapDictionaryDeep<>(dictionary,
|
||||||
|
alloc,
|
||||||
|
subStageGetter,
|
||||||
|
keySuffixSerializer,
|
||||||
|
keyPrefixLength,
|
||||||
|
keySuffixLength,
|
||||||
|
keyExtLength,
|
||||||
|
rangeMono,
|
||||||
|
range,
|
||||||
|
keyPrefix,
|
||||||
|
onClose
|
||||||
|
);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.keyPrefix = null;
|
this.keyPrefix = null;
|
||||||
this.range = null;
|
this.range = null;
|
||||||
}
|
this.onClose = null;
|
||||||
|
|
||||||
private static class CloseOnDrop<T, U, US extends DatabaseStage<U>>
|
|
||||||
implements Drop<DatabaseMapDictionaryDeep<T, U, US>> {
|
|
||||||
|
|
||||||
private final Drop<DatabaseMapDictionaryDeep<T,U,US>> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<DatabaseMapDictionaryDeep<T, U, US>> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop<T, U, US> closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(DatabaseMapDictionaryDeep<T, U, US> obj) {
|
|
||||||
obj.range.close();
|
|
||||||
obj.keyPrefix.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ import java.util.Set;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
@ -33,19 +35,45 @@ public class DatabaseMapDictionaryHashed<T, U, TH> extends
|
|||||||
LiveResourceSupport<DatabaseStage<Map<T, U>>, DatabaseMapDictionaryHashed<T, U, TH>>
|
LiveResourceSupport<DatabaseStage<Map<T, U>>, DatabaseMapDictionaryHashed<T, U, TH>>
|
||||||
implements DatabaseStageMap<T, U, DatabaseStageEntry<U>> {
|
implements DatabaseStageMap<T, U, DatabaseStageEntry<U>> {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DatabaseMapDictionaryHashed.class);
|
||||||
|
|
||||||
|
private static final Drop<DatabaseMapDictionaryHashed<?, ?, ?>> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(DatabaseMapDictionaryHashed<?, ?, ?> obj) {
|
||||||
|
try {
|
||||||
|
if (obj.subDictionary != null) {
|
||||||
|
obj.subDictionary.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close subDictionary", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<DatabaseMapDictionaryHashed<?, ?, ?>> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(DatabaseMapDictionaryHashed<?, ?, ?> obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final BufferAllocator alloc;
|
private final BufferAllocator alloc;
|
||||||
private final Function<T, TH> keySuffixHashFunction;
|
private final Function<T, TH> keySuffixHashFunction;
|
||||||
|
|
||||||
private DatabaseMapDictionary<TH, ObjectArraySet<Entry<T, U>>> subDictionary;
|
private DatabaseMapDictionary<TH, ObjectArraySet<Entry<T, U>>> subDictionary;
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
protected DatabaseMapDictionaryHashed(LLDictionary dictionary,
|
protected DatabaseMapDictionaryHashed(LLDictionary dictionary,
|
||||||
@NotNull Send<Buffer> prefixKey,
|
@NotNull Send<Buffer> prefixKey,
|
||||||
Serializer<T> keySuffixSerializer,
|
Serializer<T> keySuffixSerializer,
|
||||||
Serializer<U> valueSerializer,
|
Serializer<U> valueSerializer,
|
||||||
Function<T, TH> keySuffixHashFunction,
|
Function<T, TH> keySuffixHashFunction,
|
||||||
SerializerFixedBinaryLength<TH> keySuffixHashSerializer,
|
SerializerFixedBinaryLength<TH> keySuffixHashSerializer,
|
||||||
Drop<DatabaseMapDictionaryHashed<T, U, TH>> drop) {
|
Runnable onClose) {
|
||||||
super(new DatabaseMapDictionaryHashed.CloseOnDrop<>(drop));
|
super((Drop<DatabaseMapDictionaryHashed<T, U, TH>>) (Drop) DROP);
|
||||||
if (dictionary.getUpdateMode().block() != UpdateMode.ALLOW) {
|
if (dictionary.getUpdateMode().block() != UpdateMode.ALLOW) {
|
||||||
throw new IllegalArgumentException("Hashed maps only works when UpdateMode is ALLOW");
|
throw new IllegalArgumentException("Hashed maps only works when UpdateMode is ALLOW");
|
||||||
}
|
}
|
||||||
@ -55,15 +83,16 @@ public class DatabaseMapDictionaryHashed<T, U, TH> extends
|
|||||||
ValuesSetSerializer<Entry<T, U>> valuesSetSerializer
|
ValuesSetSerializer<Entry<T, U>> valuesSetSerializer
|
||||||
= new ValuesSetSerializer<>(alloc, valueWithHashSerializer);
|
= new ValuesSetSerializer<>(alloc, valueWithHashSerializer);
|
||||||
this.subDictionary = DatabaseMapDictionary.tail(dictionary, prefixKey, keySuffixHashSerializer,
|
this.subDictionary = DatabaseMapDictionary.tail(dictionary, prefixKey, keySuffixHashSerializer,
|
||||||
valuesSetSerializer, d -> {});
|
valuesSetSerializer, onClose);
|
||||||
this.keySuffixHashFunction = keySuffixHashFunction;
|
this.keySuffixHashFunction = keySuffixHashFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
private DatabaseMapDictionaryHashed(BufferAllocator alloc,
|
private DatabaseMapDictionaryHashed(BufferAllocator alloc,
|
||||||
Function<T, TH> keySuffixHashFunction,
|
Function<T, TH> keySuffixHashFunction,
|
||||||
Send<DatabaseStage<Map<TH, ObjectArraySet<Entry<T, U>>>>> subDictionary,
|
Send<DatabaseStage<Map<TH, ObjectArraySet<Entry<T, U>>>>> subDictionary,
|
||||||
Drop<DatabaseMapDictionaryHashed<T, U, TH>> drop) {
|
Drop<DatabaseMapDictionaryHashed<T, U, TH>> drop) {
|
||||||
super(new CloseOnDrop<>(drop));
|
super((Drop<DatabaseMapDictionaryHashed<T, U, TH>>) (Drop) DROP);
|
||||||
this.alloc = alloc;
|
this.alloc = alloc;
|
||||||
this.keySuffixHashFunction = keySuffixHashFunction;
|
this.keySuffixHashFunction = keySuffixHashFunction;
|
||||||
|
|
||||||
@ -75,7 +104,7 @@ public class DatabaseMapDictionaryHashed<T, U, TH> extends
|
|||||||
Serializer<U> valueSerializer,
|
Serializer<U> valueSerializer,
|
||||||
Function<T, UH> keyHashFunction,
|
Function<T, UH> keyHashFunction,
|
||||||
SerializerFixedBinaryLength<UH> keyHashSerializer,
|
SerializerFixedBinaryLength<UH> keyHashSerializer,
|
||||||
Drop<DatabaseMapDictionaryHashed<T, U, UH>> drop) {
|
Runnable onClose) {
|
||||||
return new DatabaseMapDictionaryHashed<>(
|
return new DatabaseMapDictionaryHashed<>(
|
||||||
dictionary,
|
dictionary,
|
||||||
LLUtils.empty(dictionary.getAllocator()),
|
LLUtils.empty(dictionary.getAllocator()),
|
||||||
@ -83,7 +112,7 @@ public class DatabaseMapDictionaryHashed<T, U, TH> extends
|
|||||||
valueSerializer,
|
valueSerializer,
|
||||||
keyHashFunction,
|
keyHashFunction,
|
||||||
keyHashSerializer,
|
keyHashSerializer,
|
||||||
drop
|
onClose
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,14 +122,14 @@ public class DatabaseMapDictionaryHashed<T, U, TH> extends
|
|||||||
Serializer<U> valueSerializer,
|
Serializer<U> valueSerializer,
|
||||||
Function<T, UH> keySuffixHashFunction,
|
Function<T, UH> keySuffixHashFunction,
|
||||||
SerializerFixedBinaryLength<UH> keySuffixHashSerializer,
|
SerializerFixedBinaryLength<UH> keySuffixHashSerializer,
|
||||||
Drop<DatabaseMapDictionaryHashed<T, U, UH>> drop) {
|
Runnable onClose) {
|
||||||
return new DatabaseMapDictionaryHashed<>(dictionary,
|
return new DatabaseMapDictionaryHashed<>(dictionary,
|
||||||
prefixKey,
|
prefixKey,
|
||||||
keySuffixSerializer,
|
keySuffixSerializer,
|
||||||
valueSerializer,
|
valueSerializer,
|
||||||
keySuffixHashFunction,
|
keySuffixHashFunction,
|
||||||
keySuffixHashSerializer,
|
keySuffixHashSerializer,
|
||||||
drop
|
onClose
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +202,7 @@ public class DatabaseMapDictionaryHashed<T, U, TH> extends
|
|||||||
private Mono<DatabaseSingleBucket<T, U, TH>> atPrivate(@Nullable CompositeSnapshot snapshot, T key, TH hash) {
|
private Mono<DatabaseSingleBucket<T, U, TH>> atPrivate(@Nullable CompositeSnapshot snapshot, T key, TH hash) {
|
||||||
return subDictionary
|
return subDictionary
|
||||||
.at(snapshot, hash)
|
.at(snapshot, hash)
|
||||||
.map(entry -> new DatabaseSingleBucket<T, U, TH>(entry, key, d -> {}))
|
.map(entry -> new DatabaseSingleBucket<T, U, TH>(entry, key, null))
|
||||||
.doOnDiscard(Resource.class, Resource::close);
|
.doOnDiscard(Resource.class, Resource::close);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,23 +354,4 @@ public class DatabaseMapDictionaryHashed<T, U, TH> extends
|
|||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.subDictionary = null;
|
this.subDictionary = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CloseOnDrop<T, U, TH> implements Drop<DatabaseMapDictionaryHashed<T,U,TH>> {
|
|
||||||
|
|
||||||
private final Drop<DatabaseMapDictionaryHashed<T,U,TH>> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<DatabaseMapDictionaryHashed<T,U,TH>> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop<T, U, TH> closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(DatabaseMapDictionaryHashed<T, U, TH> obj) {
|
|
||||||
obj.subDictionary.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,21 +20,21 @@ public class DatabaseSetDictionary<T> extends DatabaseMapDictionary<T, Nothing>
|
|||||||
protected DatabaseSetDictionary(LLDictionary dictionary,
|
protected DatabaseSetDictionary(LLDictionary dictionary,
|
||||||
Send<Buffer> prefixKey,
|
Send<Buffer> prefixKey,
|
||||||
SerializerFixedBinaryLength<T> keySuffixSerializer,
|
SerializerFixedBinaryLength<T> keySuffixSerializer,
|
||||||
Drop<DatabaseMapDictionaryDeep<T, Nothing, DatabaseStageEntry<Nothing>>> drop) {
|
Runnable onClose) {
|
||||||
super(dictionary, prefixKey, keySuffixSerializer, DatabaseEmpty.nothingSerializer(dictionary.getAllocator()), drop);
|
super(dictionary, prefixKey, keySuffixSerializer, DatabaseEmpty.nothingSerializer(dictionary.getAllocator()), onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> DatabaseSetDictionary<T> simple(LLDictionary dictionary,
|
public static <T> DatabaseSetDictionary<T> simple(LLDictionary dictionary,
|
||||||
SerializerFixedBinaryLength<T> keySerializer,
|
SerializerFixedBinaryLength<T> keySerializer,
|
||||||
Drop<DatabaseMapDictionaryDeep<T, Nothing, DatabaseStageEntry<Nothing>>> drop) {
|
Runnable onClose) {
|
||||||
return new DatabaseSetDictionary<>(dictionary, LLUtils.empty(dictionary.getAllocator()), keySerializer, drop);
|
return new DatabaseSetDictionary<>(dictionary, LLUtils.empty(dictionary.getAllocator()), keySerializer, onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> DatabaseSetDictionary<T> tail(LLDictionary dictionary,
|
public static <T> DatabaseSetDictionary<T> tail(LLDictionary dictionary,
|
||||||
Send<Buffer> prefixKey,
|
Send<Buffer> prefixKey,
|
||||||
SerializerFixedBinaryLength<T> keySuffixSerializer,
|
SerializerFixedBinaryLength<T> keySuffixSerializer,
|
||||||
Drop<DatabaseMapDictionaryDeep<T, Nothing, DatabaseStageEntry<Nothing>>> drop) {
|
Runnable onClose) {
|
||||||
return new DatabaseSetDictionary<>(dictionary, prefixKey, keySuffixSerializer, drop);
|
return new DatabaseSetDictionary<>(dictionary, prefixKey, keySuffixSerializer, onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mono<Set<T>> getKeySet(@Nullable CompositeSnapshot snapshot) {
|
public Mono<Set<T>> getKeySet(@Nullable CompositeSnapshot snapshot) {
|
||||||
|
@ -25,14 +25,14 @@ public class DatabaseSetDictionaryHashed<T, TH> extends DatabaseMapDictionaryHas
|
|||||||
Serializer<T> keySuffixSerializer,
|
Serializer<T> keySuffixSerializer,
|
||||||
Function<T, TH> keySuffixHashFunction,
|
Function<T, TH> keySuffixHashFunction,
|
||||||
SerializerFixedBinaryLength<TH> keySuffixHashSerializer,
|
SerializerFixedBinaryLength<TH> keySuffixHashSerializer,
|
||||||
Drop<DatabaseMapDictionaryHashed<T, Nothing, TH>> drop) {
|
Runnable onClose) {
|
||||||
super(dictionary,
|
super(dictionary,
|
||||||
prefixKey,
|
prefixKey,
|
||||||
keySuffixSerializer,
|
keySuffixSerializer,
|
||||||
DatabaseEmpty.nothingSerializer(dictionary.getAllocator()),
|
DatabaseEmpty.nothingSerializer(dictionary.getAllocator()),
|
||||||
keySuffixHashFunction,
|
keySuffixHashFunction,
|
||||||
keySuffixHashSerializer,
|
keySuffixHashSerializer,
|
||||||
drop
|
onClose
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,13 +40,13 @@ public class DatabaseSetDictionaryHashed<T, TH> extends DatabaseMapDictionaryHas
|
|||||||
Serializer<T> keySerializer,
|
Serializer<T> keySerializer,
|
||||||
Function<T, TH> keyHashFunction,
|
Function<T, TH> keyHashFunction,
|
||||||
SerializerFixedBinaryLength<TH> keyHashSerializer,
|
SerializerFixedBinaryLength<TH> keyHashSerializer,
|
||||||
Drop<DatabaseMapDictionaryHashed<T, Nothing, TH>> drop) {
|
Runnable onClose) {
|
||||||
return new DatabaseSetDictionaryHashed<>(dictionary,
|
return new DatabaseSetDictionaryHashed<>(dictionary,
|
||||||
LLUtils.empty(dictionary.getAllocator()),
|
LLUtils.empty(dictionary.getAllocator()),
|
||||||
keySerializer,
|
keySerializer,
|
||||||
keyHashFunction,
|
keyHashFunction,
|
||||||
keyHashSerializer,
|
keyHashSerializer,
|
||||||
drop
|
onClose
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,13 +54,14 @@ public class DatabaseSetDictionaryHashed<T, TH> extends DatabaseMapDictionaryHas
|
|||||||
Send<Buffer> prefixKey,
|
Send<Buffer> prefixKey,
|
||||||
Serializer<T> keySuffixSerializer,
|
Serializer<T> keySuffixSerializer,
|
||||||
Function<T, TH> keyHashFunction,
|
Function<T, TH> keyHashFunction,
|
||||||
SerializerFixedBinaryLength<TH> keyHashSerializer, Drop<DatabaseMapDictionaryHashed<T, Nothing, TH>> drop) {
|
SerializerFixedBinaryLength<TH> keyHashSerializer,
|
||||||
|
Runnable onClose) {
|
||||||
return new DatabaseSetDictionaryHashed<>(dictionary,
|
return new DatabaseSetDictionaryHashed<>(dictionary,
|
||||||
prefixKey,
|
prefixKey,
|
||||||
keySuffixSerializer,
|
keySuffixSerializer,
|
||||||
keyHashFunction,
|
keyHashFunction,
|
||||||
keyHashSerializer,
|
keyHashSerializer,
|
||||||
drop
|
onClose
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import io.net5.buffer.api.Send;
|
|||||||
import io.net5.buffer.api.internal.ResourceSupport;
|
import io.net5.buffer.api.internal.ResourceSupport;
|
||||||
import it.cavallium.dbengine.client.BadBlock;
|
import it.cavallium.dbengine.client.BadBlock;
|
||||||
import it.cavallium.dbengine.client.CompositeSnapshot;
|
import it.cavallium.dbengine.client.CompositeSnapshot;
|
||||||
|
import it.cavallium.dbengine.client.SearchResultKeys;
|
||||||
import it.cavallium.dbengine.database.Delta;
|
import it.cavallium.dbengine.database.Delta;
|
||||||
import it.cavallium.dbengine.database.LLDictionary;
|
import it.cavallium.dbengine.database.LLDictionary;
|
||||||
import it.cavallium.dbengine.database.LLDictionaryResultType;
|
import it.cavallium.dbengine.database.LLDictionaryResultType;
|
||||||
@ -19,6 +20,8 @@ import it.cavallium.dbengine.database.serialization.SerializationException;
|
|||||||
import it.cavallium.dbengine.database.serialization.SerializationFunction;
|
import it.cavallium.dbengine.database.serialization.SerializationFunction;
|
||||||
import it.cavallium.dbengine.database.serialization.Serializer;
|
import it.cavallium.dbengine.database.serialization.Serializer;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.core.publisher.SynchronousSink;
|
import reactor.core.publisher.SynchronousSink;
|
||||||
@ -26,20 +29,49 @@ import reactor.core.publisher.SynchronousSink;
|
|||||||
public class DatabaseSingle<U> extends ResourceSupport<DatabaseStage<U>, DatabaseSingle<U>> implements
|
public class DatabaseSingle<U> extends ResourceSupport<DatabaseStage<U>, DatabaseSingle<U>> implements
|
||||||
DatabaseStageEntry<U> {
|
DatabaseStageEntry<U> {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DatabaseSingle.class);
|
||||||
|
|
||||||
|
private static final Drop<DatabaseSingle<?>> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(DatabaseSingle<?> obj) {
|
||||||
|
try {
|
||||||
|
obj.key.close();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close key", ex);
|
||||||
|
}
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<DatabaseSingle<?>> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(DatabaseSingle<?> obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final LLDictionary dictionary;
|
private final LLDictionary dictionary;
|
||||||
private final Mono<Send<Buffer>> keyMono;
|
private final Mono<Send<Buffer>> keyMono;
|
||||||
private final Serializer<U> serializer;
|
private final Serializer<U> serializer;
|
||||||
|
|
||||||
private Buffer key;
|
private Buffer key;
|
||||||
|
private Runnable onClose;
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public DatabaseSingle(LLDictionary dictionary, Send<Buffer> key, Serializer<U> serializer,
|
public DatabaseSingle(LLDictionary dictionary, Send<Buffer> key, Serializer<U> serializer,
|
||||||
Drop<DatabaseSingle<U>> drop) {
|
Runnable onClose) {
|
||||||
super(new CloseOnDrop<>(drop));
|
super((Drop<DatabaseSingle<U>>) (Drop) DROP);
|
||||||
try (key) {
|
try (key) {
|
||||||
this.dictionary = dictionary;
|
this.dictionary = dictionary;
|
||||||
this.key = key.receive();
|
this.key = key.receive();
|
||||||
this.keyMono = LLUtils.lazyRetain(this.key);
|
this.keyMono = LLUtils.lazyRetain(this.key);
|
||||||
this.serializer = serializer;
|
this.serializer = serializer;
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,30 +176,17 @@ public class DatabaseSingle<U> extends ResourceSupport<DatabaseStage<U>, Databas
|
|||||||
@Override
|
@Override
|
||||||
protected Owned<DatabaseSingle<U>> prepareSend() {
|
protected Owned<DatabaseSingle<U>> prepareSend() {
|
||||||
var key = this.key.send();
|
var key = this.key.send();
|
||||||
return drop -> new DatabaseSingle<>(dictionary, key, serializer, drop);
|
var onClose = this.onClose;
|
||||||
|
return drop -> {
|
||||||
|
var instance = new DatabaseSingle<>(dictionary, key, serializer, onClose);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.key = null;
|
this.key = null;
|
||||||
}
|
this.onClose = null;
|
||||||
|
|
||||||
private static class CloseOnDrop<U> implements Drop<DatabaseSingle<U>> {
|
|
||||||
|
|
||||||
private final Drop<DatabaseSingle<U>> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<DatabaseSingle<U>> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop<U> closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(DatabaseSingle<U> obj) {
|
|
||||||
obj.key.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,6 +24,8 @@ import java.util.function.Function;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.warp.commonutils.functional.TriFunction;
|
import org.warp.commonutils.functional.TriFunction;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
@ -32,22 +34,58 @@ public class DatabaseSingleBucket<K, V, TH>
|
|||||||
extends LiveResourceSupport<DatabaseStage<V>, DatabaseSingleBucket<K, V, TH>>
|
extends LiveResourceSupport<DatabaseStage<V>, DatabaseSingleBucket<K, V, TH>>
|
||||||
implements DatabaseStageEntry<V> {
|
implements DatabaseStageEntry<V> {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DatabaseSingleBucket.class);
|
||||||
|
|
||||||
|
private static final Drop<DatabaseSingleBucket<?, ?, ?>> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(DatabaseSingleBucket<?, ?, ?> obj) {
|
||||||
|
try {
|
||||||
|
if (obj.bucketStage != null) {
|
||||||
|
obj.bucketStage.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close bucketStage", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close onClose", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<DatabaseSingleBucket<?, ?, ?>> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(DatabaseSingleBucket<?, ?, ?> obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final K key;
|
private final K key;
|
||||||
|
|
||||||
private DatabaseStageEntry<ObjectArraySet<Entry<K, V>>> bucketStage;
|
private DatabaseStageEntry<ObjectArraySet<Entry<K, V>>> bucketStage;
|
||||||
|
|
||||||
public DatabaseSingleBucket(DatabaseStageEntry<ObjectArraySet<Entry<K, V>>> bucketStage, K key,
|
private Runnable onClose;
|
||||||
Drop<DatabaseSingleBucket<K, V, TH>> drop) {
|
|
||||||
super(new CloseOnDrop<>(drop));
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
public DatabaseSingleBucket(DatabaseStageEntry<ObjectArraySet<Entry<K, V>>> bucketStage, K key, Runnable onClose) {
|
||||||
|
super((Drop<DatabaseSingleBucket<K,V,TH>>) (Drop) DROP);
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.bucketStage = bucketStage;
|
this.bucketStage = bucketStage;
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DatabaseSingleBucket(Send<DatabaseStage<ObjectArraySet<Entry<K, V>>>> bucketStage, K key,
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
Drop<DatabaseSingleBucket<K, V, TH>> drop) {
|
private DatabaseSingleBucket(Send<DatabaseStage<ObjectArraySet<Entry<K, V>>>> bucketStage, K key, Runnable onClose) {
|
||||||
super(new CloseOnDrop<>(drop));
|
super((Drop<DatabaseSingleBucket<K,V,TH>>) (Drop) DROP);
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.bucketStage = (DatabaseStageEntry<ObjectArraySet<Entry<K, V>>>) bucketStage.receive();
|
this.bucketStage = (DatabaseStageEntry<ObjectArraySet<Entry<K, V>>>) bucketStage.receive();
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -210,31 +248,17 @@ public class DatabaseSingleBucket<K, V, TH>
|
|||||||
@Override
|
@Override
|
||||||
protected Owned<DatabaseSingleBucket<K, V, TH>> prepareSend() {
|
protected Owned<DatabaseSingleBucket<K, V, TH>> prepareSend() {
|
||||||
var bucketStage = this.bucketStage.send();
|
var bucketStage = this.bucketStage.send();
|
||||||
return drop -> new DatabaseSingleBucket<>(bucketStage, key, drop);
|
var onClose = this.onClose;
|
||||||
|
return drop -> {
|
||||||
|
var instance = new DatabaseSingleBucket<K, V, TH>(bucketStage, key, onClose);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.bucketStage = null;
|
this.bucketStage = null;
|
||||||
}
|
this.onClose = null;
|
||||||
|
|
||||||
private static class CloseOnDrop<K, V, TH> implements
|
|
||||||
Drop<DatabaseSingleBucket<K, V, TH>> {
|
|
||||||
|
|
||||||
private final Drop<DatabaseSingleBucket<K, V, TH>> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<DatabaseSingleBucket<K, V, TH>> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop<K, V, TH> closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(DatabaseSingleBucket<K, V, TH> obj) {
|
|
||||||
obj.bucketStage.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ import it.cavallium.dbengine.database.UpdateReturnMode;
|
|||||||
import it.cavallium.dbengine.database.serialization.SerializationException;
|
import it.cavallium.dbengine.database.serialization.SerializationException;
|
||||||
import it.cavallium.dbengine.database.serialization.SerializationFunction;
|
import it.cavallium.dbengine.database.serialization.SerializationFunction;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.core.publisher.SynchronousSink;
|
import reactor.core.publisher.SynchronousSink;
|
||||||
@ -22,20 +24,47 @@ import reactor.core.publisher.SynchronousSink;
|
|||||||
public class DatabaseSingleMapped<A, B> extends ResourceSupport<DatabaseStage<A>, DatabaseSingleMapped<A, B>>
|
public class DatabaseSingleMapped<A, B> extends ResourceSupport<DatabaseStage<A>, DatabaseSingleMapped<A, B>>
|
||||||
implements DatabaseStageEntry<A> {
|
implements DatabaseStageEntry<A> {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DatabaseSingleMapped.class);
|
||||||
|
|
||||||
|
private static final Drop<DatabaseSingleMapped<?, ?>> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(DatabaseSingleMapped<?, ?> obj) {
|
||||||
|
try {
|
||||||
|
if (obj.serializedSingle != null) {
|
||||||
|
obj.serializedSingle.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close serializedSingle", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<DatabaseSingleMapped<?, ?>> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(DatabaseSingleMapped<?, ?> obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final Mapper<A, B> mapper;
|
private final Mapper<A, B> mapper;
|
||||||
|
|
||||||
private DatabaseStageEntry<B> serializedSingle;
|
private DatabaseStageEntry<B> serializedSingle;
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public DatabaseSingleMapped(DatabaseStageEntry<B> serializedSingle, Mapper<A, B> mapper,
|
public DatabaseSingleMapped(DatabaseStageEntry<B> serializedSingle, Mapper<A, B> mapper,
|
||||||
Drop<DatabaseSingleMapped<A, B>> drop) {
|
Drop<DatabaseSingleMapped<A, B>> drop) {
|
||||||
super(new CloseOnDrop<>(drop));
|
super((Drop<DatabaseSingleMapped<A,B>>) (Drop) DROP);
|
||||||
this.serializedSingle = serializedSingle;
|
this.serializedSingle = serializedSingle;
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
private DatabaseSingleMapped(Send<DatabaseStage<B>> serializedSingle, Mapper<A, B> mapper,
|
private DatabaseSingleMapped(Send<DatabaseStage<B>> serializedSingle, Mapper<A, B> mapper,
|
||||||
Drop<DatabaseSingleMapped<A, B>> drop) {
|
Drop<DatabaseSingleMapped<A, B>> drop) {
|
||||||
super(new CloseOnDrop<>(drop));
|
super((Drop<DatabaseSingleMapped<A,B>>) (Drop) DROP);
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
|
|
||||||
this.serializedSingle = (DatabaseStageEntry<B>) serializedSingle.receive();
|
this.serializedSingle = (DatabaseStageEntry<B>) serializedSingle.receive();
|
||||||
@ -170,22 +199,4 @@ public class DatabaseSingleMapped<A, B> extends ResourceSupport<DatabaseStage<A>
|
|||||||
this.serializedSingle = null;
|
this.serializedSingle = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CloseOnDrop<A, B> implements Drop<DatabaseSingleMapped<A, B>> {
|
|
||||||
|
|
||||||
private final Drop<DatabaseSingleMapped<A, B>> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<DatabaseSingleMapped<A, B>> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop<A, B> closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(DatabaseSingleMapped<A, B> obj) {
|
|
||||||
obj.serializedSingle.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public class SubStageGetterHashMap<T, U, TH> implements
|
|||||||
Mono<Send<Buffer>> prefixKeyMono) {
|
Mono<Send<Buffer>> prefixKeyMono) {
|
||||||
return LLUtils.usingSend(prefixKeyMono, prefixKey -> Mono.just(DatabaseMapDictionaryHashed
|
return LLUtils.usingSend(prefixKeyMono, prefixKey -> Mono.just(DatabaseMapDictionaryHashed
|
||||||
.tail(dictionary, prefixKey, keySerializer, valueSerializer, keyHashFunction,
|
.tail(dictionary, prefixKey, keySerializer, valueSerializer, keyHashFunction,
|
||||||
keyHashSerializer, d -> {})), true);
|
keyHashSerializer, null)), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getKeyHashBinaryLength() {
|
public int getKeyHashBinaryLength() {
|
||||||
|
@ -35,7 +35,7 @@ public class SubStageGetterHashSet<T, TH> implements
|
|||||||
return Mono.usingWhen(prefixKeyMono,
|
return Mono.usingWhen(prefixKeyMono,
|
||||||
prefixKey -> Mono
|
prefixKey -> Mono
|
||||||
.fromSupplier(() -> DatabaseSetDictionaryHashed.tail(dictionary, prefixKey, keySerializer,
|
.fromSupplier(() -> DatabaseSetDictionaryHashed.tail(dictionary, prefixKey, keySerializer,
|
||||||
keyHashFunction, keyHashSerializer, d -> {})
|
keyHashFunction, keyHashSerializer, null)
|
||||||
),
|
),
|
||||||
prefixKey -> Mono.fromRunnable(prefixKey::close)
|
prefixKey -> Mono.fromRunnable(prefixKey::close)
|
||||||
);
|
);
|
||||||
|
@ -28,7 +28,7 @@ public class SubStageGetterMap<T, U> implements SubStageGetter<Map<T, U>, Databa
|
|||||||
Mono<Send<Buffer>> prefixKeyMono) {
|
Mono<Send<Buffer>> prefixKeyMono) {
|
||||||
return LLUtils.usingSend(prefixKeyMono,
|
return LLUtils.usingSend(prefixKeyMono,
|
||||||
prefixKey -> Mono.fromSupplier(() -> DatabaseMapDictionary
|
prefixKey -> Mono.fromSupplier(() -> DatabaseMapDictionary
|
||||||
.tail(dictionary, prefixKey, keySerializer, valueSerializer, d -> {})), true);
|
.tail(dictionary, prefixKey, keySerializer, valueSerializer, null)), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getKeyBinaryLength() {
|
public int getKeyBinaryLength() {
|
||||||
|
@ -42,8 +42,7 @@ public class SubStageGetterMapDeep<T, U, US extends DatabaseStage<U>> implements
|
|||||||
@Nullable CompositeSnapshot snapshot,
|
@Nullable CompositeSnapshot snapshot,
|
||||||
Mono<Send<Buffer>> prefixKeyMono) {
|
Mono<Send<Buffer>> prefixKeyMono) {
|
||||||
return LLUtils.usingSend(prefixKeyMono, prefixKey -> Mono.just(DatabaseMapDictionaryDeep
|
return LLUtils.usingSend(prefixKeyMono, prefixKey -> Mono.just(DatabaseMapDictionaryDeep
|
||||||
.deepIntermediate(dictionary, prefixKey, keySerializer, subStageGetter, keyExtLength,
|
.deepIntermediate(dictionary, prefixKey, keySerializer, subStageGetter, keyExtLength, null)), true);
|
||||||
d -> {})), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getKeyBinaryLength() {
|
public int getKeyBinaryLength() {
|
||||||
|
@ -24,7 +24,7 @@ public class SubStageGetterSet<T> implements SubStageGetter<Map<T, Nothing>, Dat
|
|||||||
Mono<Send<Buffer>> prefixKeyMono) {
|
Mono<Send<Buffer>> prefixKeyMono) {
|
||||||
return Mono.usingWhen(prefixKeyMono,
|
return Mono.usingWhen(prefixKeyMono,
|
||||||
prefixKey -> Mono
|
prefixKey -> Mono
|
||||||
.fromSupplier(() -> DatabaseSetDictionary.tail(dictionary, prefixKey, keySerializer, d -> {})),
|
.fromSupplier(() -> DatabaseSetDictionary.tail(dictionary, prefixKey, keySerializer, null)),
|
||||||
prefixKey -> Mono.fromRunnable(prefixKey::close)
|
prefixKey -> Mono.fromRunnable(prefixKey::close)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ public class SubStageGetterSingle<T> implements SubStageGetter<T, DatabaseStageE
|
|||||||
public Mono<DatabaseStageEntry<T>> subStage(LLDictionary dictionary,
|
public Mono<DatabaseStageEntry<T>> subStage(LLDictionary dictionary,
|
||||||
@Nullable CompositeSnapshot snapshot,
|
@Nullable CompositeSnapshot snapshot,
|
||||||
Mono<Send<Buffer>> keyPrefixMono) {
|
Mono<Send<Buffer>> keyPrefixMono) {
|
||||||
return keyPrefixMono.map(keyPrefix -> new DatabaseSingle<>(dictionary, keyPrefix, serializer, d -> {}));
|
return keyPrefixMono.map(keyPrefix -> new DatabaseSingle<>(dictionary, keyPrefix, serializer, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ public class CachedIndexSearcherManager implements IndexSearcherManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dropCachedIndexSearcher(LLIndexSearcher cachedIndexSearcher) {
|
private void dropCachedIndexSearcher() {
|
||||||
// This shouldn't happen more than once per searcher.
|
// This shouldn't happen more than once per searcher.
|
||||||
activeSearchers.arriveAndDeregister();
|
activeSearchers.arriveAndDeregister();
|
||||||
}
|
}
|
||||||
|
@ -3,18 +3,49 @@ package it.cavallium.dbengine.database.disk;
|
|||||||
import io.net5.buffer.api.Drop;
|
import io.net5.buffer.api.Drop;
|
||||||
import io.net5.buffer.api.Owned;
|
import io.net5.buffer.api.Owned;
|
||||||
import it.cavallium.dbengine.database.LiveResourceSupport;
|
import it.cavallium.dbengine.database.LiveResourceSupport;
|
||||||
|
import it.cavallium.dbengine.database.collections.DatabaseMapDictionaryHashed;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
import org.apache.lucene.search.IndexSearcher;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
|
|
||||||
public class LLIndexSearcher extends LiveResourceSupport<LLIndexSearcher, LLIndexSearcher> {
|
public class LLIndexSearcher extends LiveResourceSupport<LLIndexSearcher, LLIndexSearcher> {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(LLIndexSearcher.class);
|
||||||
|
|
||||||
|
private static final Drop<LLIndexSearcher> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(LLIndexSearcher obj) {
|
||||||
|
try {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close onClose", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<LLIndexSearcher> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(LLIndexSearcher obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private IndexSearcher indexSearcher;
|
private IndexSearcher indexSearcher;
|
||||||
private final boolean decRef;
|
private final boolean decRef;
|
||||||
|
|
||||||
public LLIndexSearcher(IndexSearcher indexSearcher, boolean decRef, Drop<LLIndexSearcher> drop) {
|
private Runnable onClose;
|
||||||
super(drop);
|
|
||||||
|
public LLIndexSearcher(IndexSearcher indexSearcher, boolean decRef, Runnable onClose) {
|
||||||
|
super(DROP);
|
||||||
this.indexSearcher = indexSearcher;
|
this.indexSearcher = indexSearcher;
|
||||||
this.decRef = decRef;
|
this.decRef = decRef;
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexReader getIndexReader() {
|
public IndexReader getIndexReader() {
|
||||||
@ -39,11 +70,13 @@ public class LLIndexSearcher extends LiveResourceSupport<LLIndexSearcher, LLInde
|
|||||||
@Override
|
@Override
|
||||||
protected Owned<LLIndexSearcher> prepareSend() {
|
protected Owned<LLIndexSearcher> prepareSend() {
|
||||||
var indexSearcher = this.indexSearcher;
|
var indexSearcher = this.indexSearcher;
|
||||||
return drop -> new LLIndexSearcher(indexSearcher, decRef, drop);
|
var onClose = this.onClose;
|
||||||
|
return drop -> new LLIndexSearcher(indexSearcher, decRef, onClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.indexSearcher = null;
|
this.indexSearcher = null;
|
||||||
|
this.onClose = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import io.net5.buffer.api.Resource;
|
|||||||
import io.net5.buffer.api.Send;
|
import io.net5.buffer.api.Send;
|
||||||
import io.net5.buffer.api.internal.ResourceSupport;
|
import io.net5.buffer.api.internal.ResourceSupport;
|
||||||
import it.cavallium.dbengine.database.LLEntry;
|
import it.cavallium.dbengine.database.LLEntry;
|
||||||
|
import it.cavallium.dbengine.database.LLSearchResultShard;
|
||||||
import it.cavallium.dbengine.database.LiveResourceSupport;
|
import it.cavallium.dbengine.database.LiveResourceSupport;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -22,15 +23,17 @@ import org.apache.lucene.index.MultiReader;
|
|||||||
import org.apache.lucene.index.StoredFieldVisitor;
|
import org.apache.lucene.index.StoredFieldVisitor;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
import org.apache.lucene.search.IndexSearcher;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
|
|
||||||
public interface LLIndexSearchers extends Resource<LLIndexSearchers> {
|
public interface LLIndexSearchers extends Resource<LLIndexSearchers> {
|
||||||
|
|
||||||
static LLIndexSearchers of(List<Send<LLIndexSearcher>> indexSearchers) {
|
static LLIndexSearchers of(List<Send<LLIndexSearcher>> indexSearchers) {
|
||||||
return new ShardedIndexSearchers(indexSearchers, d -> {});
|
return new ShardedIndexSearchers(indexSearchers, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UnshardedIndexSearchers unsharded(Send<LLIndexSearcher> indexSearcher) {
|
static UnshardedIndexSearchers unsharded(Send<LLIndexSearcher> indexSearcher) {
|
||||||
return new UnshardedIndexSearchers(indexSearcher, d -> {});
|
return new UnshardedIndexSearchers(indexSearcher, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<IndexSearcher> shards();
|
List<IndexSearcher> shards();
|
||||||
@ -42,11 +45,45 @@ public interface LLIndexSearchers extends Resource<LLIndexSearchers> {
|
|||||||
class UnshardedIndexSearchers extends LiveResourceSupport<LLIndexSearchers, UnshardedIndexSearchers>
|
class UnshardedIndexSearchers extends LiveResourceSupport<LLIndexSearchers, UnshardedIndexSearchers>
|
||||||
implements LLIndexSearchers {
|
implements LLIndexSearchers {
|
||||||
|
|
||||||
private LLIndexSearcher indexSearcher;
|
private static final Logger logger = LoggerFactory.getLogger(UnshardedIndexSearchers.class);
|
||||||
|
|
||||||
public UnshardedIndexSearchers(Send<LLIndexSearcher> indexSearcher, Drop<UnshardedIndexSearchers> drop) {
|
private static final Drop<UnshardedIndexSearchers> DROP = new Drop<>() {
|
||||||
super(new CloseOnDrop(drop));
|
@Override
|
||||||
|
public void drop(UnshardedIndexSearchers obj) {
|
||||||
|
try {
|
||||||
|
if (obj.indexSearcher != null) {
|
||||||
|
obj.indexSearcher.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close indexSearcher", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close onClose", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<UnshardedIndexSearchers> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(UnshardedIndexSearchers obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private LLIndexSearcher indexSearcher;
|
||||||
|
private Runnable onClose;
|
||||||
|
|
||||||
|
public UnshardedIndexSearchers(Send<LLIndexSearcher> indexSearcher, Runnable onClose) {
|
||||||
|
super(DROP);
|
||||||
this.indexSearcher = indexSearcher.receive();
|
this.indexSearcher = indexSearcher.receive();
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -82,41 +119,61 @@ public interface LLIndexSearchers extends Resource<LLIndexSearchers> {
|
|||||||
@Override
|
@Override
|
||||||
protected Owned<UnshardedIndexSearchers> prepareSend() {
|
protected Owned<UnshardedIndexSearchers> prepareSend() {
|
||||||
Send<LLIndexSearcher> indexSearcher = this.indexSearcher.send();
|
Send<LLIndexSearcher> indexSearcher = this.indexSearcher.send();
|
||||||
return drop -> new UnshardedIndexSearchers(indexSearcher, drop);
|
var onClose = this.onClose;
|
||||||
|
return drop -> {
|
||||||
|
var instance = new UnshardedIndexSearchers(indexSearcher, onClose);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.indexSearcher = null;
|
this.indexSearcher = null;
|
||||||
}
|
this.onClose = null;
|
||||||
|
|
||||||
private static class CloseOnDrop implements Drop<UnshardedIndexSearchers> {
|
|
||||||
|
|
||||||
private final Drop<UnshardedIndexSearchers> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<UnshardedIndexSearchers> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(UnshardedIndexSearchers obj) {
|
|
||||||
obj.indexSearcher.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShardedIndexSearchers extends LiveResourceSupport<LLIndexSearchers, ShardedIndexSearchers>
|
class ShardedIndexSearchers extends LiveResourceSupport<LLIndexSearchers, ShardedIndexSearchers>
|
||||||
implements LLIndexSearchers {
|
implements LLIndexSearchers {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(ShardedIndexSearchers.class);
|
||||||
|
|
||||||
|
private static final Drop<ShardedIndexSearchers> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(ShardedIndexSearchers obj) {
|
||||||
|
try {
|
||||||
|
for (LLIndexSearcher indexSearcher : obj.indexSearchers) {
|
||||||
|
indexSearcher.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close indexSearcher", ex);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close onClose", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<ShardedIndexSearchers> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(ShardedIndexSearchers obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private List<LLIndexSearcher> indexSearchers;
|
private List<LLIndexSearcher> indexSearchers;
|
||||||
private List<IndexSearcher> indexSearchersVals;
|
private List<IndexSearcher> indexSearchersVals;
|
||||||
|
private Runnable onClose;
|
||||||
|
|
||||||
public ShardedIndexSearchers(List<Send<LLIndexSearcher>> indexSearchers, Drop<ShardedIndexSearchers> drop) {
|
public ShardedIndexSearchers(List<Send<LLIndexSearcher>> indexSearchers, Runnable onClose) {
|
||||||
super(new CloseOnDrop(drop));
|
super(DROP);
|
||||||
this.indexSearchers = new ArrayList<>(indexSearchers.size());
|
this.indexSearchers = new ArrayList<>(indexSearchers.size());
|
||||||
this.indexSearchersVals = new ArrayList<>(indexSearchers.size());
|
this.indexSearchersVals = new ArrayList<>(indexSearchers.size());
|
||||||
for (Send<LLIndexSearcher> llIndexSearcher : indexSearchers) {
|
for (Send<LLIndexSearcher> llIndexSearcher : indexSearchers) {
|
||||||
@ -124,6 +181,7 @@ public interface LLIndexSearchers extends Resource<LLIndexSearchers> {
|
|||||||
this.indexSearchers.add(indexSearcher);
|
this.indexSearchers.add(indexSearcher);
|
||||||
this.indexSearchersVals.add(indexSearcher.getIndexSearcher());
|
this.indexSearchersVals.add(indexSearcher.getIndexSearcher());
|
||||||
}
|
}
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -177,33 +235,18 @@ public interface LLIndexSearchers extends Resource<LLIndexSearchers> {
|
|||||||
for (LLIndexSearcher indexSearcher : this.indexSearchers) {
|
for (LLIndexSearcher indexSearcher : this.indexSearchers) {
|
||||||
indexSearchers.add(indexSearcher.send());
|
indexSearchers.add(indexSearcher.send());
|
||||||
}
|
}
|
||||||
return drop -> new ShardedIndexSearchers(indexSearchers, drop);
|
var onClose = this.onClose;
|
||||||
|
return drop -> {
|
||||||
|
var instance = new ShardedIndexSearchers(indexSearchers, onClose);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.indexSearchers = null;
|
this.indexSearchers = null;
|
||||||
this.indexSearchersVals = null;
|
this.indexSearchersVals = null;
|
||||||
}
|
this.onClose = null;
|
||||||
|
|
||||||
private static class CloseOnDrop implements Drop<ShardedIndexSearchers> {
|
|
||||||
|
|
||||||
private final Drop<ShardedIndexSearchers> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<ShardedIndexSearchers> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(ShardedIndexSearchers obj) {
|
|
||||||
for (LLIndexSearcher indexSearcher : obj.indexSearchers) {
|
|
||||||
indexSearcher.close();
|
|
||||||
}
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,7 +332,7 @@ public class LLLocalLuceneIndex implements LLLuceneIndex {
|
|||||||
|
|
||||||
return localSearcher.collect(searcher, localQueryParams, keyFieldName, transformer).map(resultToReceive -> {
|
return localSearcher.collect(searcher, localQueryParams, keyFieldName, transformer).map(resultToReceive -> {
|
||||||
var result = resultToReceive.receive();
|
var result = resultToReceive.receive();
|
||||||
return new LLSearchResultShard(result.results(), result.totalHitsCount(), d -> result.close()).send();
|
return new LLSearchResultShard(result.results(), result.totalHitsCount(), result::close).send();
|
||||||
}).doOnDiscard(Send.class, Send::close);
|
}).doOnDiscard(Send.class, Send::close);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ public class LLLocalLuceneIndex implements LLLuceneIndex {
|
|||||||
|
|
||||||
return localSearcher.collect(searcher, localQueryParams, keyFieldName, NO_TRANSFORMATION).map(resultToReceive -> {
|
return localSearcher.collect(searcher, localQueryParams, keyFieldName, NO_TRANSFORMATION).map(resultToReceive -> {
|
||||||
var result = resultToReceive.receive();
|
var result = resultToReceive.receive();
|
||||||
return new LLSearchResultShard(result.results(), result.totalHitsCount(), d -> result.close()).send();
|
return new LLSearchResultShard(result.results(), result.totalHitsCount(), result::close).send();
|
||||||
}).doOnDiscard(Send.class, Send::close);
|
}).doOnDiscard(Send.class, Send::close);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,8 +206,7 @@ public class LLLocalMultiLuceneIndex implements LLLuceneIndex {
|
|||||||
// Transform the result type
|
// Transform the result type
|
||||||
.map(resultToReceive -> {
|
.map(resultToReceive -> {
|
||||||
var result = resultToReceive.receive();
|
var result = resultToReceive.receive();
|
||||||
return new LLSearchResultShard(result.results(), result.totalHitsCount(),
|
return new LLSearchResultShard(result.results(), result.totalHitsCount(), result::close).send();
|
||||||
d -> result.close()).send();
|
|
||||||
})
|
})
|
||||||
.doOnDiscard(Send.class, Send::close);
|
.doOnDiscard(Send.class, Send::close);
|
||||||
}
|
}
|
||||||
@ -225,8 +224,7 @@ public class LLLocalMultiLuceneIndex implements LLLuceneIndex {
|
|||||||
// Transform the result type
|
// Transform the result type
|
||||||
.map(resultToReceive -> {
|
.map(resultToReceive -> {
|
||||||
var result = resultToReceive.receive();
|
var result = resultToReceive.receive();
|
||||||
return new LLSearchResultShard(result.results(), result.totalHitsCount(),
|
return new LLSearchResultShard(result.results(), result.totalHitsCount(), result::close).send();
|
||||||
d -> result.close()).send();
|
|
||||||
})
|
})
|
||||||
.doOnDiscard(Send.class, Send::close);
|
.doOnDiscard(Send.class, Send::close);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public class CountLuceneLocalSearcher implements LuceneLocalSearcher {
|
|||||||
}).subscribeOn(Schedulers.boundedElastic()),
|
}).subscribeOn(Schedulers.boundedElastic()),
|
||||||
is -> Mono.empty()
|
is -> Mono.empty()
|
||||||
)
|
)
|
||||||
.map(count -> new LuceneSearchResult(TotalHitsCount.of(count, true), Flux.empty(), drop -> {}).send())
|
.map(count -> new LuceneSearchResult(TotalHitsCount.of(count, true), Flux.empty(), null).send())
|
||||||
.doOnDiscard(Send.class, Send::close);
|
.doOnDiscard(Send.class, Send::close);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,13 +19,38 @@ public final class LuceneSearchResult extends LiveResourceSupport<LuceneSearchRe
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(LuceneSearchResult.class);
|
private static final Logger logger = LoggerFactory.getLogger(LuceneSearchResult.class);
|
||||||
|
|
||||||
|
private static final Drop<LuceneSearchResult> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(LuceneSearchResult obj) {
|
||||||
|
try {
|
||||||
|
if (obj.onClose != null) {
|
||||||
|
obj.onClose.run();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close onClose", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<LuceneSearchResult> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(LuceneSearchResult obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private TotalHitsCount totalHitsCount;
|
private TotalHitsCount totalHitsCount;
|
||||||
private Flux<LLKeyScore> results;
|
private Flux<LLKeyScore> results;
|
||||||
|
private Runnable onClose;
|
||||||
|
|
||||||
public LuceneSearchResult(TotalHitsCount totalHitsCount, Flux<LLKeyScore> results, Drop<LuceneSearchResult> drop) {
|
public LuceneSearchResult(TotalHitsCount totalHitsCount, Flux<LLKeyScore> results, Runnable onClose) {
|
||||||
super(drop);
|
super(DROP);
|
||||||
this.totalHitsCount = totalHitsCount;
|
this.totalHitsCount = totalHitsCount;
|
||||||
this.results = results;
|
this.results = results;
|
||||||
|
this.onClose = onClose;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TotalHitsCount totalHitsCount() {
|
public TotalHitsCount totalHitsCount() {
|
||||||
@ -71,12 +96,18 @@ public final class LuceneSearchResult extends LiveResourceSupport<LuceneSearchRe
|
|||||||
protected Owned<LuceneSearchResult> prepareSend() {
|
protected Owned<LuceneSearchResult> prepareSend() {
|
||||||
var totalHitsCount = this.totalHitsCount;
|
var totalHitsCount = this.totalHitsCount;
|
||||||
var results = this.results;
|
var results = this.results;
|
||||||
return drop -> new LuceneSearchResult(totalHitsCount, results, drop);
|
var onClose = this.onClose;
|
||||||
|
return drop -> {
|
||||||
|
var instance = new LuceneSearchResult(totalHitsCount, results, onClose);
|
||||||
|
drop.attach(instance);
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.totalHitsCount = null;
|
this.totalHitsCount = null;
|
||||||
this.results = null;
|
this.results = null;
|
||||||
|
this.onClose = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ public class ScoredSimpleLuceneShardSearcher implements LuceneMultiSearcher {
|
|||||||
List<IndexSearcher> indexSearchers,
|
List<IndexSearcher> indexSearchers,
|
||||||
LocalQueryParams queryParams,
|
LocalQueryParams queryParams,
|
||||||
String keyFieldName,
|
String keyFieldName,
|
||||||
Runnable drop) {
|
Runnable onClose) {
|
||||||
var totalHitsCount = firstResult.totalHitsCount();
|
var totalHitsCount = firstResult.totalHitsCount();
|
||||||
var firstPageHitsFlux = firstResult.firstPageHitsFlux();
|
var firstPageHitsFlux = firstResult.firstPageHitsFlux();
|
||||||
var secondPageInfo = firstResult.nextPageInfo();
|
var secondPageInfo = firstResult.nextPageInfo();
|
||||||
@ -119,7 +119,7 @@ public class ScoredSimpleLuceneShardSearcher implements LuceneMultiSearcher {
|
|||||||
Flux<LLKeyScore> nextHitsFlux = searchOtherPages(indexSearchers, queryParams, keyFieldName, secondPageInfo);
|
Flux<LLKeyScore> nextHitsFlux = searchOtherPages(indexSearchers, queryParams, keyFieldName, secondPageInfo);
|
||||||
|
|
||||||
Flux<LLKeyScore> combinedFlux = firstPageHitsFlux.concatWith(nextHitsFlux);
|
Flux<LLKeyScore> combinedFlux = firstPageHitsFlux.concatWith(nextHitsFlux);
|
||||||
return new LuceneSearchResult(totalHitsCount, combinedFlux, d -> drop.run()).send();
|
return new LuceneSearchResult(totalHitsCount, combinedFlux, onClose).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,7 +102,7 @@ public class SimpleLuceneLocalSearcher implements LuceneLocalSearcher {
|
|||||||
List<IndexSearcher> indexSearchers,
|
List<IndexSearcher> indexSearchers,
|
||||||
LocalQueryParams queryParams,
|
LocalQueryParams queryParams,
|
||||||
String keyFieldName,
|
String keyFieldName,
|
||||||
Runnable drop) {
|
Runnable onClose) {
|
||||||
return firstResultMono.map(firstResult -> {
|
return firstResultMono.map(firstResult -> {
|
||||||
var totalHitsCount = firstResult.totalHitsCount();
|
var totalHitsCount = firstResult.totalHitsCount();
|
||||||
var firstPageHitsFlux = firstResult.firstPageHitsFlux();
|
var firstPageHitsFlux = firstResult.firstPageHitsFlux();
|
||||||
@ -111,7 +111,7 @@ public class SimpleLuceneLocalSearcher implements LuceneLocalSearcher {
|
|||||||
Flux<LLKeyScore> nextHitsFlux = searchOtherPages(indexSearchers, queryParams, keyFieldName, secondPageInfo);
|
Flux<LLKeyScore> nextHitsFlux = searchOtherPages(indexSearchers, queryParams, keyFieldName, secondPageInfo);
|
||||||
|
|
||||||
Flux<LLKeyScore> combinedFlux = firstPageHitsFlux.concatWith(nextHitsFlux);
|
Flux<LLKeyScore> combinedFlux = firstPageHitsFlux.concatWith(nextHitsFlux);
|
||||||
return new LuceneSearchResult(totalHitsCount, combinedFlux, d -> drop.run()).send();
|
return new LuceneSearchResult(totalHitsCount, combinedFlux, onClose).send();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public class SimpleUnsortedUnscoredLuceneMultiSearcher implements LuceneMultiSea
|
|||||||
indexSearchers -> Flux
|
indexSearchers -> Flux
|
||||||
.fromIterable(indexSearchers.shards())
|
.fromIterable(indexSearchers.shards())
|
||||||
.flatMap(searcher -> {
|
.flatMap(searcher -> {
|
||||||
var llSearcher = Mono.fromCallable(() -> new LLIndexSearcher(searcher, false, d -> {}).send());
|
var llSearcher = Mono.fromCallable(() -> new LLIndexSearcher(searcher, false, null).send());
|
||||||
return localSearcher.collect(llSearcher, localQueryParams, keyFieldName, transformer);
|
return localSearcher.collect(llSearcher, localQueryParams, keyFieldName, transformer);
|
||||||
})
|
})
|
||||||
.collectList()
|
.collectList()
|
||||||
@ -67,7 +67,7 @@ public class SimpleUnsortedUnscoredLuceneMultiSearcher implements LuceneMultiSea
|
|||||||
.skip(queryParams.offset())
|
.skip(queryParams.offset())
|
||||||
.take(queryParams.limit(), true);
|
.take(queryParams.limit(), true);
|
||||||
|
|
||||||
return new LuceneSearchResult(totalHitsCount, mergedFluxes, d -> {
|
return new LuceneSearchResult(totalHitsCount, mergedFluxes, () -> {
|
||||||
for (LuceneSearchResult luceneSearchResult : resultsToDrop) {
|
for (LuceneSearchResult luceneSearchResult : resultsToDrop) {
|
||||||
luceneSearchResult.close();
|
luceneSearchResult.close();
|
||||||
}
|
}
|
||||||
|
@ -92,9 +92,7 @@ public class UnsortedUnscoredContinuousLuceneMultiSearcher implements LuceneMult
|
|||||||
.skip(queryParams.offset())
|
.skip(queryParams.offset())
|
||||||
.take(queryParams.limit(), true);
|
.take(queryParams.limit(), true);
|
||||||
|
|
||||||
return new LuceneSearchResult(totalHitsCount, mergedFluxes, d -> {
|
return new LuceneSearchResult(totalHitsCount, mergedFluxes, indexSearchers::close).send();
|
||||||
indexSearchers.close();
|
|
||||||
}).send();
|
|
||||||
}), false);
|
}), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public class JMXNettyMonitoringManager {
|
|||||||
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
var instance = getInstance();
|
var instance = getInstance();
|
||||||
instance.register("global", DefaultGlobalBufferAllocator.DEFAUL_GLOBAL_BUFFER_ALLOCATOR);
|
instance.register("global", DefaultGlobalBufferAllocator.DEFAULT_GLOBAL_BUFFER_ALLOCATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized static JMXNettyMonitoringManager getInstance() {
|
public synchronized static JMXNettyMonitoringManager getInstance() {
|
||||||
|
@ -6,22 +6,50 @@ import io.net5.buffer.api.Owned;
|
|||||||
import io.net5.buffer.api.Send;
|
import io.net5.buffer.api.Send;
|
||||||
import io.net5.buffer.api.internal.ResourceSupport;
|
import io.net5.buffer.api.internal.ResourceSupport;
|
||||||
import it.cavallium.dbengine.client.SearchResult;
|
import it.cavallium.dbengine.client.SearchResult;
|
||||||
|
import it.cavallium.dbengine.database.LLSearchResultShard;
|
||||||
import it.cavallium.dbengine.database.LiveResourceSupport;
|
import it.cavallium.dbengine.database.LiveResourceSupport;
|
||||||
import it.cavallium.dbengine.database.collections.DatabaseSingle;
|
import it.cavallium.dbengine.database.collections.DatabaseSingle;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.warp.commonutils.log.Logger;
|
||||||
|
import org.warp.commonutils.log.LoggerFactory;
|
||||||
|
|
||||||
public class NullableBuffer extends LiveResourceSupport<NullableBuffer, NullableBuffer> {
|
public class NullableBuffer extends LiveResourceSupport<NullableBuffer, NullableBuffer> {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(NullableBuffer.class);
|
||||||
|
|
||||||
|
private static final Drop<NullableBuffer> DROP = new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(NullableBuffer obj) {
|
||||||
|
try {
|
||||||
|
if (obj.buffer != null) {
|
||||||
|
obj.buffer.close();
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
logger.error("Failed to close buffer", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<NullableBuffer> fork() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(NullableBuffer obj) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Buffer buffer;
|
private Buffer buffer;
|
||||||
|
|
||||||
public NullableBuffer(@Nullable Buffer buffer, Drop<NullableBuffer> drop) {
|
public NullableBuffer(@Nullable Buffer buffer) {
|
||||||
super(new CloseOnDrop(drop));
|
super(DROP);
|
||||||
this.buffer = buffer == null ? null : buffer.send().receive();
|
this.buffer = buffer == null ? null : buffer.send().receive();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NullableBuffer(@Nullable Send<Buffer> buffer, Drop<NullableBuffer> drop) {
|
public NullableBuffer(@Nullable Send<Buffer> buffer) {
|
||||||
super(new CloseOnDrop(drop));
|
super(DROP);
|
||||||
this.buffer = buffer == null ? null : buffer.receive();
|
this.buffer = buffer == null ? null : buffer.receive();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,29 +71,10 @@ public class NullableBuffer extends LiveResourceSupport<NullableBuffer, Nullable
|
|||||||
@Override
|
@Override
|
||||||
protected Owned<NullableBuffer> prepareSend() {
|
protected Owned<NullableBuffer> prepareSend() {
|
||||||
var buffer = this.buffer == null ? null : this.buffer.send();
|
var buffer = this.buffer == null ? null : this.buffer.send();
|
||||||
return drop -> new NullableBuffer(buffer, drop);
|
return drop -> new NullableBuffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void makeInaccessible() {
|
protected void makeInaccessible() {
|
||||||
this.buffer = null;
|
this.buffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CloseOnDrop implements Drop<NullableBuffer> {
|
|
||||||
|
|
||||||
private final Drop<NullableBuffer> delegate;
|
|
||||||
|
|
||||||
public CloseOnDrop(Drop<NullableBuffer> drop) {
|
|
||||||
if (drop instanceof CloseOnDrop closeOnDrop) {
|
|
||||||
this.delegate = closeOnDrop.delegate;
|
|
||||||
} else {
|
|
||||||
this.delegate = drop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void drop(NullableBuffer obj) {
|
|
||||||
if (obj.buffer != null) obj.buffer.close();
|
|
||||||
delegate.drop(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ public class DbTestUtils {
|
|||||||
return DatabaseMapDictionary.simple(dictionary,
|
return DatabaseMapDictionary.simple(dictionary,
|
||||||
SerializerFixedBinaryLength.utf8(dictionary.getAllocator(), keyBytes),
|
SerializerFixedBinaryLength.utf8(dictionary.getAllocator(), keyBytes),
|
||||||
Serializer.utf8(dictionary.getAllocator()),
|
Serializer.utf8(dictionary.getAllocator()),
|
||||||
d -> {}
|
null
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return DatabaseMapDictionaryHashed.simple(dictionary,
|
return DatabaseMapDictionaryHashed.simple(dictionary,
|
||||||
@ -211,7 +211,7 @@ public class DbTestUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
d -> {}
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,7 +227,7 @@ public class DbTestUtils {
|
|||||||
new SubStageGetterMap<>(SerializerFixedBinaryLength.utf8(dictionary.getAllocator(), key2Bytes),
|
new SubStageGetterMap<>(SerializerFixedBinaryLength.utf8(dictionary.getAllocator(), key2Bytes),
|
||||||
Serializer.utf8(dictionary.getAllocator())
|
Serializer.utf8(dictionary.getAllocator())
|
||||||
),
|
),
|
||||||
d -> {}
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ public class DbTestUtils {
|
|||||||
String::hashCode,
|
String::hashCode,
|
||||||
SerializerFixedBinaryLength.intSerializer(dictionary.getAllocator())
|
SerializerFixedBinaryLength.intSerializer(dictionary.getAllocator())
|
||||||
),
|
),
|
||||||
d -> {}
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ public class DbTestUtils {
|
|||||||
Serializer.utf8(dictionary.getAllocator()),
|
Serializer.utf8(dictionary.getAllocator()),
|
||||||
String::hashCode,
|
String::hashCode,
|
||||||
SerializerFixedBinaryLength.intSerializer(dictionary.getAllocator()),
|
SerializerFixedBinaryLength.intSerializer(dictionary.getAllocator()),
|
||||||
d -> {}
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user