187 lines
4.4 KiB
Java
187 lines
4.4 KiB
Java
package it.cavallium.dbengine.database;
|
|
|
|
import it.cavallium.buffer.Buf;
|
|
import it.cavallium.dbengine.database.disk.LiveFileMetadata;
|
|
import java.util.Objects;
|
|
import java.util.StringJoiner;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
/**
|
|
* Range of data, from min (inclusive), to max (exclusive)
|
|
*/
|
|
public class LLRange {
|
|
|
|
private static final LLRange RANGE_ALL = new LLRange( null, null, (Buf) null);
|
|
@Nullable
|
|
private final Buf min;
|
|
@Nullable
|
|
private final Buf max;
|
|
@Nullable
|
|
private final Buf single;
|
|
|
|
private LLRange(@Nullable Buf min, @Nullable Buf max, @Nullable Buf single) {
|
|
assert single == null || (min == null && max == null);
|
|
assert min == null || max == null || min.compareTo(max) <= 0
|
|
: "Minimum buffer is bigger than maximum buffer: " + min + " > " + max;
|
|
this.min = min;
|
|
this.max = max;
|
|
this.single = single;
|
|
}
|
|
|
|
public static LLRange all() {
|
|
return RANGE_ALL;
|
|
}
|
|
|
|
public static LLRange from(Buf min) {
|
|
return new LLRange(min, null, null);
|
|
}
|
|
|
|
public static LLRange to(Buf max) {
|
|
return new LLRange(null, max, null);
|
|
}
|
|
|
|
public static LLRange single(Buf single) {
|
|
return new LLRange(null, null, single);
|
|
}
|
|
|
|
public static LLRange of(Buf min, Buf max) {
|
|
return new LLRange(min, max, null);
|
|
}
|
|
|
|
public static boolean isInside(LLRange rangeSub, LLRange rangeParent) {
|
|
if (rangeParent.isAll()) {
|
|
return true;
|
|
} else if (rangeParent.isSingle()) {
|
|
return Objects.equals(rangeSub, rangeParent);
|
|
} else {
|
|
return ((!rangeParent.hasMin() || (rangeSub.hasMin() && rangeParent.getMin().compareTo(rangeSub.getMin()) <= 0)))
|
|
&& ((!rangeParent.hasMax() || (rangeSub.hasMax() && rangeParent.getMax().compareTo(rangeSub.getMax()) >= 0)));
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
public static LLRange intersect(LLRange rangeA, LLRange rangeB) {
|
|
boolean aEndInclusive = rangeA.isSingle();
|
|
boolean bEndInclusive = rangeB.isSingle();
|
|
Buf min = rangeA.isAll()
|
|
? rangeB.getMin()
|
|
: (rangeB.isAll()
|
|
? rangeA.getMin()
|
|
: (rangeA.getMin().compareTo(rangeB.getMin()) <= 0 ? rangeB.getMin() : rangeA.getMin()));
|
|
int aComparedToB;
|
|
Buf max;
|
|
boolean maxInclusive;
|
|
if (rangeA.isAll()) {
|
|
max = rangeB.getMax();
|
|
maxInclusive = bEndInclusive;
|
|
} else if (rangeB.isAll()) {
|
|
max = rangeA.getMax();
|
|
maxInclusive = aEndInclusive;
|
|
} else if ((aComparedToB = rangeA.getMax().compareTo(rangeB.getMax())) >= 0) {
|
|
max = rangeB.getMax();
|
|
if (aComparedToB == 0) {
|
|
maxInclusive = bEndInclusive && aEndInclusive;
|
|
} else {
|
|
maxInclusive = bEndInclusive;
|
|
}
|
|
} else {
|
|
max = rangeA.getMax();
|
|
maxInclusive = aEndInclusive;
|
|
}
|
|
if (min != null && max != null && min.compareTo(max) >= (maxInclusive ? 1 : 0)) {
|
|
return null;
|
|
} else {
|
|
if (min != null && min.equals(max)) {
|
|
return LLRange.single(min);
|
|
} else {
|
|
return LLRange.of(min, max);
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean isAll() {
|
|
return min == null && max == null && single == null;
|
|
}
|
|
|
|
public boolean isSingle() {
|
|
return single != null;
|
|
}
|
|
|
|
public boolean hasMin() {
|
|
return min != null || single != null;
|
|
}
|
|
|
|
public Buf getMin() {
|
|
// todo: use a read-only copy
|
|
if (min != null) {
|
|
return min;
|
|
} else {
|
|
return single;
|
|
}
|
|
}
|
|
|
|
public boolean hasMax() {
|
|
return max != null || single != null;
|
|
}
|
|
|
|
public Buf getMax() {
|
|
// todo: use a read-only copy
|
|
if (max != null) {
|
|
return max;
|
|
} else {
|
|
return single;
|
|
}
|
|
}
|
|
|
|
public Buf getSingle() {
|
|
assert isSingle();
|
|
// todo: use a read-only copy
|
|
return single;
|
|
}
|
|
|
|
public Buf getSingleUnsafe() {
|
|
assert isSingle();
|
|
return single;
|
|
}
|
|
|
|
@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;
|
|
}
|
|
|
|
@SuppressWarnings("UnnecessaryUnicodeEscape")
|
|
@Override
|
|
public String toString() {
|
|
if (single != null) {
|
|
return "[" + single + "]";
|
|
} else if (min != null && max != null) {
|
|
return "[" + LLUtils.toString(min) + "," + LLUtils.toString(max) + ")";
|
|
} else if (min != null) {
|
|
return "[" + min + ",\u221E)";
|
|
} else if (max != null) {
|
|
return "[\u2205," + max + ")";
|
|
} else {
|
|
return "[\u221E)";
|
|
}
|
|
}
|
|
|
|
public LLRange copy() {
|
|
// todo: use a read-only copy
|
|
return new LLRange(min, max, single);
|
|
}
|
|
}
|