Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up Trace Statistics view calculation #1941

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import memoizeOne from 'memoize-one';
import * as _ from 'lodash';
import DRange from 'drange';
import { Trace, Span } from '../../../types/trace';
Expand All @@ -21,8 +22,37 @@ import colorGenerator from '../../../utils/color-generator';
const serviceName = 'Service Name';
const operationName = 'Operation Name';

function parentChildOfMap(allSpans: Span[]): Record<string, Span[]> {
const parentChildOfMap: Record<string, Span[]> = {};
allSpans.forEach(s => {
if (s.references) {
// Filter for CHILD_OF we don't want to calculate FOLLOWS_FROM (prod-cons)
const parentIDs = s.references.filter(r => r.refType === 'CHILD_OF').map(r => r.spanID);
parentIDs.forEach((pID: string) => {
parentChildOfMap[pID] = parentChildOfMap[pID] || [];
parentChildOfMap[pID].push(s);
});
}
});
return parentChildOfMap;
}

const memoizedParentChildOfMap = memoizeOne(parentChildOfMap);

function getChildOfSpans(parentID: string, allSpans: Span[]): Span[] {
yurishkuro marked this conversation as resolved.
Show resolved Hide resolved
return memoizedParentChildOfMap(allSpans)[parentID] || [];
}

function getChildOfDrange(parentID: string, allSpans: Span[]) {
const childrenDrange = new DRange();
getChildOfSpans(parentID, allSpans).forEach(s => {
// -1 otherwise it will take for each child a micro (incluse,exclusive)
childrenDrange.add(10 * s.startTime, 10 * (s.startTime + Math.max(s.duration, 0)) - 1);
});
return childrenDrange;
}

function computeSelfTime(span: Span, allSpans: Span[]): number {
if (!span.hasChildren) return span.duration;
yurishkuro marked this conversation as resolved.
Show resolved Hide resolved
// We want to represent spans as half-open intervals like [startTime, startTime + duration).
// This way the subtraction preserves the right boundaries. However, DRange treats all
// intervals as inclusive. For example,
Expand All @@ -32,17 +62,10 @@ function computeSelfTime(span: Span, allSpans: Span[]): number {
// We should've ended up with length 9-4=5, but we got 3.
// To work around that, we multiply start/end times by 10 and subtract one from the end.
// So instead of [1-10] we get [10-99]. This makes the intervals work like half-open.
yurishkuro marked this conversation as resolved.
Show resolved Hide resolved
const spanRange = new DRange(10 * span.startTime, 10 * (span.startTime + span.duration) - 1);
// Only keep CHILD_OF spans. FOLLOWS_FROM spans do not block the parent.
const children = allSpans.filter(
each =>
span.childSpanIds.includes(each.spanID) &&
each.references[0].spanID === span.spanID &&
each.references[0].refType === 'CHILD_OF'
if (!span.hasChildren) return span.duration;
const spanRange = new DRange(10 * span.startTime, 10 * (span.startTime + span.duration) - 1).subtract(
getChildOfDrange(span.spanID, allSpans)
maxgaponov marked this conversation as resolved.
Show resolved Hide resolved
);
children.forEach(child => {
spanRange.subtract(10 * child.startTime, 10 * (child.startTime + child.duration) - 1);
});
return Math.round(spanRange.length / 10);
}

Expand Down
Loading