TSElement.java
package redis.clients.jedis.timeseries;
import java.util.Collections;
import java.util.List;
/**
* A single sample of a time series.
* <p>
* A {@code TSElement} carries a timestamp and one or more values. Most queries return one
* value per sample, in which case {@link #getValue()} returns it directly. Queries that
* request multiple aggregators (see
* {@link TSRangeParams#aggregation(AggregationType[], long)}) return one value per
* aggregator per bucket; in that case the values are accessible in declaration order via
* {@link #getValues()} and {@link #getValue()} returns the first value for backward
* compatibility.
*/
public class TSElement {
private final long timestamp;
private final double value;
public TSElement(long timestamp, double value) {
this.timestamp = timestamp;
this.value = value;
}
public long getTimestamp() {
return timestamp;
}
/**
* @return the first value of this sample. Equivalent to {@code getValues().get(0)}.
*/
public double getValue() {
return value;
}
/**
* @return all values of this sample, in the order in which they were returned by the
* server (matching the order of aggregators when the query was issued with
* multiple aggregators)
*/
public List<Double> getValues() {
return Collections.singletonList(value);
}
@Override
public int hashCode() {
// Matches Collections.singletonList(value).hashCode() (= 31 + Double.hashCode(value))
// so a TSElement and a MultiValueTSElement holding the same single value hash alike.
return 31 * Long.hashCode(timestamp) + 31 + Double.hashCode(value);
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof TSElement)) return false;
TSElement other = (TSElement) obj;
if (this.timestamp != other.timestamp) return false;
if (this.getClass() == TSElement.class && other.getClass() == TSElement.class) {
return Double.doubleToLongBits(this.value) == Double.doubleToLongBits(other.value);
}
return this.getValues().equals(other.getValues());
}
@Override
public String toString() {
return "(" + timestamp + ":" + value + ")";
}
/**
* Variant produced by {@link TimeSeriesBuilderFactory} when a query returned more than
* one value per sample (multiple aggregators). Holds the parser's list as-is and is
* never instantiated for single-value samples, so callers can assume
* {@code values.size() >= 2}.
*/
static final class MultiValueTSElement extends TSElement {
private final List<Double> values;
MultiValueTSElement(long timestamp, List<Double> values) {
super(timestamp, values.get(0));
this.values = values;
}
@Override
public List<Double> getValues() {
return values;
}
@Override
public int hashCode() {
if(values.size() == 1) {
return super.hashCode();
}
return 31 * Long.hashCode(getTimestamp()) + values.hashCode();
}
@Override
public String toString() {
return "(" + getTimestamp() + ":" + values + ")";
}
}
}