2021-01-30 00:24:55 +01:00
|
|
|
package it.cavallium.dbengine.database;
|
|
|
|
|
2021-04-30 19:15:04 +02:00
|
|
|
import static io.netty.buffer.Unpooled.wrappedBuffer;
|
|
|
|
import static io.netty.buffer.Unpooled.wrappedUnmodifiableBuffer;
|
|
|
|
|
|
|
|
import io.netty.buffer.ByteBuf;
|
|
|
|
import io.netty.buffer.ByteBufUtil;
|
2021-01-30 00:24:55 +01:00
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.StringJoiner;
|
2021-06-19 13:27:58 +02:00
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
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-01-30 00:24:55 +01:00
|
|
|
public class LLRange {
|
|
|
|
|
|
|
|
private static final LLRange RANGE_ALL = new LLRange(null, null);
|
2021-04-30 19:15:04 +02:00
|
|
|
private final ByteBuf min;
|
|
|
|
private final ByteBuf max;
|
2021-06-19 13:27:58 +02:00
|
|
|
private final AtomicInteger refCnt = new AtomicInteger(1);
|
2021-04-30 19:15:04 +02:00
|
|
|
|
|
|
|
private LLRange(ByteBuf min, ByteBuf max) {
|
|
|
|
assert min == null || min.refCnt() > 0;
|
|
|
|
assert max == null || max.refCnt() > 0;
|
2021-01-30 00:24:55 +01:00
|
|
|
this.min = min;
|
|
|
|
this.max = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static LLRange all() {
|
|
|
|
return RANGE_ALL;
|
|
|
|
}
|
|
|
|
|
2021-04-30 19:15:04 +02:00
|
|
|
public static LLRange from(ByteBuf min) {
|
2021-01-30 00:24:55 +01:00
|
|
|
return new LLRange(min, null);
|
|
|
|
}
|
|
|
|
|
2021-04-30 19:15:04 +02:00
|
|
|
public static LLRange to(ByteBuf max) {
|
2021-01-30 00:24:55 +01:00
|
|
|
return new LLRange(null, max);
|
|
|
|
}
|
|
|
|
|
2021-04-30 19:15:04 +02:00
|
|
|
public static LLRange single(ByteBuf single) {
|
2021-05-12 19:02:51 +02:00
|
|
|
try {
|
|
|
|
return new LLRange(single.retain(), single.retain());
|
|
|
|
} finally {
|
|
|
|
single.release();
|
|
|
|
}
|
2021-01-30 19:27:59 +01:00
|
|
|
}
|
|
|
|
|
2021-04-30 19:15:04 +02:00
|
|
|
public static LLRange of(ByteBuf min, ByteBuf max) {
|
2021-01-30 19:27:59 +01:00
|
|
|
return new LLRange(min, max);
|
|
|
|
}
|
|
|
|
|
2021-01-30 00:24:55 +01:00
|
|
|
public boolean isAll() {
|
2021-06-19 13:27:58 +02:00
|
|
|
checkReleased();
|
2021-04-30 19:15:04 +02:00
|
|
|
assert min == null || min.refCnt() > 0;
|
|
|
|
assert max == null || max.refCnt() > 0;
|
2021-01-30 00:24:55 +01:00
|
|
|
return min == null && max == null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isSingle() {
|
2021-06-19 13:27:58 +02:00
|
|
|
checkReleased();
|
2021-04-30 19:15:04 +02:00
|
|
|
assert min == null || min.refCnt() > 0;
|
|
|
|
assert max == null || max.refCnt() > 0;
|
2021-01-30 00:24:55 +01:00
|
|
|
if (min == null || max == null) return false;
|
2021-04-30 19:15:04 +02:00
|
|
|
return LLUtils.equals(min, max);
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasMin() {
|
2021-06-19 13:27:58 +02:00
|
|
|
checkReleased();
|
2021-04-30 19:15:04 +02:00
|
|
|
assert min == null || min.refCnt() > 0;
|
|
|
|
assert max == null || max.refCnt() > 0;
|
2021-01-30 00:24:55 +01:00
|
|
|
return min != null;
|
|
|
|
}
|
|
|
|
|
2021-04-30 19:15:04 +02:00
|
|
|
public ByteBuf getMin() {
|
2021-06-19 13:27:58 +02:00
|
|
|
checkReleased();
|
2021-04-30 19:15:04 +02:00
|
|
|
assert min == null || min.refCnt() > 0;
|
|
|
|
assert max == null || max.refCnt() > 0;
|
2021-01-30 00:24:55 +01:00
|
|
|
assert min != null;
|
|
|
|
return min;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasMax() {
|
2021-06-19 13:27:58 +02:00
|
|
|
checkReleased();
|
2021-04-30 19:15:04 +02:00
|
|
|
assert min == null || min.refCnt() > 0;
|
|
|
|
assert max == null || max.refCnt() > 0;
|
2021-01-30 00:24:55 +01:00
|
|
|
return max != null;
|
|
|
|
}
|
|
|
|
|
2021-04-30 19:15:04 +02:00
|
|
|
public ByteBuf getMax() {
|
2021-06-19 13:27:58 +02:00
|
|
|
checkReleased();
|
2021-04-30 19:15:04 +02:00
|
|
|
assert min == null || min.refCnt() > 0;
|
|
|
|
assert max == null || max.refCnt() > 0;
|
2021-01-30 00:24:55 +01:00
|
|
|
assert max != null;
|
|
|
|
return max;
|
|
|
|
}
|
|
|
|
|
2021-04-30 19:15:04 +02:00
|
|
|
public ByteBuf getSingle() {
|
2021-06-19 13:27:58 +02:00
|
|
|
checkReleased();
|
2021-04-30 19:15:04 +02:00
|
|
|
assert min == null || min.refCnt() > 0;
|
|
|
|
assert max == null || max.refCnt() > 0;
|
2021-01-30 00:24:55 +01:00
|
|
|
assert isSingle();
|
|
|
|
return min;
|
|
|
|
}
|
|
|
|
|
2021-06-19 13:27:58 +02:00
|
|
|
private void checkReleased() {
|
|
|
|
if (refCnt.get() <= 0) {
|
|
|
|
throw new IllegalStateException("Released");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
|
|
public LLRange retain() {
|
2021-06-19 13:27:58 +02:00
|
|
|
if (refCnt.updateAndGet(refCnt -> refCnt <= 0 ? 0 : (refCnt + 1)) <= 0) {
|
2021-06-19 12:14:14 +02:00
|
|
|
throw new IllegalStateException("Released");
|
|
|
|
}
|
2021-04-30 19:15:04 +02:00
|
|
|
if (min != null) {
|
|
|
|
min.retain();
|
|
|
|
}
|
|
|
|
if (max != null) {
|
|
|
|
max.retain();
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void release() {
|
2021-06-19 13:27:58 +02:00
|
|
|
if (refCnt.decrementAndGet() < 0) {
|
2021-06-19 12:14:14 +02:00
|
|
|
throw new IllegalStateException("Already released");
|
|
|
|
}
|
2021-04-30 19:15:04 +02:00
|
|
|
if (min != null) {
|
|
|
|
min.release();
|
|
|
|
}
|
|
|
|
if (max != null) {
|
|
|
|
max.release();
|
|
|
|
}
|
|
|
|
}
|
2021-01-30 00:24:55 +01:00
|
|
|
}
|