diff --git a/src/hooks/useFastSearchFromOptions.ts b/src/hooks/useFastSearchFromOptions.ts index 41f42b7d2649..41bb4f08965e 100644 --- a/src/hooks/useFastSearchFromOptions.ts +++ b/src/hooks/useFastSearchFromOptions.ts @@ -1,8 +1,9 @@ import deburr from 'lodash/deburr'; -import {useMemo} from 'react'; +import {useCallback, useEffect, useState} from 'react'; import FastSearch from '@libs/FastSearch'; -import {filterUserToInvite, isSearchStringMatch} from '@libs/OptionsListUtils'; import type {Options as OptionsListType, ReportAndPersonalDetailOptions} from '@libs/OptionsListUtils'; +import {filterUserToInvite, isSearchStringMatch} from '@libs/OptionsListUtils'; +import type {OptionData} from '@libs/ReportUtils'; import StringUtils from '@libs/StringUtils'; type AllOrSelectiveOptions = ReportAndPersonalDetailOptions | OptionsListType; @@ -34,8 +35,10 @@ function useFastSearchFromOptions( options: ReportAndPersonalDetailOptions | OptionsListType, {includeUserToInvite}: Options = {includeUserToInvite: false}, ): (searchInput: string) => AllOrSelectiveOptions { - const findInSearchTree = useMemo(() => { - const fastSearch = FastSearch.createFastSearch([ + const [fastSearch, setFastSearch] = useState> | null>(null); + + useEffect(() => { + const newFastSearch = FastSearch.createFastSearch([ { data: options.personalDetails, toSearchableString: (option) => { @@ -63,8 +66,16 @@ function useFastSearchFromOptions( }, }, ]); + setFastSearch(newFastSearch); + + return () => newFastSearch.dispose(); + }, [options]); - function search(searchInput: string): AllOrSelectiveOptions { + const findInSearchTree = useCallback( + (searchInput: string): AllOrSelectiveOptions => { + if (!fastSearch) { + return emptyResult; + } const deburredInput = deburr(searchInput); const searchWords = deburredInput.split(/\s+/); const searchWordsSorted = StringUtils.sortStringArrayByLength(searchWords); @@ -104,10 +115,9 @@ function useFastSearchFromOptions( personalDetails, recentReports, }; - } - - return search; - }, [includeUserToInvite, options]); + }, + [includeUserToInvite, options, fastSearch], + ); return findInSearchTree; } diff --git a/src/libs/DynamicArrayBuffer.ts b/src/libs/DynamicArrayBuffer.ts index 750922d432a0..b4a3d2ff6be8 100644 --- a/src/libs/DynamicArrayBuffer.ts +++ b/src/libs/DynamicArrayBuffer.ts @@ -83,6 +83,10 @@ class DynamicArrayBuffer { return this; } + clear(): void { + this.truncate(0); + } + [Symbol.iterator](): Iterator { let index = 0; return { diff --git a/src/libs/FastSearch.ts b/src/libs/FastSearch.ts index e7d5ef051960..30c6640ab5a5 100644 --- a/src/libs/FastSearch.ts +++ b/src/libs/FastSearch.ts @@ -123,9 +123,16 @@ function createFastSearch(dataSets: Array>) { return resultsByDataSet.map((set) => Array.from(set)); } + function dispose(): void { + concatenatedNumericList.clear(); + occurrenceToIndex.clear(); + tree.disposeTree(); + listOffsets.length = 0; + } return { search, + dispose, }; } diff --git a/src/libs/SuffixUkkonenTree/index.ts b/src/libs/SuffixUkkonenTree/index.ts index d12da078dfa9..d6a2df31dc29 100644 --- a/src/libs/SuffixUkkonenTree/index.ts +++ b/src/libs/SuffixUkkonenTree/index.ts @@ -51,14 +51,14 @@ function makeTree(numericSearchValues: DynamicArrayBuffer) { / \ / \ / \ / \ [0,0,0,0, 0,0,0,0, 0,0,0,0, ................. 0,0,0,0] */ - const transitionNodes = new Uint32Array(maxNodes * ALPHABET_SIZE); + let transitionNodes = new Uint32Array(maxNodes * ALPHABET_SIZE); // Storing the range of the original string that each node represents: - const rangeStart = new Uint32Array(maxNodes); - const rangeEnd = new Uint32Array(maxNodes); + let rangeStart = new Uint32Array(maxNodes); + let rangeEnd = new Uint32Array(maxNodes); - const parent = new Uint32Array(maxNodes); - const suffixLink = new Uint32Array(maxNodes); + let parent = new Uint32Array(maxNodes); + let suffixLink = new Uint32Array(maxNodes); let currentNode = 1; let currentPosition = 1; @@ -144,6 +144,13 @@ function makeTree(numericSearchValues: DynamicArrayBuffer) { processCharacter(c); } } + function disposeTree() { + rangeEnd = new Uint32Array(0); + rangeStart = new Uint32Array(0); + transitionNodes = new Uint32Array(0); + parent = new Uint32Array(0); + suffixLink = new Uint32Array(0); + } /** * Returns all occurrences of the given (sub)string in the input string. @@ -196,6 +203,7 @@ function makeTree(numericSearchValues: DynamicArrayBuffer) { return { build, findSubstring, + disposeTree, }; }