package com.librato.metrics.client;
import java.util.*;
public class TaggedMeasure extends AbstractMeasure {
private double sum;
private long count;
private double min;
private double max;
private List<Tag> tags = new LinkedList<Tag>();
public TaggedMeasure(GaugeMeasure measure) {
super(measure);
if (measure.getValue() != null) {
this.sum = measure.getValue();
this.count = 1;
this.min = sum;
this.max = sum;
} else {
this.sum = measure.getSum();
this.count = measure.getCount();
this.min = measure.getMin();
this.max = measure.getMax();
}
}
public TaggedMeasure(String name, double value, Tag tag, Tag...tags) {
this(name, value, 1, value, value, tag, tags);
}
public TaggedMeasure(String name, double sum, long count, double min, double max, Tag tag, Tag...tags) {
super(name);
this.sum = sum;
this.count = count;
this.min = min;
this.max = max;
addTag(tag);
addTags(tags);
}
public void addTags(Tag... tags) {
for (Tag tag : tags) {
addTag(tag);
}
}
public void addTag(Tag tag) {
String tagName = sanitizeTagName(tag.name);
String tagValue = sanitizeTagValue(tag.value);
this.tags.add(new Tag(tagName, tagValue));
}
private String sanitizeTagValue(String value) {
value = Sanitizer.LAST_PASS.apply(value);
return trimToSize(value, 255);
}
private String sanitizeTagName(String name) {
name = Sanitizer.LAST_PASS.apply(name);
return trimToSize(name, 64);
}
private String trimToSize(String string, int size) {
if (string == null || string.length() <= size) {
return string;
}
return string.substring(0, size);
}
@Override
public Map<String, Object> toMap() {
Map<String, Object> map = super.toMap();
Maps.putIfNotNull(map, "time", epoch);
map.put("sum", sum);
map.put("count", count);
map.put("min", min);
map.put("max", max);
if (!tags.isEmpty()) {
map.put("tags", Tags.toMap(tags));
}
return map;
}
@Override
public boolean isTagged() {
return true;
}
@Override
public boolean isGauge() {
return true;
}
public TaggedMeasure setPeriod(int period) {
this.period = period;
return this;
}
public TaggedMeasure setMetricAttributes(Map<String, Object> attributes) {
this.metricAttributes = attributes;
return this;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("name=").append(name);
sb.append(", epoch=").append(epoch);
sb.append(", tags=").append(tags);
sb.append(", sum=").append(sum);
sb.append(", count=").append(count);
sb.append(", min=").append(min);
sb.append(", max=").append(max);
sb.append('}');
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
TaggedMeasure that = (TaggedMeasure) o;
if (Double.compare(that.sum, sum) != 0) return false;
if (count != that.count) return false;
if (Double.compare(that.min, min) != 0) return false;
if (Double.compare(that.max, max) != 0) return false;
return tags != null ? tags.equals(that.tags) : that.tags == null;
}
@Override
public int hashCode() {
int result;
long temp;
temp = Double.doubleToLongBits(sum);
result = (int) (temp ^ (temp >>> 32));
result = 31 * result + (int) (count ^ (count >>> 32));
temp = Double.doubleToLongBits(min);
result = 31 * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(max);
result = 31 * result + (int) (temp ^ (temp >>> 32));
result = 31 * result + (tags != null ? tags.hashCode() : 0);
return result;
}
}