|
14 | 14 |
|
15 | 15 | import memoizeOne from 'memoize-one';
|
16 | 16 | import _uniq from 'lodash/uniq';
|
17 |
| -import DRange from 'drange'; |
18 | 17 | import { Trace, Span } from '../../../types/trace';
|
19 | 18 | import { ITableSpan } from './types';
|
20 | 19 | import colorGenerator from '../../../utils/color-generator';
|
@@ -45,21 +44,47 @@ function getChildOfSpans(parentID: string, allSpans: Span[]): Span[] {
|
45 | 44 |
|
46 | 45 | function computeSelfTime(span: Span, allSpans: Span[]): number {
|
47 | 46 | if (!span.hasChildren) return span.duration;
|
48 |
| - // We want to represent spans as half-open intervals like [startTime, startTime + duration). |
49 |
| - // This way the subtraction preserves the right boundaries. However, DRange treats all |
50 |
| - // intervals as inclusive. For example, |
51 |
| - // range(1, 10).subtract(4, 8) => range([1, 3], [9-10]) |
52 |
| - // length=(3-1)+(10-9)=2+1=3 |
53 |
| - // In other words, we took an interval of length=10-1=9 and subtracted length=8-4=4. |
54 |
| - // We should've ended up with length 9-4=5, but we got 3. |
55 |
| - // To work around that, we multiply start/end times by 10 and subtract one from the end. |
56 |
| - // So instead of [1-10] we get [10-99]. This makes the intervals work like half-open. |
57 |
| - const spanRange = new DRange(10 * span.startTime, 10 * (span.startTime + span.duration) - 1); |
58 |
| - const children = getChildOfSpans(span.spanID, allSpans); |
59 |
| - children.forEach(child => { |
60 |
| - spanRange.subtract(10 * child.startTime, 10 * (child.startTime + child.duration) - 1); |
61 |
| - }); |
62 |
| - return Math.round(spanRange.length / 10); |
| 47 | + |
| 48 | + let spanSelfTime = span.duration; |
| 49 | + let previousSpanEndTime = span.startTime; |
| 50 | + |
| 51 | + const children = getChildOfSpans(span.spanID, allSpans).sort((a,b) => a.startTime - b.startTime ); |
| 52 | + |
| 53 | + const parentSpanEndTime = span.startTime + span.duration; |
| 54 | + |
| 55 | + for (let index = 0; index < children.length; index++) { |
| 56 | + const child = children[index]; |
| 57 | + |
| 58 | + const spanEndTime = child.startTime + child.duration; |
| 59 | + const spanStartsAfterParentEnded = child.startTime > parentSpanEndTime; |
| 60 | + const spanEndsBeforePreviousSpan = spanEndTime < previousSpanEndTime; |
| 61 | + if (spanStartsAfterParentEnded || spanEndsBeforePreviousSpan) { |
| 62 | + continue; |
| 63 | + } |
| 64 | + |
| 65 | + let nonOverlappingStartTime = child.startTime; |
| 66 | + let nonOverlappingDuration = child.duration; |
| 67 | + |
| 68 | + const spanStartsBeforePreviousSpanEnds = child.startTime < previousSpanEndTime; |
| 69 | + if (spanStartsBeforePreviousSpanEnds) { |
| 70 | + const diff = previousSpanEndTime - child.startTime |
| 71 | + nonOverlappingDuration = child.duration - diff; |
| 72 | + nonOverlappingStartTime = previousSpanEndTime; |
| 73 | + } |
| 74 | + // last span which can be included in self time calculation, because it ends after parent span ends |
| 75 | + else if (spanEndTime > parentSpanEndTime) { |
| 76 | + const diff = spanEndTime - parentSpanEndTime |
| 77 | + |
| 78 | + nonOverlappingDuration = child.duration - diff; |
| 79 | + spanSelfTime -= nonOverlappingDuration |
| 80 | + break; |
| 81 | + } |
| 82 | + |
| 83 | + spanSelfTime -= nonOverlappingDuration |
| 84 | + previousSpanEndTime = nonOverlappingStartTime + nonOverlappingDuration; |
| 85 | + } |
| 86 | + |
| 87 | + return spanSelfTime |
63 | 88 | }
|
64 | 89 |
|
65 | 90 | function computeColumnValues(trace: Trace, span: Span, allSpans: Span[], resultValue: StatsPerTag) {
|
|
0 commit comments