CavalliumDBEngine/src/main/java/it/cavallium/dbengine/database/LLRange.java
Andrea Cavalli 92bb13336d Bugfix
2021-06-19 13:27:58 +02:00

164 lines
3.6 KiB
Java

package it.cavallium.dbengine.database;
import static io.netty.buffer.Unpooled.wrappedBuffer;
import static io.netty.buffer.Unpooled.wrappedUnmodifiableBuffer;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import java.util.Arrays;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Range of data, from min (inclusive),to max (exclusive)
*/
public class LLRange {
private static final LLRange RANGE_ALL = new LLRange(null, null);
private final ByteBuf min;
private final ByteBuf max;
private final AtomicInteger refCnt = new AtomicInteger(1);
private LLRange(ByteBuf min, ByteBuf max) {
assert min == null || min.refCnt() > 0;
assert max == null || max.refCnt() > 0;
this.min = min;
this.max = max;
}
public static LLRange all() {
return RANGE_ALL;
}
public static LLRange from(ByteBuf min) {
return new LLRange(min, null);
}
public static LLRange to(ByteBuf max) {
return new LLRange(null, max);
}
public static LLRange single(ByteBuf single) {
try {
return new LLRange(single.retain(), single.retain());
} finally {
single.release();
}
}
public static LLRange of(ByteBuf min, ByteBuf max) {
return new LLRange(min, max);
}
public boolean isAll() {
checkReleased();
assert min == null || min.refCnt() > 0;
assert max == null || max.refCnt() > 0;
return min == null && max == null;
}
public boolean isSingle() {
checkReleased();
assert min == null || min.refCnt() > 0;
assert max == null || max.refCnt() > 0;
if (min == null || max == null) return false;
return LLUtils.equals(min, max);
}
public boolean hasMin() {
checkReleased();
assert min == null || min.refCnt() > 0;
assert max == null || max.refCnt() > 0;
return min != null;
}
public ByteBuf getMin() {
checkReleased();
assert min == null || min.refCnt() > 0;
assert max == null || max.refCnt() > 0;
assert min != null;
return min;
}
public boolean hasMax() {
checkReleased();
assert min == null || min.refCnt() > 0;
assert max == null || max.refCnt() > 0;
return max != null;
}
public ByteBuf getMax() {
checkReleased();
assert min == null || min.refCnt() > 0;
assert max == null || max.refCnt() > 0;
assert max != null;
return max;
}
public ByteBuf getSingle() {
checkReleased();
assert min == null || min.refCnt() > 0;
assert max == null || max.refCnt() > 0;
assert isSingle();
return min;
}
private void checkReleased() {
if (refCnt.get() <= 0) {
throw new IllegalStateException("Released");
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LLRange llRange = (LLRange) o;
return LLUtils.equals(min, llRange.min) && LLUtils.equals(max, llRange.max);
}
@Override
public int hashCode() {
int result = LLUtils.hashCode(min);
result = 31 * result + LLUtils.hashCode(max);
return result;
}
@Override
public String toString() {
return new StringJoiner(", ", LLRange.class.getSimpleName() + "[", "]")
.add("min=" + LLUtils.toString(min))
.add("max=" + LLUtils.toString(max))
.toString();
}
public LLRange retain() {
if (refCnt.updateAndGet(refCnt -> refCnt <= 0 ? 0 : (refCnt + 1)) <= 0) {
throw new IllegalStateException("Released");
}
if (min != null) {
min.retain();
}
if (max != null) {
max.retain();
}
return this;
}
public void release() {
if (refCnt.decrementAndGet() < 0) {
throw new IllegalStateException("Already released");
}
if (min != null) {
min.release();
}
if (max != null) {
max.release();
}
}
}