|
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';
|
@@ -43,23 +42,53 @@ function getChildOfSpans(parentID: string, allSpans: Span[]): Span[] {
|
43 | 42 | return memoizedParentChildOfMap(allSpans)[parentID] || [];
|
44 | 43 | }
|
45 | 44 |
|
46 |
| -function computeSelfTime(span: Span, allSpans: Span[]): number { |
47 |
| - 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); |
| 45 | +function computeSelfTime(parentSpan: Span, allSpans: Span[]): number { |
| 46 | + if (!parentSpan.hasChildren) return parentSpan.duration; |
| 47 | + |
| 48 | + let parentSpanSelfTime = parentSpan.duration; |
| 49 | + let previousChildEndTime = parentSpan.startTime; |
| 50 | + |
| 51 | + const children = getChildOfSpans(parentSpan.spanID, allSpans).sort((a, b) => a.startTime - b.startTime); |
| 52 | + |
| 53 | + const parentSpanEndTime = parentSpan.startTime + parentSpan.duration; |
| 54 | + |
| 55 | + for (let index = 0; index < children.length; index++) { |
| 56 | + const child = children[index]; |
| 57 | + |
| 58 | + const childEndTime = child.startTime + child.duration; |
| 59 | + const childStartsAfterParentEnded = child.startTime > parentSpanEndTime; |
| 60 | + const childEndsBeforePreviousChild = childEndTime < previousChildEndTime; |
| 61 | + |
| 62 | + // parent |..................| |
| 63 | + // child |.......| - previousChild |
| 64 | + // child |.....| - childEndsBeforePreviousChild is true, skipped |
| 65 | + // child |......| - childStartsAfterParentEnded is true, skipped |
| 66 | + if (childStartsAfterParentEnded || childEndsBeforePreviousChild) { |
| 67 | + continue; |
| 68 | + } |
| 69 | + |
| 70 | + // parent |.....................| |
| 71 | + // child |.......| - previousChild |
| 72 | + // child |.....| - nonOverlappingStartTime is previousChildEndTime |
| 73 | + // child |.....| - nonOverlappingStartTime is child.startTime |
| 74 | + const nonOverlappingStartTime = Math.max(previousChildEndTime, child.startTime); |
| 75 | + const childEndTimeOrParentEndTime = Math.min(parentSpanEndTime, childEndTime); |
| 76 | + |
| 77 | + const nonOverlappingDuration = childEndTimeOrParentEndTime - nonOverlappingStartTime; |
| 78 | + parentSpanSelfTime -= nonOverlappingDuration; |
| 79 | + |
| 80 | + // last span which can be included in self time calculation, because it ends after parent span ends |
| 81 | + // parent |......................| |
| 82 | + // child |.....| - last span included in self time calculation |
| 83 | + // child |.........| - skipped |
| 84 | + if (childEndTimeOrParentEndTime === parentSpanEndTime) { |
| 85 | + break; |
| 86 | + } |
| 87 | + |
| 88 | + previousChildEndTime = childEndTime; |
| 89 | + } |
| 90 | + |
| 91 | + return parentSpanSelfTime; |
63 | 92 | }
|
64 | 93 |
|
65 | 94 | function computeColumnValues(trace: Trace, span: Span, allSpans: Span[], resultValue: StatsPerTag) {
|
|
0 commit comments