com.yahoo.document.predicate.FeatureRange Maven / Gradle / Ivy
The newest version!
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.document.predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author Simon Thoresen Hult
*/
public class FeatureRange extends PredicateValue {
private String key;
private Long from;
private Long to;
private final List partitions;
private final List edgePartitions;
public FeatureRange(String key) {
this(key, null, null);
}
public FeatureRange(String key, Long from, Long to) {
Objects.requireNonNull(key, "key");
this.key = key;
if (from != null && to != null && from > to) {
throw new IllegalArgumentException("Expected 'to' greater than or equal to " + from + ", got " + to + ".");
}
this.from = from;
this.to = to;
partitions = new ArrayList<>();
edgePartitions = new ArrayList<>();
}
public FeatureRange setKey(String key) {
Objects.requireNonNull(key, "key");
this.key = key;
return this;
}
public String getKey() {
return key;
}
public FeatureRange setFromInclusive(Long from) {
if (from != null && to != null && from > to) {
throw new IllegalArgumentException("Expected 'from' less than or equal to " + to + ", got " + from + ".");
}
this.from = from;
return this;
}
public Long getFromInclusive() {
return from;
}
public FeatureRange setToInclusive(Long to) {
if (from != null && to != null && from > to) {
throw new IllegalArgumentException("Expected 'to' greater than or equal to " + from + ", got " + to + ".");
}
this.to = to;
return this;
}
public Long getToInclusive() {
return to;
}
public void addPartition(RangePartition p) {
if (p instanceof RangeEdgePartition) {
edgePartitions.add((RangeEdgePartition)p);
} else {
partitions.add(p);
}
}
public List getEdgePartitions() {
return edgePartitions;
}
public List getPartitions() {
return partitions;
}
public void clearPartitions() {
partitions.clear();
edgePartitions.clear();
}
@Override
public FeatureRange clone() throws CloneNotSupportedException {
return (FeatureRange)super.clone();
}
@Override
public int hashCode() {
return ((key.hashCode() + (from != null ? from.hashCode() : 0)) * 31 + (to != null ? to.hashCode() : 0)) * 31;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof FeatureRange)) {
return false;
}
FeatureRange rhs = (FeatureRange)obj;
if (!key.equals(rhs.key)) {
return false;
}
if (!Objects.equals(from, rhs.from)) {
return false;
}
if (!Objects.equals(to, rhs.to)) {
return false;
}
return partitions.equals(rhs.partitions) && edgePartitions.equals(rhs.edgePartitions);
}
@Override
protected void appendTo(StringBuilder out) {
appendQuotedTo(key, out);
out.append(" in [");
if (from != null) {
out.append(from);
}
out.append("..");
if (to != null) {
out.append(to);
}
if (!partitions.isEmpty() || !edgePartitions.isEmpty()) {
out.append(" (");
for (RangeEdgePartition p : edgePartitions) {
p.appendTo(out);
out.append(',');
}
for (RangePartition p : partitions) {
p.appendTo(out);
out.append(',');
}
out.deleteCharAt(out.length() - 1); // Remove extra ','
out.append(")");
}
out.append("]");
}
public static FeatureRange buildFromMixedIn(String key, List partitions, int arity) {
Long fromInclusive = null;
Long toInclusive = null;
long from = 0;
long to = 0;
for (String p : partitions) {
String[] parts = p.split(",");
if (parts.length == 1) {
String[] subparts = parts[0].split("=|-");
int offset = subparts.length == 3? 0 : 1;
if (subparts.length < 3 || subparts.length > 4) {
throw new IllegalArgumentException("MIXED_IN range partition must be on the form label=val-val");
}
from = Long.parseLong(subparts[offset + 1]);
to = Long.parseLong(subparts[offset + 2]);
if (parts[0].contains("=-")) {
long tmp = from;
from = -to;
to = -tmp;
}
} else {
if (parts.length != 3) {
throw new IllegalArgumentException("MIXED_IN range edge partition must be on the form label=val,val,payload");
}
long value = Long.parseLong(parts[1]);
long payload = Long.parseLong(parts[2]);
if ((payload & 0xc0000000) == 0x80000000L) {
from = value + (payload & 0xffff);
to = value + arity - 1;
} else if ((payload & 0xc0000000) == 0x40000000L) {
from = value;
to = value + (payload & 0xffff);
} else {
from = value + (payload >> 16);
to = value + (payload & 0xffff);
}
}
if (fromInclusive == null || fromInclusive > from) {
fromInclusive = from;
}
if (toInclusive == null || toInclusive > to) {
toInclusive = to;
}
}
return new FeatureRange(key, fromInclusive, toInclusive);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy