Chore: uFuzzy 1.0.6 (#64575)

This commit is contained in:
Leon Sorokin 2023-03-10 05:49:02 -06:00 committed by GitHub
parent 3ff380f40f
commit 14251db9ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 61 deletions

View File

@ -271,7 +271,7 @@
"@grafana/schema": "workspace:*", "@grafana/schema": "workspace:*",
"@grafana/ui": "workspace:*", "@grafana/ui": "workspace:*",
"@kusto/monaco-kusto": "5.3.6", "@kusto/monaco-kusto": "5.3.6",
"@leeoniya/ufuzzy": "1.0.2", "@leeoniya/ufuzzy": "1.0.6",
"@lezer/common": "1.0.2", "@lezer/common": "1.0.2",
"@lezer/highlight": "1.1.3", "@lezer/highlight": "1.1.3",
"@lezer/lr": "1.3.3", "@lezer/lr": "1.3.3",

View File

@ -52,7 +52,7 @@
"@grafana/data": "9.5.0-pre", "@grafana/data": "9.5.0-pre",
"@grafana/e2e-selectors": "9.5.0-pre", "@grafana/e2e-selectors": "9.5.0-pre",
"@grafana/schema": "9.5.0-pre", "@grafana/schema": "9.5.0-pre",
"@leeoniya/ufuzzy": "1.0.2", "@leeoniya/ufuzzy": "1.0.6",
"@monaco-editor/react": "4.4.6", "@monaco-editor/react": "4.4.6",
"@popperjs/core": "2.11.6", "@popperjs/core": "2.11.6",
"@react-aria/button": "3.6.1", "@react-aria/button": "3.6.1",

View File

@ -108,7 +108,7 @@ export const filterRules = (
const [idxs, info, order] = ufuzzy.search(namespaceHaystack, namespaceFilter); const [idxs, info, order] = ufuzzy.search(namespaceHaystack, namespaceFilter);
if (info && order) { if (info && order) {
filteredNamespaces = order.map((idx) => filteredNamespaces[info.idx[idx]]); filteredNamespaces = order.map((idx) => filteredNamespaces[info.idx[idx]]);
} else { } else if (idxs) {
filteredNamespaces = idxs.map((idx) => filteredNamespaces[idx]); filteredNamespaces = idxs.map((idx) => filteredNamespaces[idx]);
} }
} }
@ -127,7 +127,7 @@ const reduceNamespaces = (filterState: RulesFilter) => {
const [idxs, info, order] = ufuzzy.search(groupsHaystack, groupNameFilter); const [idxs, info, order] = ufuzzy.search(groupsHaystack, groupNameFilter);
if (info && order) { if (info && order) {
filteredGroups = order.map((idx) => filteredGroups[info.idx[idx]]); filteredGroups = order.map((idx) => filteredGroups[info.idx[idx]]);
} else { } else if (idxs) {
filteredGroups = idxs.map((idx) => filteredGroups[idx]); filteredGroups = idxs.map((idx) => filteredGroups[idx]);
} }
} }
@ -157,7 +157,7 @@ const reduceGroups = (filterState: RulesFilter) => {
const [idxs, info, order] = ufuzzy.search(rulesHaystack, ruleNameQuery); const [idxs, info, order] = ufuzzy.search(rulesHaystack, ruleNameQuery);
if (info && order) { if (info && order) {
filteredRules = order.map((idx) => filteredRules[info.idx[idx]]); filteredRules = order.map((idx) => filteredRules[info.idx[idx]]);
} else { } else if (idxs) {
filteredRules = idxs.map((idx) => filteredRules[idx]); filteredRules = idxs.map((idx) => filteredRules[idx]);
} }
} }

View File

@ -130,7 +130,7 @@ class FullResultCache {
} }
} }
// > 1000 matches (unranked) // > 1000 matches (unranked)
else { else if (idxs) {
for (let i = 0; i < idxs.length; i++) { for (let i = 0; i < idxs.length; i++) {
let haystackIdx = idxs[i]; let haystackIdx = idxs[i];
dst.push(src[haystackIdx]); dst.push(src[haystackIdx]);

View File

@ -2,7 +2,7 @@ import { css } from '@emotion/css';
import uFuzzy from '@leeoniya/ufuzzy'; import uFuzzy from '@leeoniya/ufuzzy';
import debounce from 'debounce-promise'; import debounce from 'debounce-promise';
import { debounce as debounceLodash } from 'lodash'; import { debounce as debounceLodash } from 'lodash';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime'; import { reportInteraction } from '@grafana/runtime';
@ -81,9 +81,24 @@ export const placeholders = {
export const DEFAULT_RESULTS_PER_PAGE = 10; export const DEFAULT_RESULTS_PER_PAGE = 10;
export const MetricEncyclopediaModal = (props: Props) => { const uf = new uFuzzy({
const uf = UseUfuzzy(); intraMode: 1,
intraIns: 1,
intraSub: 1,
intraTrn: 1,
intraDel: 1,
});
function fuzzySearch(haystack: string[], query: string, setter: React.Dispatch<React.SetStateAction<number[]>>) {
// console.log('fuzzySearch');
const idxs = uf.filter(haystack, query);
idxs && setter(idxs);
}
const debouncedFuzzySearch = debounceLodash(fuzzySearch, 300);
export const MetricEncyclopediaModal = (props: Props) => {
const { datasource, isOpen, onClose, onChange, query } = props; const { datasource, isOpen, onClose, onChange, query } = props;
const [variables, setVariables] = useState<Array<SelectableValue<string>>>([]); const [variables, setVariables] = useState<Array<SelectableValue<string>>>([]);
@ -93,7 +108,7 @@ export const MetricEncyclopediaModal = (props: Props) => {
// metric list // metric list
const [metrics, setMetrics] = useState<MetricsData>([]); const [metrics, setMetrics] = useState<MetricsData>([]);
const [hasMetadata, setHasMetadata] = useState<boolean>(true); const [hasMetadata, setHasMetadata] = useState<boolean>(true);
const [haystack, setHaystack] = useState<string[]>([]); const [metaHaystack, setMetaHaystack] = useState<string[]>([]);
const [nameHaystack, setNameHaystack] = useState<string[]>([]); const [nameHaystack, setNameHaystack] = useState<string[]>([]);
const [openTabs, setOpenTabs] = useState<string[]>([]); const [openTabs, setOpenTabs] = useState<string[]>([]);
@ -104,7 +119,7 @@ export const MetricEncyclopediaModal = (props: Props) => {
// filters // filters
const [fuzzySearchQuery, setFuzzySearchQuery] = useState<string>(''); const [fuzzySearchQuery, setFuzzySearchQuery] = useState<string>('');
const [fuzzyMetaSearchResults, setFuzzyMetaSearchResults] = useState<number[]>([]); const [fuzzyMetaSearchResults, setFuzzyMetaSearchResults] = useState<number[]>([]);
const [fuzzyNameSearchResults, setNameFuzzySearchResults] = useState<number[]>([]); const [fuzzyNameSearchResults, setFuzzyNameSearchResults] = useState<number[]>([]);
const [fullMetaSearch, setFullMetaSearch] = useState<boolean>(false); const [fullMetaSearch, setFullMetaSearch] = useState<boolean>(false);
const [excludeNullMetadata, setExcludeNullMetadata] = useState<boolean>(false); const [excludeNullMetadata, setExcludeNullMetadata] = useState<boolean>(false);
const [selectedTypes, setSelectedTypes] = useState<Array<SelectableValue<string>>>([]); const [selectedTypes, setSelectedTypes] = useState<Array<SelectableValue<string>>>([]);
@ -141,14 +156,14 @@ export const MetricEncyclopediaModal = (props: Props) => {
metrics = (await datasource.languageProvider.getLabelValues('__name__')) ?? []; metrics = (await datasource.languageProvider.getLabelValues('__name__')) ?? [];
} }
let haystackData: string[] = []; let haystackMetaData: string[] = [];
let haystackNameData: string[] = []; let haystackNameData: string[] = [];
let metricsData: MetricsData = metrics.map((m) => { let metricsData: MetricsData = metrics.map((m) => {
const type = getMetadataType(m, datasource.languageProvider.metricsMetadata!); const type = getMetadataType(m, datasource.languageProvider.metricsMetadata!);
const description = getMetadataHelp(m, datasource.languageProvider.metricsMetadata!); const description = getMetadataHelp(m, datasource.languageProvider.metricsMetadata!);
// string[] = name + type + description // string[] = name + type + description
haystackData.push(`${m} ${type} ${description}`); haystackMetaData.push(`${m} ${type} ${description}`);
haystackNameData.push(m); haystackNameData.push(m);
return { return {
value: m, value: m,
@ -159,7 +174,7 @@ export const MetricEncyclopediaModal = (props: Props) => {
// setting this by the backend if useBackend is true // setting this by the backend if useBackend is true
setMetrics(metricsData); setMetrics(metricsData);
setHaystack(haystackData); setMetaHaystack(haystackMetaData);
setNameHaystack(haystackNameData); setNameHaystack(haystackNameData);
setVariables( setVariables(
@ -211,27 +226,6 @@ export const MetricEncyclopediaModal = (props: Props) => {
return selectedTypes.length > 0; return selectedTypes.length > 0;
} }
function fuzzySearch(query: string) {
// search either the names or all metadata
// fuzzy search go!
if (fullMetaSearch) {
// considered simply filtering indexes with reduce and includes
// Performance comparison with 13,000 metrics searching metadata
// Fuzzy 6326ms
// Reduce & Includes 5541ms
const metaIdxs = uf.filter(haystack, query.toLowerCase());
setFuzzyMetaSearchResults(metaIdxs);
} else {
const nameIdxs = uf.filter(nameHaystack, query.toLowerCase());
setNameFuzzySearchResults(nameIdxs);
}
}
const debouncedFuzzySearch = debounceLodash((query: string) => {
fuzzySearch(query);
}, 300);
/** /**
* Filter * Filter
* *
@ -367,8 +361,14 @@ export const MetricEncyclopediaModal = (props: Props) => {
setIsLoading(true); setIsLoading(true);
debouncedBackendSearch(value); debouncedBackendSearch(value);
} else { } else {
// do the search on the frontend // search either the names or all metadata
debouncedFuzzySearch(value); // fuzzy search go!
if (fullMetaSearch) {
debouncedFuzzySearch(metaHaystack, value, setFuzzyMetaSearchResults);
} else {
debouncedFuzzySearch(nameHaystack, value, setFuzzyNameSearchResults);
}
} }
setPageNum(1); setPageNum(1);
@ -656,22 +656,6 @@ function alphabetically(ascending: boolean, metadataFilters: boolean) {
}; };
} }
function UseUfuzzy(): uFuzzy {
const ref = useRef<uFuzzy>();
if (!ref.current) {
ref.current = new uFuzzy({
intraMode: 1,
intraIns: 1,
intraSub: 1,
intraTrn: 1,
intraDel: 1,
});
}
return ref.current;
}
const getStyles = (theme: GrafanaTheme2) => { const getStyles = (theme: GrafanaTheme2) => {
return { return {
cardsContainer: css` cardsContainer: css`

View File

@ -92,8 +92,12 @@ const FlameGraph = ({
const foundLabels = new Set<string>(); const foundLabels = new Set<string>();
if (search) { if (search) {
for (let idx of ufuzzy.filter(uniqueLabels, search)) { let idxs = ufuzzy.filter(uniqueLabels, search);
foundLabels.add(uniqueLabels[idx]);
if (idxs) {
for (let idx of idxs) {
foundLabels.add(uniqueLabels[idx]);
}
} }
} }

View File

@ -5351,7 +5351,7 @@ __metadata:
"@grafana/e2e-selectors": 9.5.0-pre "@grafana/e2e-selectors": 9.5.0-pre
"@grafana/schema": 9.5.0-pre "@grafana/schema": 9.5.0-pre
"@grafana/tsconfig": ^1.2.0-rc1 "@grafana/tsconfig": ^1.2.0-rc1
"@leeoniya/ufuzzy": 1.0.2 "@leeoniya/ufuzzy": 1.0.6
"@mdx-js/react": 1.6.22 "@mdx-js/react": 1.6.22
"@monaco-editor/react": 4.4.6 "@monaco-editor/react": 4.4.6
"@popperjs/core": 2.11.6 "@popperjs/core": 2.11.6
@ -6330,10 +6330,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@leeoniya/ufuzzy@npm:1.0.2": "@leeoniya/ufuzzy@npm:1.0.6":
version: 1.0.2 version: 1.0.6
resolution: "@leeoniya/ufuzzy@npm:1.0.2" resolution: "@leeoniya/ufuzzy@npm:1.0.6"
checksum: 5460378a8c32d121b0bc7c8e95cde995316516655528e248051b1bf360cdca0311ef3275de14b802587748231333cee6183c931b3abba26f9e4236ecc4959aa3 checksum: e09672848e094745726331feebe6744d42563ccf160b38796eed4d72105daa052838fdec1944d5b44a27e328fc74a00547d00b894710e2720aa692ed5d3d6e3b
languageName: node languageName: node
linkType: hard linkType: hard
@ -22136,7 +22136,7 @@ __metadata:
"@grafana/tsconfig": ^1.2.0-rc1 "@grafana/tsconfig": ^1.2.0-rc1
"@grafana/ui": "workspace:*" "@grafana/ui": "workspace:*"
"@kusto/monaco-kusto": 5.3.6 "@kusto/monaco-kusto": 5.3.6
"@leeoniya/ufuzzy": 1.0.2 "@leeoniya/ufuzzy": 1.0.6
"@lezer/common": 1.0.2 "@lezer/common": 1.0.2
"@lezer/highlight": 1.1.3 "@lezer/highlight": 1.1.3
"@lezer/lr": 1.3.3 "@lezer/lr": 1.3.3