summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2019-10-05 16:24:42 -0400
committertoasted-nutbread <toasted-nutbread@users.noreply.github.com>2019-10-05 18:28:30 -0400
commit50a47348a7a040d1bcaf0a12a38cca049dc207f7 (patch)
treede61259ab82a7a681bd7716970e0d2d80aa5c286
parent30263c3db84714a01e516c1f56225b423f5c8612 (diff)
Optimize internal data structure used by the Deinflector class
-rw-r--r--ext/bg/js/deinflector.js73
-rw-r--r--ext/bg/js/translator.js17
2 files changed, 51 insertions, 39 deletions
diff --git a/ext/bg/js/deinflector.js b/ext/bg/js/deinflector.js
index ad77895c..ce4b2961 100644
--- a/ext/bg/js/deinflector.js
+++ b/ext/bg/js/deinflector.js
@@ -19,51 +19,74 @@
class Deinflector {
constructor(reasons) {
- this.reasons = reasons;
+ this.reasons = Deinflector.normalizeReasons(reasons);
}
deinflect(source) {
const results = [{
source,
term: source,
- rules: [],
+ rules: 0,
definitions: [],
reasons: []
}];
for (let i = 0; i < results.length; ++i) {
- const entry = results[i];
-
- for (const reason in this.reasons) {
- for (const variant of this.reasons[reason]) {
- let accept = entry.rules.length === 0;
- if (!accept) {
- for (const rule of entry.rules) {
- if (variant.rulesIn.includes(rule)) {
- accept = true;
- break;
- }
- }
- }
-
- if (!accept || !entry.term.endsWith(variant.kanaIn)) {
- continue;
- }
-
- const term = entry.term.slice(0, -variant.kanaIn.length) + variant.kanaOut;
- if (term.length === 0) {
+ const {rules, term, reasons} = results[i];
+ for (const [reason, variants] of this.reasons) {
+ for (const [kanaIn, kanaOut, rulesIn, rulesOut] of variants) {
+ if (
+ (rules !== 0 && (rules & rulesIn) === 0) ||
+ !term.endsWith(kanaIn) ||
+ (term.length - kanaIn.length + kanaOut.length) <= 0
+ ) {
continue;
}
results.push({
source,
- term,
- rules: variant.rulesOut,
+ term: term.slice(0, -kanaIn.length) + kanaOut,
+ rules: rulesOut,
definitions: [],
- reasons: [reason, ...entry.reasons]
+ reasons: [reason, ...reasons]
});
}
}
}
return results;
}
+
+ static normalizeReasons(reasons) {
+ const normalizedReasons = [];
+ for (const reason in reasons) {
+ const variants = [];
+ for (const {kanaIn, kanaOut, rulesIn, rulesOut} of reasons[reason]) {
+ variants.push([
+ kanaIn,
+ kanaOut,
+ Deinflector.rulesToRuleFlags(rulesIn),
+ Deinflector.rulesToRuleFlags(rulesOut)
+ ]);
+ }
+ normalizedReasons.push([reason, variants]);
+ }
+ return normalizedReasons;
+ }
+
+ static rulesToRuleFlags(rules) {
+ const ruleTypes = Deinflector.ruleTypes;
+ let value = 0;
+ for (const rule of rules) {
+ value |= ruleTypes[rule];
+ }
+ return value;
+ }
}
+
+Deinflector.ruleTypes = {
+ 'v1': 0b0000001, // Verb ichidan
+ 'v5': 0b0000010, // Verb godan
+ 'vs': 0b0000100, // Verb suru
+ 'vk': 0b0001000, // Verb kuru
+ 'adj-i': 0b0010000, // Adjective i
+ 'iru': 0b0100000, // Intermediate -iru endings for progressive or perfect tense
+};
diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js
index 65d746ea..601ee30c 100644
--- a/ext/bg/js/translator.js
+++ b/ext/bg/js/translator.js
@@ -238,8 +238,10 @@ class Translator {
const definitions = await this.database.findTermsBulk(uniqueDeinflectionTerms, titles);
for (const definition of definitions) {
+ const definitionRules = Deinflector.rulesToRuleFlags(definition.rules);
for (const deinflection of uniqueDeinflectionArrays[definition.index]) {
- if (Translator.definitionContainsAnyRule(definition, deinflection.rules)) {
+ const deinflectionRules = deinflection.rules;
+ if (deinflectionRules === 0 || (definitionRules & deinflectionRules) !== 0) {
deinflection.definitions.push(definition);
}
}
@@ -248,19 +250,6 @@ class Translator {
return deinflections.filter(e => e.definitions.length > 0);
}
- static definitionContainsAnyRule(definition, rules) {
- if (rules.length === 0) {
- return true;
- }
- const definitionRules = definition.rules;
- for (const rule of rules) {
- if (definitionRules.includes(rule)) {
- return true;
- }
- }
- return false;
- }
-
getDeinflections(text) {
const deinflections = [];