From 47fe5fa2c60caa68bdb6a174bd0b98c304ab637b Mon Sep 17 00:00:00 2001 From: Jonah <47046556+jwbonner@users.noreply.github.com> Date: Sat, 3 Feb 2024 22:51:22 -0500 Subject: [PATCH] Improve field search algorithm (#117) Switches to Fuse.js, which is faster than the old approach and supports fuzzy matching --- package-lock.json | 16 ++++++++++++++++ package.json | 1 + src/shared/log/LogUtil.ts | 22 +++++++--------------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index bdd2a86b..d3bfb0e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "chart.js": "^4.4.0", "electron": "^26.2.1", "electron-builder": "^24.6.4", + "fuse.js": "^7.0.0", "heatmap.js": "https://github.com/jwbonner/heatmap.js.git", "highlight.js": "^11.9.0", "mathjs": "11.3.0", @@ -2678,6 +2679,15 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "node_modules/fuse.js": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz", + "integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -7129,6 +7139,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "fuse.js": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz", + "integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", diff --git a/package.json b/package.json index da5c90b8..218abaef 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "chart.js": "^4.4.0", "electron": "^26.2.1", "electron-builder": "^24.6.4", + "fuse.js": "^7.0.0", "heatmap.js": "https://github.com/jwbonner/heatmap.js.git", "highlight.js": "^11.9.0", "mathjs": "11.3.0", diff --git a/src/shared/log/LogUtil.ts b/src/shared/log/LogUtil.ts index 346f3079..07629803 100644 --- a/src/shared/log/LogUtil.ts +++ b/src/shared/log/LogUtil.ts @@ -1,3 +1,4 @@ +import Fuse from "fuse.js"; import { Rotation2d, Translation2d } from "../geometry"; import MatchInfo, { MatchType } from "../MatchInfo"; import { convert } from "../units"; @@ -444,23 +445,14 @@ export function mergeMechanismStates(states: MechanismState[]): MechanismState { }; } +const SEARCH_FUSE = new Fuse([] as string[], { findAllMatches: true, ignoreLocation: true }); + export function searchFields(log: Log, query: string): string[] { - if (query.length == 1) return []; - query = query.toLowerCase(); - let fieldStrings = log.getFieldKeys().filter((field) => field.toLowerCase().includes(query)); - let fields = fieldStrings.map((field) => { - return { - string: field, - endDistance: field.length - field.toLowerCase().lastIndexOf(query) - }; - }); - fields.sort((a, b) => a.string.localeCompare(b.string, undefined, { numeric: true })); - fields.sort((a, b) => a.string.length - b.string.length); - fields.sort((a, b) => a.endDistance - b.endDistance); - return fields + if (query.length == 0) return []; + SEARCH_FUSE.setCollection(log.getFieldKeys()); + return SEARCH_FUSE.search(query) .slice(0, MAX_SEARCH_RESULTS) - .map((field) => field.string) - .filter((field) => !log.isGenerated(field)); + .map((field) => field.item); } export function getMatchInfo(log: Log): MatchInfo | null {