package com.yammer.telemetry.tracing;
import com.google.common.base.Optional;
import java.math.BigInteger;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Logger;
public class Trace {
private static final Logger LOG = Logger.getLogger(SpanHelper.class.getName());
private final BigInteger traceId;
private final ConcurrentMap<BigInteger, List<SpanData>> childSpans;
private final ConcurrentMap<BigInteger, List<AnnotationData>> annotations;
private SpanData root = null;
public Trace(BigInteger traceId) {
this.traceId = traceId;
this.childSpans = new ConcurrentHashMap<>();
this.annotations = new ConcurrentHashMap<>();
}
public BigInteger getTraceId() {
return traceId;
}
public SpanData getRoot() {
return root;
}
public List<SpanData> getChildren(BigInteger spanId) {
if (spanId == null) {
return Collections.emptyList();
}
return Optional.fromNullable(childSpans.get(spanId)).or(Collections.<SpanData>emptyList());
}
public List<AnnotationData> getAnnotations(BigInteger spanId) {
if (spanId == null) {
return Collections.emptyList();
}
return Optional.fromNullable(annotations.get(spanId)).or(Collections.<AnnotationData>emptyList());
}
public void addSpan(SpanData spanData) {
final Optional<BigInteger> parentSpanId = spanData.getParentSpanId();
if (!parentSpanId.isPresent()) {
this.root = spanData;
} else {
final List<SpanData> newSiblings = new LinkedList<>();
newSiblings.add(spanData);
final List<SpanData> siblings = childSpans.putIfAbsent(parentSpanId.get(), newSiblings);
if (siblings != null) {
siblings.add(spanData);
}
}
for (AnnotationData annotation : spanData.getAnnotations()) {
addAnnotation(spanData.getSpanId(), annotation);
}
}
public void addAnnotation(BigInteger spanId, AnnotationData data) {
final LinkedList<AnnotationData> currentAnnotation = new LinkedList<>();
currentAnnotation.add(data);
List<AnnotationData> previousAnnotations = annotations.putIfAbsent(spanId, currentAnnotation);
if (previousAnnotations != null) {
previousAnnotations.add(data);
}
}
}