2021-01-30 00:24:55 +01:00
|
|
|
package it.cavallium.dbengine.database;
|
|
|
|
|
2022-03-16 13:47:56 +01:00
|
|
|
import static io.netty5.buffer.Unpooled.wrappedBuffer;
|
2021-04-30 19:15:04 +02:00
|
|
|
|
2022-03-16 13:47:56 +01:00
|
|
|
import io.netty5.buffer.api.Buffer;
|
|
|
|
import io.netty5.buffer.api.Drop;
|
|
|
|
import io.netty5.buffer.api.Owned;
|
|
|
|
import io.netty5.buffer.api.Send;
|
|
|
|
import io.netty5.buffer.api.internal.ResourceSupport;
|
2021-01-30 00:24:55 +01:00
|
|
|
import java.util.StringJoiner;
|
2021-12-17 01:48:49 +01:00
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
|
|
import org.apache.logging.log4j.Logger;
|
2021-09-24 01:59:56 +02:00
|
|
|
import org.jetbrains.annotations.Nullable;
|
2021-01-30 00:24:55 +01:00
|
|
|
|
2021-03-13 19:01:36 +01:00
|
|
|
/**
|
|
|
|
* Range of data, from min (inclusive),to max (exclusive)
|
|
|
|
*/
|
2021-10-17 17:15:57 +02:00
|
|
|
public class LLRange extends ResourceSupport<LLRange, LLRange> {
|
2021-01-30 00:24:55 +01:00
|
|
|
|
2021-12-17 01:48:49 +01:00
|
|
|
private static final Logger logger = LogManager.getLogger(LLRange.class);
|
2021-10-01 19:17:33 +02:00
|
|
|
|
|
|
|
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) {
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-11-08 16:33:41 +01:00
|
|
|
private static final LLRange RANGE_ALL = new LLRange((Buffer) null, (Buffer) null, (Buffer) null);
|
2021-09-24 01:59:56 +02:00
|
|
|
@Nullable
|
2021-08-29 23:18:03 +02:00
|
|
|
private Buffer min;
|
2021-09-24 01:59:56 +02:00
|
|
|
@Nullable
|
2021-08-29 23:18:03 +02:00
|
|
|
private Buffer max;
|
2021-09-24 01:59:56 +02:00
|
|
|
@Nullable
|
2021-08-29 23:18:03 +02:00
|
|
|
private Buffer single;
|
2021-04-30 19:15:04 +02:00
|
|
|
|
2021-10-01 19:17:33 +02:00
|
|
|
private LLRange(Send<Buffer> min, Send<Buffer> max, Send<Buffer> single) {
|
|
|
|
super(DROP);
|
2021-08-29 23:18:03 +02:00
|
|
|
assert isAllAccessible();
|
|
|
|
assert single == null || (min == null && max == null);
|
|
|
|
this.min = min != null ? min.receive().makeReadOnly() : null;
|
|
|
|
this.max = max != null ? max.receive().makeReadOnly() : null;
|
|
|
|
this.single = single != null ? single.receive().makeReadOnly() : null;
|
|
|
|
}
|
|
|
|
|
2021-11-08 16:33:41 +01:00
|
|
|
private LLRange(Buffer min, Buffer max, Buffer single) {
|
|
|
|
super(DROP);
|
|
|
|
assert isAllAccessible();
|
|
|
|
assert single == null || (min == null && max == null);
|
|
|
|
this.min = min != null ? min.makeReadOnly() : null;
|
|
|
|
this.max = max != null ? max.makeReadOnly() : null;
|
|
|
|
this.single = single != null ? single.makeReadOnly() : null;
|
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
private boolean isAllAccessible() {
|
2021-12-17 01:48:49 +01:00
|
|
|
assert min == null || min.isAccessible() : "Range min not owned";
|
|
|
|
assert max == null || max.isAccessible() : "Range max not owned";
|
|
|
|
assert single == null || single.isAccessible() : "Range single not owned";
|
|
|
|
assert this.isAccessible() : "Range not accessible";
|
|
|
|
assert this.isOwned() : "Range not owned";
|
2021-08-29 23:18:03 +02:00
|
|
|
return true;
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public static LLRange all() {
|
2021-08-29 23:18:03 +02:00
|
|
|
return RANGE_ALL.copy();
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
public static LLRange from(Send<Buffer> min) {
|
2021-10-01 19:17:33 +02:00
|
|
|
return new LLRange(min, null, null);
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
public static LLRange to(Send<Buffer> max) {
|
2021-10-01 19:17:33 +02:00
|
|
|
return new LLRange(null, max, null);
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
public static LLRange single(Send<Buffer> single) {
|
2021-10-01 19:17:33 +02:00
|
|
|
return new LLRange(null, null, single);
|
2021-01-30 19:27:59 +01:00
|
|
|
}
|
|
|
|
|
2022-01-22 23:21:40 +01:00
|
|
|
public static LLRange singleUnsafe(Buffer single) {
|
|
|
|
return new LLRange(null, null, single);
|
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
public static LLRange of(Send<Buffer> min, Send<Buffer> max) {
|
2021-10-01 19:17:33 +02:00
|
|
|
return new LLRange(min, max, null);
|
2021-11-08 16:33:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public static LLRange ofUnsafe(Buffer min, Buffer max) {
|
|
|
|
return new LLRange(min, max, null);
|
2021-01-30 19:27:59 +01:00
|
|
|
}
|
|
|
|
|
2021-01-30 00:24:55 +01:00
|
|
|
public boolean isAll() {
|
2021-08-29 23:18:03 +02:00
|
|
|
ensureOwned();
|
|
|
|
return min == null && max == null && single == null;
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isSingle() {
|
2021-08-29 23:18:03 +02:00
|
|
|
ensureOwned();
|
|
|
|
return single != null;
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasMin() {
|
2021-08-29 23:18:03 +02:00
|
|
|
ensureOwned();
|
|
|
|
return min != null || single != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Send<Buffer> getMin() {
|
|
|
|
ensureOwned();
|
|
|
|
if (min != null) {
|
|
|
|
return min.copy().send();
|
|
|
|
} else if (single != null) {
|
|
|
|
return single.copy().send();
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
public Buffer getMinUnsafe() {
|
|
|
|
ensureOwned();
|
|
|
|
if (min != null) {
|
|
|
|
return min;
|
|
|
|
} else if (single != null) {
|
|
|
|
return single;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasMax() {
|
2021-08-29 23:18:03 +02:00
|
|
|
ensureOwned();
|
|
|
|
return max != null || single != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Send<Buffer> getMax() {
|
|
|
|
ensureOwned();
|
|
|
|
if (max != null) {
|
|
|
|
return max.copy().send();
|
|
|
|
} else if (single != null) {
|
|
|
|
return single.copy().send();
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Buffer getMaxUnsafe() {
|
|
|
|
ensureOwned();
|
|
|
|
if (max != null) {
|
|
|
|
return max;
|
|
|
|
} else if (single != null) {
|
|
|
|
return single;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
public Send<Buffer> getSingle() {
|
|
|
|
ensureOwned();
|
|
|
|
assert isSingle();
|
|
|
|
return single != null ? single.copy().send() : null;
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
public Buffer getSingleUnsafe() {
|
|
|
|
ensureOwned();
|
2021-01-30 00:24:55 +01:00
|
|
|
assert isSingle();
|
2021-08-29 23:18:03 +02:00
|
|
|
return single;
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
private void ensureOwned() {
|
|
|
|
assert isAllAccessible();
|
|
|
|
if (!isOwned()) {
|
|
|
|
if (!isAccessible()) {
|
|
|
|
throw this.createResourceClosedException();
|
|
|
|
} else {
|
|
|
|
throw new IllegalStateException("Resource not owned");
|
|
|
|
}
|
2021-06-19 13:27:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-30 00:24:55 +01:00
|
|
|
@Override
|
|
|
|
public boolean equals(Object o) {
|
|
|
|
if (this == o) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (o == null || getClass() != o.getClass()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
LLRange llRange = (LLRange) o;
|
2021-04-30 19:15:04 +02:00
|
|
|
return LLUtils.equals(min, llRange.min) && LLUtils.equals(max, llRange.max);
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
2021-04-30 19:15:04 +02:00
|
|
|
int result = LLUtils.hashCode(min);
|
|
|
|
result = 31 * result + LLUtils.hashCode(max);
|
2021-01-30 00:24:55 +01:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return new StringJoiner(", ", LLRange.class.getSimpleName() + "[", "]")
|
2021-04-30 19:15:04 +02:00
|
|
|
.add("min=" + LLUtils.toString(min))
|
|
|
|
.add("max=" + LLUtils.toString(max))
|
2021-01-30 00:24:55 +01:00
|
|
|
.toString();
|
|
|
|
}
|
2021-04-30 19:15:04 +02:00
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
public LLRange copy() {
|
|
|
|
ensureOwned();
|
|
|
|
return new LLRange(min != null ? min.copy().send() : null,
|
|
|
|
max != null ? max.copy().send() : null,
|
2021-10-01 19:17:33 +02:00
|
|
|
single != null ? single.copy().send(): null
|
2021-08-29 23:18:03 +02:00
|
|
|
);
|
2021-04-30 19:15:04 +02:00
|
|
|
}
|
|
|
|
|
2021-08-29 23:18:03 +02:00
|
|
|
@Override
|
|
|
|
protected RuntimeException createResourceClosedException() {
|
|
|
|
return new IllegalStateException("Closed");
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Owned<LLRange> prepareSend() {
|
|
|
|
Send<Buffer> minSend;
|
|
|
|
Send<Buffer> maxSend;
|
|
|
|
Send<Buffer> singleSend;
|
|
|
|
minSend = this.min != null ? this.min.send() : null;
|
|
|
|
maxSend = this.max != null ? this.max.send() : null;
|
|
|
|
singleSend = this.single != null ? this.single.send() : null;
|
2021-10-01 19:17:33 +02:00
|
|
|
return drop -> {
|
|
|
|
var instance = new LLRange(minSend, maxSend, singleSend);
|
|
|
|
drop.attach(instance);
|
|
|
|
return instance;
|
|
|
|
};
|
2021-08-29 23:18:03 +02:00
|
|
|
}
|
|
|
|
|
2021-09-23 15:34:56 +02:00
|
|
|
protected void makeInaccessible() {
|
2021-08-29 23:18:03 +02:00
|
|
|
this.min = null;
|
|
|
|
this.max = null;
|
|
|
|
this.single = null;
|
|
|
|
}
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|