From f9411aec64a09d045cfaa81aac698aa582d02858 Mon Sep 17 00:00:00 2001 From: wzv5 Date: Thu, 13 Feb 2025 06:24:10 +0800 Subject: [PATCH] feat(simplifier): cache opencc (#977) --- src/rime/gear/gears_module.cc | 2 +- src/rime/gear/simplifier.cc | 81 ++++++++++++++++++++--------------- src/rime/gear/simplifier.h | 16 ++++--- 3 files changed, 59 insertions(+), 40 deletions(-) diff --git a/src/rime/gear/gears_module.cc b/src/rime/gear/gears_module.cc index a41e1468d5..59679b07cf 100644 --- a/src/rime/gear/gears_module.cc +++ b/src/rime/gear/gears_module.cc @@ -77,7 +77,7 @@ static void rime_gears_initialize() { r.Register("history_translator", new Component); // filters - r.Register("simplifier", new Component); + r.Register("simplifier", new SimplifierComponent); r.Register("uniquifier", new Component); if (!r.Find("charset_filter")) { // allow improved implementation r.Register("charset_filter", new Component); diff --git a/src/rime/gear/simplifier.cc b/src/rime/gear/simplifier.cc index 6109194376..9ef1f1b78d 100644 --- a/src/rime/gear/simplifier.cc +++ b/src/rime/gear/simplifier.cc @@ -156,8 +156,8 @@ class Opencc { // Simplifier -Simplifier::Simplifier(const Ticket& ticket) - : Filter(ticket), TagMatching(ticket) { +Simplifier::Simplifier(const Ticket& ticket, an opencc) + : Filter(ticket), TagMatching(ticket), opencc_(opencc) { if (name_space_ == "filter") { name_space_ = "simplifier"; } @@ -174,7 +174,6 @@ Simplifier::Simplifier(const Ticket& ticket) comment_formatter_.Load(config->GetList(name_space_ + "/comment_format")); config->GetBool(name_space_ + "/random", &random_); config->GetString(name_space_ + "/option_name", &option_name_); - config->GetString(name_space_ + "/opencc_config", &opencc_config_); if (auto types = config->GetList(name_space_ + "/excluded_types")) { for (auto it = types->begin(); it != types->end(); ++it) { if (auto value = As(*it)) { @@ -186,39 +185,11 @@ Simplifier::Simplifier(const Ticket& ticket) if (option_name_.empty()) { option_name_ = "simplification"; // default switcher option } - if (opencc_config_.empty()) { - opencc_config_ = "t2s.json"; // default opencc config file - } if (random_) { srand((unsigned)time(NULL)); } } -void Simplifier::Initialize() { - initialized_ = true; // no retry - path opencc_config_path = path(opencc_config_); - if (opencc_config_path.extension().u8string() == ".ini") { - LOG(ERROR) << "please upgrade opencc_config to an opencc 1.0 config file."; - return; - } - if (opencc_config_path.is_relative()) { - path user_config_path = Service::instance().deployer().user_data_dir; - path shared_config_path = Service::instance().deployer().shared_data_dir; - (user_config_path /= "opencc") /= opencc_config_path; - (shared_config_path /= "opencc") /= opencc_config_path; - if (exists(user_config_path)) { - opencc_config_path = user_config_path; - } else if (exists(shared_config_path)) { - opencc_config_path = shared_config_path; - } - } - try { - opencc_.reset(new Opencc(opencc_config_path)); - } catch (opencc::Exception& e) { - LOG(ERROR) << "Error initializing opencc: " << e.what(); - } -} - class SimplifiedTranslation : public PrefetchTranslation { public: SimplifiedTranslation(an translation, Simplifier* simplifier) @@ -244,9 +215,6 @@ an Simplifier::Apply(an translation, if (!engine_->context()->get_option(option_name_)) { // off return translation; } - if (!initialized_) { - Initialize(); - } if (!opencc_) { return translation; } @@ -317,4 +285,49 @@ bool Simplifier::Convert(const an& original, return success; } +SimplifierComponent::SimplifierComponent() {} + +Simplifier* SimplifierComponent::Create(const Ticket& ticket) { + string name_space = ticket.name_space; + if (name_space == "filter") { + name_space = "simplifier"; + } + string opencc_config; + an opencc; + if (Config* config = ticket.engine->schema()->config()) { + config->GetString(name_space + "/opencc_config", &opencc_config); + } + if (opencc_config.empty()) { + opencc_config = "t2s.json"; // default opencc config file + } + opencc = opencc_map_[opencc_config].lock(); + if (opencc) { + return new Simplifier(ticket, opencc); + } + path opencc_config_path = path(opencc_config); + if (opencc_config_path.extension().u8string() == ".ini") { + LOG(ERROR) << "please upgrade opencc_config to an opencc 1.0 config file."; + return nullptr; + } + if (opencc_config_path.is_relative()) { + path user_config_path = Service::instance().deployer().user_data_dir; + path shared_config_path = Service::instance().deployer().shared_data_dir; + (user_config_path /= "opencc") /= opencc_config_path; + (shared_config_path /= "opencc") /= opencc_config_path; + if (exists(user_config_path)) { + opencc_config_path = user_config_path; + } else if (exists(shared_config_path)) { + opencc_config_path = shared_config_path; + } + } + try { + opencc = New(opencc_config_path); + // 以原始配置中的文件路径作为 key,避免重复查找文件 + opencc_map_[opencc_config] = opencc; + } catch (opencc::Exception& e) { + LOG(ERROR) << "Error initializing opencc: " << e.what(); + } + return new Simplifier(ticket, opencc); +} + } // namespace rime diff --git a/src/rime/gear/simplifier.h b/src/rime/gear/simplifier.h index 703f18e605..ffe8e32841 100644 --- a/src/rime/gear/simplifier.h +++ b/src/rime/gear/simplifier.h @@ -17,7 +17,7 @@ class Opencc; class Simplifier : public Filter, TagMatching { public: - explicit Simplifier(const Ticket& ticket); + Simplifier(const Ticket& ticket, an opencc); virtual an Apply(an translation, CandidateList* candidates); @@ -29,17 +29,14 @@ class Simplifier : public Filter, TagMatching { protected: enum TipsLevel { kTipsNone, kTipsChar, kTipsAll }; - void Initialize(); void PushBack(const an& original, CandidateQueue* result, const string& simplified); - bool initialized_ = false; - the opencc_; + an opencc_; // settings TipsLevel tips_level_ = kTipsNone; string option_name_; - string opencc_config_; set excluded_types_; bool show_in_comment_ = false; bool inherit_comment_ = true; @@ -47,6 +44,15 @@ class Simplifier : public Filter, TagMatching { bool random_ = false; }; +class SimplifierComponent : public Simplifier::Component { + public: + SimplifierComponent(); + Simplifier* Create(const Ticket& ticket); + + private: + hash_map> opencc_map_; +}; + } // namespace rime #endif // RIME_SIMPLIFIER_H_