Chore: uFuzzy 1.0.2 (#62276)

Co-authored-by: joshhunt <josh@trtr.co>
This commit is contained in:
Leon Sorokin 2023-02-02 09:09:48 -06:00 committed by GitHub
parent 1aae808723
commit 4d564f8b0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 63 additions and 66 deletions

View File

@ -272,7 +272,7 @@
"@grafana/schema": "workspace:*",
"@grafana/ui": "workspace:*",
"@kusto/monaco-kusto": "5.3.6",
"@leeoniya/ufuzzy": "0.9.1",
"@leeoniya/ufuzzy": "1.0.2",
"@lezer/common": "1.0.1",
"@lezer/highlight": "1.1.2",
"@lezer/lr": "1.3.1",

View File

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

View File

@ -186,8 +186,8 @@ function useInternalMatches(filtered: ActionImpl[], search: string): Match[] {
return throttledFiltered.map((action) => ({ score: 0, action }));
}
const haystack = throttledFiltered.map((action) =>
[action.name, action.keywords, action.subtitle].join(' ').toLowerCase()
const haystack = throttledFiltered.map(({ name, keywords, subtitle }) =>
`${name} ${keywords ?? ''} ${subtitle ?? ''}`.toLowerCase()
);
const results: Match[] = [];
@ -201,35 +201,27 @@ function useInternalMatches(filtered: ActionImpl[], search: string): Match[] {
const haystackItem = haystack[haystackIndex];
// Use the position of the match as a stand-in for score
const substringPosition = haystackItem.toLowerCase().indexOf(query);
const substringPosition = haystackItem.indexOf(query);
if (substringPosition > -1) {
const score = haystack.length - substringPosition;
const score = substringPosition * -1; // lower position of the match should be a higher priority score
const action = throttledFiltered[haystackIndex];
results.push({ score, action });
}
}
} else {
const allMatchedIndexes = new Set<number>();
const termCount = ufuzzy.split(throttledSearch).length;
const infoThresh = Infinity;
const oooSearch = termCount < 5;
const queryWords = ufuzzy.split(throttledSearch);
const queryPermutations =
queryWords.length < 5 ? uFuzzy.permute(queryWords).map((terms) => terms.join(' ')) : [throttledSearch];
for (const permutedSearchTerm of queryPermutations) {
const indexes = ufuzzy.filter(haystack, permutedSearchTerm);
const info = ufuzzy.info(indexes, haystack, permutedSearchTerm);
const order = ufuzzy.sort(info, haystack, permutedSearchTerm);
const [, info, order] = ufuzzy.search(haystack, throttledSearch, oooSearch, infoThresh);
if (info && order) {
for (let orderIndex = 0; orderIndex < order.length; orderIndex++) {
const actionIndex = order[orderIndex];
if (!allMatchedIndexes.has(actionIndex)) {
allMatchedIndexes.add(actionIndex);
const score = order.length - orderIndex;
const action = throttledFiltered[info.idx[actionIndex]];
results.push({ score, action });
}
const score = order.length - orderIndex;
const action = throttledFiltered[info.idx[actionIndex]];
results.push({ score, action });
}
}
}

View File

@ -116,28 +116,27 @@ class FullResultCache {
// eslint-disable-next-line
const values = allFields.map((v) => [] as any[]); // empty value for each field
// out-of-order terms
const oooIdxs = new Set<number>();
const queryTerms = this.ufuzzy.split(query);
const oooNeedles = uFuzzy.permute(queryTerms).map((terms) => terms.join(' '));
let [idxs, info, order] = this.ufuzzy.search(haystack, query, true);
oooNeedles.forEach((needle) => {
let idxs = this.ufuzzy.filter(haystack, needle);
let info = this.ufuzzy.info(idxs, haystack, needle);
let order = this.ufuzzy.sort(info, haystack, needle);
for (let c = 0; c < allFields.length; c++) {
let src = allFields[c].values.toArray();
let dst = values[c];
for (let i = 0; i < order.length; i++) {
let haystackIdx = info.idx[order[i]];
if (!oooIdxs.has(haystackIdx)) {
oooIdxs.add(haystackIdx);
for (let c = 0; c < allFields.length; c++) {
values[c].push(allFields[c].values.get(haystackIdx));
}
// <= 1000 matches (ranked)
if (info && order) {
for (let i = 0; i < order.length; i++) {
let haystackIdx = info.idx[order[i]];
dst.push(src[haystackIdx]);
}
}
});
// > 1000 matches (unranked)
else {
for (let i = 0; i < idxs.length; i++) {
let haystackIdx = idxs[i];
dst.push(src[haystackIdx]);
}
}
}
// mutates the search object
this.empty.dataFrame.fields.forEach((f, idx) => {

View File

@ -18,7 +18,7 @@
// THIS SOFTWARE.
import { css } from '@emotion/css';
import uFuzzy from '@leeoniya/ufuzzy';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useMeasure } from 'react-use';
import { CoreApp, createTheme, DataFrame, FieldType, getDisplayProcessor } from '@grafana/data';
@ -90,6 +90,26 @@ const FlameGraph = ({
[levels, totalTicks, rangeMin]
);
const [ufuzzy] = useState(() => {
return new uFuzzy();
});
const uniqueLabels = useMemo(() => {
return [...new Set<string>(data.fields.find((f) => f.name === 'label')?.values.toArray())];
}, [data]);
const foundLabels = useMemo(() => {
const foundLabels = new Set<string>();
if (search) {
for (let idx of ufuzzy.filter(uniqueLabels, search)) {
foundLabels.add(uniqueLabels[idx]);
}
}
return foundLabels;
}, [ufuzzy, search, uniqueLabels]);
const render = useCallback(
(pixelsPerTick: number) => {
if (!levels.length) {
@ -113,11 +133,6 @@ const FlameGraph = ({
theme: createTheme() /* theme does not matter for us here */,
});
const ufuzzy = new uFuzzy({
intraMode: 0,
intraIns: 0,
});
for (let levelIndex = 0; levelIndex < levels.length; levelIndex++) {
const level = levels[levelIndex];
// Get all the dimensions of the rectangles for the level. We do this by level instead of per rectangle, because
@ -125,11 +140,11 @@ const FlameGraph = ({
const dimensions = getRectDimensionsForLevel(level, levelIndex, totalTicks, rangeMin, pixelsPerTick, processor);
for (const rect of dimensions) {
// Render each rectangle based on the computed dimensions
renderRect(ctx, rect, totalTicks, rangeMin, rangeMax, search, levelIndex, topLevelIndex, ufuzzy);
renderRect(ctx, rect, totalTicks, rangeMin, rangeMax, search, levelIndex, topLevelIndex, foundLabels);
}
}
},
[levels, wrapperWidth, valueField, totalTicks, rangeMin, rangeMax, search, topLevelIndex]
[levels, wrapperWidth, valueField, totalTicks, rangeMin, rangeMax, search, topLevelIndex, foundLabels]
);
useEffect(() => {

View File

@ -86,7 +86,7 @@ export function renderRect(
query: string,
levelIndex: number,
topLevelIndex: number,
ufuzzy: uFuzzy
foundNames: Set<string>
) {
if (rect.width < HIDE_THRESHOLD) {
return;
@ -101,19 +101,17 @@ export function renderRect(
const l = 65 + 7 * intensity;
const name = rect.label;
const idxs = ufuzzy.filter([name], query);
const queryResult = query && idxs.length > 0;
if (!rect.collapsed) {
ctx.stroke();
if (query) {
ctx.fillStyle = queryResult ? getBarColor(h, l) : colors[55];
ctx.fillStyle = foundNames.has(name) ? getBarColor(h, l) : colors[55];
} else {
ctx.fillStyle = levelIndex > topLevelIndex - 1 ? getBarColor(h, l) : getBarColor(h, l + 15);
}
} else {
ctx.fillStyle = queryResult ? getBarColor(h, l) : colors[55];
ctx.fillStyle = foundNames.has(name) ? getBarColor(h, l) : colors[55];
}
ctx.fill();

View File

@ -5302,7 +5302,7 @@ __metadata:
"@grafana/e2e-selectors": 9.4.0-pre
"@grafana/schema": 9.4.0-pre
"@grafana/tsconfig": ^1.2.0-rc1
"@leeoniya/ufuzzy": 0.9.0
"@leeoniya/ufuzzy": 1.0.2
"@mdx-js/react": 1.6.22
"@monaco-editor/react": 4.4.6
"@popperjs/core": 2.11.6
@ -6246,17 +6246,10 @@ __metadata:
languageName: node
linkType: hard
"@leeoniya/ufuzzy@npm:0.9.0":
version: 0.9.0
resolution: "@leeoniya/ufuzzy@npm:0.9.0"
checksum: ee1b781530b3dbddd44eb0923f576028829209648c7b7283e5981f89527ac029c034d234ac2e98c9c25e99fe1d97e524d1e3ee0a79f5cbb92230d36e9cfa69d5
languageName: node
linkType: hard
"@leeoniya/ufuzzy@npm:0.9.1":
version: 0.9.1
resolution: "@leeoniya/ufuzzy@npm:0.9.1"
checksum: 27750dff2e754ec3729937abce7c36b87917325e934cef7b1bb54a2310fd1e497dcb725397abee8c714f24a84da155120177a93da8f9706eefe32a8a1bb66945
"@leeoniya/ufuzzy@npm:1.0.2":
version: 1.0.2
resolution: "@leeoniya/ufuzzy@npm:1.0.2"
checksum: 5460378a8c32d121b0bc7c8e95cde995316516655528e248051b1bf360cdca0311ef3275de14b802587748231333cee6183c931b3abba26f9e4236ecc4959aa3
languageName: node
linkType: hard
@ -22083,7 +22076,7 @@ __metadata:
"@grafana/tsconfig": ^1.2.0-rc1
"@grafana/ui": "workspace:*"
"@kusto/monaco-kusto": 5.3.6
"@leeoniya/ufuzzy": 0.9.1
"@leeoniya/ufuzzy": 1.0.2
"@lezer/common": 1.0.1
"@lezer/highlight": 1.1.2
"@lezer/lr": 1.3.1