mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
datatrails: fix: improve performance of related metrics sort (#82285)
fix: improve performance of related metrics sort
This commit is contained in:
parent
1fe32479d7
commit
cd09c36448
@ -1,5 +1,4 @@
|
||||
import { css } from '@emotion/css';
|
||||
import leven from 'leven';
|
||||
import { debounce } from 'lodash';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
@ -29,6 +28,7 @@ import { MetricCategoryCascader } from './MetricCategory/MetricCategoryCascader'
|
||||
import { MetricScene } from './MetricScene';
|
||||
import { SelectMetricAction } from './SelectMetricAction';
|
||||
import { hideEmptyPreviews } from './hideEmptyPreviews';
|
||||
import { sortRelatedMetrics } from './relatedMetrics';
|
||||
import { getVariablesWithMetricConstant, trailDS, VAR_DATASOURCE, VAR_FILTERS_EXPR, VAR_METRIC_NAMES } from './shared';
|
||||
import { getColorByIndex, getTrailFor } from './utils';
|
||||
|
||||
@ -431,22 +431,6 @@ function getCardPanelFor(metric: string) {
|
||||
.build();
|
||||
}
|
||||
|
||||
// Computes the Levenshtein distance between two strings, twice, once for the first half and once for the whole string.
|
||||
function sortRelatedMetrics(metricList: string[], metric: string) {
|
||||
return metricList.sort((aValue, bValue) => {
|
||||
const aSplit = aValue.split('_');
|
||||
const aHalf = aSplit.slice(0, aSplit.length / 2).join('_');
|
||||
|
||||
const bSplit = bValue.split('_');
|
||||
const bHalf = bSplit.slice(0, bSplit.length / 2).join('_');
|
||||
|
||||
return (
|
||||
(leven(aHalf, metric!) || 0 + (leven(aValue, metric!) || 0)) -
|
||||
(leven(bHalf, metric!) || 0 + (leven(bValue, metric!) || 0))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function getStyles(theme: GrafanaTheme2) {
|
||||
return {
|
||||
container: css({
|
||||
|
42
public/app/features/trails/relatedMetrics.ts
Normal file
42
public/app/features/trails/relatedMetrics.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import leven from 'leven';
|
||||
|
||||
export function sortRelatedMetrics(metricList: string[], metric: string) {
|
||||
return metricList.sort((aValue, bValue) => {
|
||||
const a = getLevenDistances(aValue, metric);
|
||||
const b = getLevenDistances(bValue, metric);
|
||||
|
||||
return a.halfLeven + a.wholeLeven - (b.halfLeven + b.wholeLeven);
|
||||
});
|
||||
}
|
||||
|
||||
type LevenDistances = { halfLeven: number; wholeLeven: number };
|
||||
type TargetToLevenDistances = Map<string, LevenDistances>;
|
||||
|
||||
const metricToTargetLevenDistances = new Map<string, TargetToLevenDistances>();
|
||||
|
||||
// Provides the Levenshtein distance between a metric to be sorted
|
||||
// and a targetMetric compared to which all other metrics are being sorted
|
||||
// There are two distances: once for the first half and once for the whole string.
|
||||
// This operation is not expected to be symmetric; order of parameters matters
|
||||
// since only `metric` is split.
|
||||
function getLevenDistances(metric: string, targetMetric: string) {
|
||||
let targetToDistances: TargetToLevenDistances | undefined = metricToTargetLevenDistances.get(metric);
|
||||
if (!targetToDistances) {
|
||||
targetToDistances = new Map<string, LevenDistances>();
|
||||
metricToTargetLevenDistances.set(metric, targetToDistances);
|
||||
}
|
||||
|
||||
let distances: LevenDistances | undefined = targetToDistances.get(targetMetric);
|
||||
if (!distances) {
|
||||
const metricSplit = metric.split('_');
|
||||
const metricHalf = metricSplit.slice(0, metricSplit.length / 2).join('_');
|
||||
|
||||
const halfLeven = leven(metricHalf, targetMetric!) || 0;
|
||||
const wholeLeven = leven(metric, targetMetric!) || 0;
|
||||
|
||||
distances = { halfLeven, wholeLeven };
|
||||
targetToDistances.set(targetMetric, distances);
|
||||
}
|
||||
|
||||
return distances;
|
||||
}
|
Loading…
Reference in New Issue
Block a user