Skip to content

Commit

Permalink
fix: fix issue where some dictionaries (nl-nl) could cause slow sugge…
Browse files Browse the repository at this point in the history
…stions (#1583)

Using compound words can be very very slow to generate suggestions.
The current Dutch dictionary has compounds turned on. This caused very very slow suggestions to be generated.
  • Loading branch information
Jason3S authored Aug 25, 2021
1 parent 3a2553b commit 8c8d0ee
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
2 changes: 2 additions & 0 deletions packages/cspell-lib/src/Settings/CSpellSettingsServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@ describe('Validate search/load config files', () => {
${s('js-config/cspell-no-export.js')} | ${cfg(s('js-config/cspell-no-export.js'))}
${s('js-config/cspell-bad.js')} | ${cfg(readError(s('js-config/cspell-bad.js')))}
`('ReadRawSettings from $file', async ({ file, expectedConfig }: TestLoadConfig) => {
// js-config/cspell-no-export.js logs a message.
jest.spyOn(console, 'log').mockImplementation(() => undefined);
const searchResult = await readRawSettings(file);
expect(searchResult).toEqual(expectedConfig ? expect.objectContaining(expectedConfig) : undefined);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,56 @@ describe('Verify using multiple dictionaries', () => {
const dictCollection = createCollection(dicts, 'test');
const sugResult = dictCollection.suggest('appletango', 10, CompoundWordsMethod.SEPARATE_WORDS);
const sugs = sugResult.map((a) => a.word);
expect(sugs).toHaveLength(10);
expect(sugs).toContain('apple+mango');
expect(sugs).not.toContain('apple+mango');
expect(sugs).toContain('apple mango');
});

test('checks for compound NONE suggestions', async () => {
// Add "wordsA" twice, once as a compound dictionary and once as a normal dictionary.
const trie = new SpellingDictionaryFromTrie(Trie.Trie.create(wordsA), 'wordsA', {});
trie.options.useCompounds = true;
const dicts = await Promise.all([
trie,
createSpellingDictionary(wordsB, 'wordsB', 'test', undefined),
createSpellingDictionary(wordsA, 'wordsA', 'test', undefined),
createSpellingDictionary(wordsC, 'wordsC', 'test', undefined),
createForbiddenWordsDictionary(['Avocado'], 'flag_words', 'test', undefined),
]);

// cspell:ignore appletango applemango
const dictCollection = createCollection(dicts, 'test');
const sugResult = dictCollection.suggest('applemango', 10, CompoundWordsMethod.NONE);
const sugs = sugResult.map((a) => a.word);
expect(sugs).not.toContain('apple+mango');
expect(sugs).not.toContain('apple mango');
expect(sugs).toContain('apple');
expect(sugs).toContain('mango');
});

test('checks for compound JOIN_WORDS suggestions', async () => {
// Add "wordsA" twice, once as a compound dictionary and once as a normal dictionary.
const trie = new SpellingDictionaryFromTrie(Trie.Trie.create(wordsA), 'wordsA', {});
trie.options.useCompounds = true;
const dicts = await Promise.all([
trie,
createSpellingDictionary(wordsB, 'wordsB', 'test', undefined),
createSpellingDictionary(wordsA, 'wordsA', 'test', undefined),
createSpellingDictionary(wordsC, 'wordsC', 'test', undefined),
createForbiddenWordsDictionary(['Avocado'], 'flag_words', 'test', undefined),
]);

// cspell:ignore appletango applemango
const dictCollection = createCollection(dicts, 'test');
const sugResult = dictCollection.suggest('applemango', 10, CompoundWordsMethod.JOIN_WORDS);
const sugs = sugResult.map((a) => a.word);
expect(sugs).toContain('apple+mango');
expect(sugs).not.toContain('apple mango');
// possible word combinations
expect(sugs).toContain('apple');
expect(sugs).toContain('apple+apple');
expect(sugs).toContain('grape+mango');
});

test('checks for compound suggestions with numbChanges', async () => {
const trie = new SpellingDictionaryFromTrie(Trie.Trie.create(wordsA), 'wordsA', {});
const dicts = await Promise.all([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,9 @@ export class SpellingDictionaryFromTrie implements SpellingDictionary {

public genSuggestions(collector: SuggestionCollector, suggestOptions: SuggestOptions): void {
if (this.options.noSuggest) return;
const { compoundMethod = CompoundWordsMethod.SEPARATE_WORDS } = suggestOptions;
const _compoundMethod = this.options.useCompounds ? CompoundWordsMethod.JOIN_WORDS : compoundMethod;
const _compoundMethod =
suggestOptions.compoundMethod ??
(this.options.useCompounds ? CompoundWordsMethod.JOIN_WORDS : CompoundWordsMethod.NONE);
wordSuggestFormsArray(collector.word).forEach((w) =>
this.trie.genSuggestions(impersonateCollector(collector, w), _compoundMethod)
);
Expand Down

0 comments on commit 8c8d0ee

Please sign in to comment.