public static List <Span> Apply(List <Span> spans) { var root = spans.FirstOrDefault(s => !s.parentId.HasValue); if (root == null) { return(spans); } else { var tree = SpanNode.Create(root, spans); Adjust(tree, null); return(tree.ToSpans()); } }
/** * Recursively adjust the timestamps on the span tree. Root span is the reference point, all * children's timestamps gets adjusted based on that span's timestamps. */ private static void Adjust(SpanNode node, ClockSkew skewFromParent) { // adjust skew for the endpoint brought over from the parent span if (skewFromParent != null) { node.span = AdjustTimestamps(node.span, skewFromParent); } // Is there any skew in the current span? var skew = GetClockSkew(node.span); if (skew != null) { // the current span's skew may be a different endpoint than skewFromParent, adjust again. node.span = AdjustTimestamps(node.span, skew); // propagate skew to any children foreach (SpanNode child in node.children) { Adjust(child, skew); } } }
public static SpanNode Create(Span span, IEnumerable <Span> spans) { SpanNode rootNode = new SpanNode(span); // Initialize nodes representing the trace tree var idToNode = new Dictionary <long, SpanNode>(); foreach (var s in spans) { if (s.parentId.HasValue && s != span) { idToNode.Add(s.id, new SpanNode(s)); } } // Collect the parent-child relationships between all spans. var idToParent = new Dictionary <long, long>(); foreach (var kvp in idToNode) { idToParent.Add(kvp.Key, kvp.Value.span.parentId.Value); } // Materialize the tree using parent - child relationships foreach (var kvp in idToParent) { var node = idToNode[kvp.Key]; SpanNode parent; if (idToNode.TryGetValue(kvp.Value, out parent)) { parent.AddChild(node); } else { rootNode.AddChild(node); } } return(rootNode); }
private void AddChild(SpanNode node) { children.Add(node); }