diff --git a/src/components/modes/treemode/TreeMode.svelte b/src/components/modes/treemode/TreeMode.svelte index c45aaf91..911fcd79 100644 --- a/src/components/modes/treemode/TreeMode.svelte +++ b/src/components/modes/treemode/TreeMode.svelte @@ -25,6 +25,7 @@ import { CONTEXT_MENU_HEIGHT, CONTEXT_MENU_WIDTH, + MAX_SEARCH_RESULTS, SCROLL_DURATION, SEARCH_UPDATE_THROTTLE, SIMPLE_MODAL_OPTIONS, @@ -209,7 +210,7 @@ debug('searching...', searchText) // console.time('search') // TODO: cleanup - const flatResults = search(searchText, json, state) + const flatResults = search(searchText, json, state, MAX_SEARCH_RESULTS) searchResult = updateSearchResult(json, flatResults, searchResult) // console.timeEnd('search') // TODO: cleanup diff --git a/src/logic/search.js b/src/logic/search.js index 5e95eede..ffc9612e 100644 --- a/src/logic/search.js +++ b/src/logic/search.js @@ -112,12 +112,10 @@ export function searchPrevious (searchResult) { } // TODO: comment -export function search (searchText, json, state) { +export function search (searchText, json, state, maxResults = Infinity) { const results = [] const path = [] // we reuse the same Array recursively, this is *much* faster than creating a new path every time - // TODO: implement maxResults - function searchRecursive (searchTextLowerCase, json, state) { if (Array.isArray(json)) { const level = path.length @@ -125,7 +123,12 @@ export function search (searchText, json, state) { for (let i = 0; i < json.length; i++) { path[level] = i + searchRecursive(searchTextLowerCase, json[i], state ? state[i] : undefined) + + if (results.length >= maxResults) { + return + } } path.pop() @@ -140,16 +143,20 @@ export function search (searchText, json, state) { for (const key of keys) { path[level] = key - if (containsCaseInsensitive(key, searchTextLowerCase)) { + if (containsCaseInsensitive(key, searchTextLowerCase) && results.length < maxResults) { results.push(path.concat([STATE_SEARCH_PROPERTY])) } searchRecursive(searchTextLowerCase, json[key], state ? state[key] : undefined) + + if (results.length >= maxResults) { + return + } } path.pop() } else { // type is a value - if (containsCaseInsensitive(json, searchTextLowerCase)) { + if (containsCaseInsensitive(json, searchTextLowerCase) && results.length < maxResults) { results.push(path.concat([STATE_SEARCH_VALUE])) } } diff --git a/src/logic/search.test.js b/src/logic/search.test.js index 3b81a39d..e113d0b7 100644 --- a/src/logic/search.test.js +++ b/src/logic/search.test.js @@ -48,6 +48,18 @@ describe('search', () => { ]) }) + it('should limit search results to the provided max', () => { + const count = 10 + const json = Array(count).fill(42) + + const resultsAll = search('42', json, undefined) + assert.deepStrictEqual(resultsAll.length, count) + + const maxResults = 4 + const results = search('42', json, undefined, maxResults) + assert.deepStrictEqual(results.length, maxResults) + }) + it('should generate recursive search results from flat results', () => { // Based on document: const json = {