Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: components/translate/core/browser/translate_ranker.cc

Issue 2565873002: [translate] Add translate ranker model loader. (Closed)
Patch Set: Initial CL Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/translate/core/browser/translate_ranker.h" 5 #include "components/translate/core/browser/translate_ranker.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
12 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
13 #include "base/profiler/scoped_tracker.h" 15 #include "base/profiler/scoped_tracker.h"
16 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
15 #include "components/metrics/proto/translate_event.pb.h" 18 #include "components/metrics/proto/translate_event.pb.h"
16 #include "components/translate/core/browser/proto/translate_ranker_model.pb.h" 19 #include "components/translate/core/browser/proto/translate_ranker_model.pb.h"
17 #include "components/translate/core/browser/translate_download_manager.h" 20 #include "components/translate/core/browser/translate_download_manager.h"
18 #include "components/translate/core/browser/translate_prefs.h" 21 #include "components/translate/core/browser/translate_prefs.h"
22 #include "components/translate/core/browser/translate_ranker_model_loader.h"
19 #include "components/translate/core/browser/translate_url_fetcher.h" 23 #include "components/translate/core/browser/translate_url_fetcher.h"
20 #include "components/translate/core/common/translate_switches.h" 24 #include "components/translate/core/common/translate_switches.h"
25 #include "components/variations/variations_associated_data.h"
26
27 #if defined(OS_WIN)
28 #include "base/base_paths_win.h"
29 #include "base/path_service.h"
30 #include "base/strings/utf_string_conversions.h"
31 #elif defined(OS_ANDROID)
32 #include "base/base_paths_android.h"
33 #include "base/path_service.h"
34 #elif defined(OS_LINUX)
35 #include "base/environment.h"
36 #include "base/nix/xdg_util.h"
37 #elif defined(OS_MACOSX)
38 #include "base/base_paths_mac.h"
39 #include "base/path_service.h"
40 #endif
21 41
22 namespace translate { 42 namespace translate {
23 43
24 namespace { 44 namespace {
25 45
46 using chrome_intelligence::TranslateRankerModel;
47
48 const char kUserDataDirSwitch[] = "user-data-dir";
pasko 2016/12/19 14:26:49 this looks like the wrong layer to do it. kUserDat
Roger McFarlane (Chromium) 2017/02/08 23:08:07 I've turned the ranker into a KeyedService and con
49 const char kTranslateRankerModelFileName[] = "Translate Ranker Model";
26 typedef google::protobuf::Map<std::string, float> WeightMap; 50 typedef google::protobuf::Map<std::string, float> WeightMap;
27 51
28 const double kTranslationOfferThreshold = 0.5; 52 const double kTranslationOfferThreshold = 0.5;
29 53
30 // Parameters for model fetching.
31 const char kTranslateRankerModelURL[] =
32 "https://chromium-i18n.appspot.com/ssl-translate-ranker-model";
33 const int kMaxRetryOn5xx = 3;
34 const int kDownloadRefractoryPeriodMin = 15;
35 const char kUnknown[] = "UNKNOWN"; 54 const char kUnknown[] = "UNKNOWN";
36 55
37 // Enumeration denoting the outcome of an attempt to download the translate
38 // ranker model. This must be kept in sync with the TranslateRankerModelStatus
39 // enum in histograms.xml
40 enum ModelStatus {
41 MODEL_STATUS_OK = 0,
42 MODEL_STATUS_DOWNLOAD_THROTTLED = 1,
43 MODEL_STATUS_DOWNLOAD_FAILED = 2,
44 MODEL_STATUS_PARSE_FAILED = 3,
45 MODEL_STATUS_VALIDATION_FAILED = 4,
46 // Insert new values above this line.
47 MODEL_STATUS_MAX
48 };
49
50 double Sigmoid(double x) { 56 double Sigmoid(double x) {
51 return 1.0 / (1.0 + exp(-x)); 57 return 1.0 / (1.0 + exp(-x));
52 } 58 }
53 59
54 double ScoreComponent(const WeightMap& weights, const std::string& key) { 60 double ScoreComponent(const WeightMap& weights, const std::string& key) {
55 WeightMap::const_iterator i = weights.find(base::ToLowerASCII(key)); 61 WeightMap::const_iterator i = weights.find(base::ToLowerASCII(key));
56 if (i == weights.end()) 62 if (i == weights.end())
57 i = weights.find(kUnknown); 63 i = weights.find(kUnknown);
58 return i == weights.end() ? 0.0 : i->second; 64 return i == weights.end() ? 0.0 : i->second;
59 } 65 }
60 66
61 GURL GetTranslateRankerURL() { 67 GURL GetTranslateRankerModelURL() {
68 // Allow override of the ranker model URL from the command line.
62 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 69 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
63 return GURL(command_line->HasSwitch(switches::kTranslateRankerModelURL) 70 if (command_line->HasSwitch(switches::kTranslateRankerModelURL)) {
64 ? command_line->GetSwitchValueASCII( 71 return GURL(
65 switches::kTranslateRankerModelURL) 72 command_line->GetSwitchValueASCII(switches::kTranslateRankerModelURL));
66 : kTranslateRankerModelURL); 73 }
74
75 // Otherwise take the ranker model URL from the ranker query variation.
76 const std::string raw_url = variations::GetVariationParamValueByFeature(
77 kTranslateRankerQuery, switches::kTranslateRankerModelURL);
78
79 DVLOG(3) << switches::kTranslateRankerModelURL << " = " << raw_url;
80
81 return GURL(raw_url);
67 } 82 }
68 83
69 void ReportModelStatus(ModelStatus model_status) { 84 base::FilePath GetUserDataDir() {
70 UMA_HISTOGRAM_ENUMERATION("Translate.Ranker.Model.Status", model_status, 85 base::FilePath path;
71 MODEL_STATUS_MAX); 86 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
87 if (command_line->HasSwitch(kUserDataDirSwitch)) {
88 path = command_line->GetSwitchValuePath(kUserDataDirSwitch);
89 } else {
90 #if defined(OS_WIN)
91 CHECK(PathService::Get(base::DIR_LOCAL_APP_DATA, &path));
92 #elif defined(OS_MACOSX)
93 CHECK(PathService::Get(base::DIR_APP_DATA, &path));
94 #elif defined(OS_ANDROID)
95 CHECK(PathService::Get(base::DIR_ANDROID_APP_DATA, &path));
96 #elif defined(OS_LINUX)
97 std::unique_ptr<base::Environment> env(base::Environment::Create());
98 path = base::nix::GetXDGDirectory(
99 env.get(), base::nix::kXdgConfigHomeEnvVar, base::nix::kDotConfigDir);
100 #else
101 NOTIMPLEMENTED();
102 #endif
103 }
104 return path;
105 }
106
107 base::FilePath GetTranslateRankerModelPath() {
108 // Allow override of the ranker model path from the command line.
109 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
110 if (command_line->HasSwitch(switches::kTranslateRankerModelPath)) {
111 return base::FilePath(command_line->GetSwitchValueNative(
112 switches::kTranslateRankerModelPath));
113 }
114
115 // Otherwise, look for the file in the top-level user data dir.
116 return GetUserDataDir().AppendASCII(kTranslateRankerModelFileName);
117 }
118
119 bool IsUpToDate(const TranslateRankerModel& model) {
120 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
121
122 // When forcibly loading a model from disk, assume it's up-to-date to skip
123 // downloading a new model over it.
124 if (command_line->HasSwitch(switches::kTranslateRankerModelPath))
125 return true;
126
127 // When forcibly download a model, assume that any model loaded from disk
128 // is out-of-date.
129 if (command_line->HasSwitch(switches::kTranslateRankerModelURL))
130 return false;
131
132 // Otherwise take the expected ranker model URL from the ranker query
133 // variation.
134 const std::string& expected_version_str =
135 variations::GetVariationParamValueByFeature(
136 kTranslateRankerQuery, "translate-ranker-model-version");
137
138 DVLOG(2) << "Expected version = '" << expected_version_str << "'";
139 DVLOG(2) << "Received version = '" << model.version() << "'";
140
141 unsigned expected_version;
142 return base::StringToUint(expected_version_str, &expected_version) &&
143 model.has_version() && model.version() == expected_version;
144 }
145
146 bool IsCompatible(const chrome_intelligence::TranslateRankerModel& model) {
147 if (!model.has_logistic_regression_model())
148 return false;
149
150 const TranslateRankerModel::LogisticRegressionModel& logit =
151 model.logistic_regression_model();
152
153 return logit.has_bias() && logit.has_accept_ratio_weight() &&
154 logit.has_decline_ratio_weight();
72 } 155 }
73 156
74 } // namespace 157 } // namespace
75 158
76 const base::Feature kTranslateRankerQuery{"TranslateRankerQuery", 159 const base::Feature kTranslateRankerQuery{"TranslateRankerQuery",
77 base::FEATURE_DISABLED_BY_DEFAULT}; 160 base::FEATURE_DISABLED_BY_DEFAULT};
78 161
79 const base::Feature kTranslateRankerEnforcement{ 162 const base::Feature kTranslateRankerEnforcement{
80 "TranslateRankerEnforcement", base::FEATURE_DISABLED_BY_DEFAULT}; 163 "TranslateRankerEnforcement", base::FEATURE_DISABLED_BY_DEFAULT};
81 164
(...skipping 20 matching lines...) Expand all
102 // static 185 // static
103 bool TranslateRanker::IsEnforcementEnabled() { 186 bool TranslateRanker::IsEnforcementEnabled() {
104 return base::FeatureList::IsEnabled(kTranslateRankerEnforcement); 187 return base::FeatureList::IsEnabled(kTranslateRankerEnforcement);
105 } 188 }
106 189
107 // static 190 // static
108 TranslateRanker* TranslateRanker::GetInstance() { 191 TranslateRanker* TranslateRanker::GetInstance() {
109 return base::Singleton<TranslateRanker>::get(); 192 return base::Singleton<TranslateRanker>::get();
110 } 193 }
111 194
195 // static
112 std::unique_ptr<TranslateRanker> TranslateRanker::CreateForTesting( 196 std::unique_ptr<TranslateRanker> TranslateRanker::CreateForTesting(
113 const std::string& model_data) { 197 const std::string& model_data) {
114 std::unique_ptr<TranslateRanker> ranker(new TranslateRanker()); 198 std::unique_ptr<TranslateRanker> ranker(new TranslateRanker());
199 std::unique_ptr<TranslateRankerModel> model(new TranslateRankerModel());
115 CHECK(ranker != nullptr); 200 CHECK(ranker != nullptr);
116 ranker->ParseModel(0, true, model_data); 201 CHECK(model != nullptr);
117 CHECK(ranker->model_ != nullptr); 202 CHECK(model->ParseFromString(model_data));
203 CHECK(IsCompatible(*model));
204 ranker->SetSharedModelPtr(std::move(model));
118 return ranker; 205 return ranker;
119 } 206 }
120 207
208 void TranslateRanker::StartModelLoader() {
209 if (model_loader_)
210 return;
211
212 base::AutoLock auto_lock(lock_);
213
214 if (model_loader_)
215 return;
216
217 model_loader_.reset(new TranslateRankerModelLoader());
218 model_loader_->set_cache_file_path(GetTranslateRankerModelPath())
219 .set_download_url(GetTranslateRankerModelURL())
220 .set_is_compatible_func(base::BindRepeating(&IsCompatible))
221 .set_is_up_to_date_func(base::BindRepeating(&IsUpToDate))
222 .set_on_model_available_func(base::BindRepeating(
223 &TranslateRanker::SetSharedModelPtr, base::Unretained(this)))
224 .Start();
225 }
226
121 bool TranslateRanker::ShouldOfferTranslation( 227 bool TranslateRanker::ShouldOfferTranslation(
122 const TranslatePrefs& translate_prefs, 228 const TranslatePrefs& translate_prefs,
123 const std::string& src_lang, 229 const std::string& src_lang,
124 const std::string& dst_lang) { 230 const std::string& dst_lang) {
125 // The ranker is a gate in the "show a translation prompt" flow. To retain 231 // The ranker is a gate in the "show a translation prompt" flow. To retain
126 // the pre-existing functionality, it defaults to returning true in the 232 // the pre-existing functionality, it defaults to returning true in the
127 // absence of a model or if enforcement is disabled. As this is ranker is 233 // absence of a model or if enforcement is disabled. As this is ranker is
128 // subsumed into a more general assist ranker, this default will go away 234 // subsumed into a more general assist ranker, this default will go away
129 // (or become False). 235 // (or become False).
130 const bool kDefaultResponse = true; 236 const bool kDefaultResponse = true;
131 237
238 ConstSharedModelPtr model = GetSharedModelPtr();
239
132 // If we don't have a model, request one and return the default. 240 // If we don't have a model, request one and return the default.
133 if (model_ == nullptr) { 241 if (model == nullptr) {
134 FetchModelData();
135 return kDefaultResponse; 242 return kDefaultResponse;
136 } 243 }
137 244
138 DCHECK(model_->has_logistic_regression_model()); 245 DCHECK(IsCompatible(model->data));
139 246
140 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.ShouldOfferTranslation"); 247 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.ShouldOfferTranslation");
141 248
142 // TODO(rogerm): Remove ScopedTracker below once crbug.com/646711 is closed. 249 // TODO(rogerm): Remove ScopedTracker below once crbug.com/646711 is closed.
143 tracked_objects::ScopedTracker tracking_profile( 250 tracked_objects::ScopedTracker tracking_profile(
144 FROM_HERE_WITH_EXPLICIT_FUNCTION( 251 FROM_HERE_WITH_EXPLICIT_FUNCTION(
145 "646711 translate::TranslateRanker::ShouldOfferTranslation")); 252 "646711 translate::TranslateRanker::ShouldOfferTranslation"));
146 253
147 const std::string& app_locale = 254 const std::string& app_locale =
148 TranslateDownloadManager::GetInstance()->application_locale(); 255 TranslateDownloadManager::GetInstance()->application_locale();
149 const std::string& country = translate_prefs.GetCountry(); 256 const std::string& country = translate_prefs.GetCountry();
150 double accept_count = translate_prefs.GetTranslationAcceptedCount(src_lang); 257 double accept_count = translate_prefs.GetTranslationAcceptedCount(src_lang);
151 double denied_count = translate_prefs.GetTranslationDeniedCount(src_lang); 258 double denied_count = translate_prefs.GetTranslationDeniedCount(src_lang);
152 double ignored_count = 259 double ignored_count =
153 model_->logistic_regression_model().has_ignore_ratio_weight() 260 model->data.logistic_regression_model().has_ignore_ratio_weight()
154 ? translate_prefs.GetTranslationIgnoredCount(src_lang) 261 ? translate_prefs.GetTranslationIgnoredCount(src_lang)
155 : 0.0; 262 : 0.0;
156 double total_count = accept_count + denied_count + ignored_count; 263 double total_count = accept_count + denied_count + ignored_count;
157 double accept_ratio = 264 double accept_ratio =
158 (total_count == 0.0) ? 0.0 : (accept_count / total_count); 265 (total_count == 0.0) ? 0.0 : (accept_count / total_count);
159 double decline_ratio = 266 double decline_ratio =
160 (total_count == 0.0) ? 0.0 : (denied_count / total_count); 267 (total_count == 0.0) ? 0.0 : (denied_count / total_count);
161 double ignore_ratio = 268 double ignore_ratio =
162 (total_count == 0.0) ? 0.0 : (ignored_count / total_count); 269 (total_count == 0.0) ? 0.0 : (ignored_count / total_count);
163 DVLOG(3) << "TranslateRanker: features=[" 270 DVLOG(3) << "TranslateRanker: features=["
164 << "src_lang='" << src_lang << "', dst_lang='" << dst_lang 271 << "src_lang='" << src_lang << "', dst_lang='" << dst_lang
165 << "', country='" << country << "', locale='" << app_locale 272 << "', country='" << country << "', locale='" << app_locale
166 << ", accept_count=" << accept_count 273 << ", accept_count=" << accept_count
167 << ", denied_count=" << denied_count 274 << ", denied_count=" << denied_count
168 << ", ignored_count=" << ignored_count 275 << ", ignored_count=" << ignored_count
169 << ", total_count=" << total_count 276 << ", total_count=" << total_count
170 << ", accept_ratio=" << accept_ratio 277 << ", accept_ratio=" << accept_ratio
171 << ", decline_ratio=" << decline_ratio 278 << ", decline_ratio=" << decline_ratio
172 << ", ignore_ratio=" << ignore_ratio << "]"; 279 << ", ignore_ratio=" << ignore_ratio << "]";
173 280
174 double score = CalculateScore(accept_ratio, decline_ratio, ignore_ratio, 281 double score =
175 src_lang, dst_lang, app_locale, country); 282 CalculateScore(model->data, accept_ratio, decline_ratio, ignore_ratio,
283 src_lang, dst_lang, app_locale, country);
176 284
177 DVLOG(2) << "TranslateRanker Score: " << score; 285 DVLOG(2) << "TranslateRanker Score: " << score;
178 286
179 bool result = (score >= kTranslationOfferThreshold); 287 bool result = (score >= kTranslationOfferThreshold);
180 288
181 UMA_HISTOGRAM_BOOLEAN("Translate.Ranker.QueryResult", result); 289 UMA_HISTOGRAM_BOOLEAN("Translate.Ranker.QueryResult", result);
182 290
183 return result; 291 return result;
184 } 292 }
185 293
186 TranslateRanker::TranslateRanker() {} 294 TranslateRanker::TranslateRanker() {}
187 295
188 double TranslateRanker::CalculateScore(double accept_ratio, 296 double TranslateRanker::CalculateScore(const TranslateRankerModel& model,
297 double accept_ratio,
189 double decline_ratio, 298 double decline_ratio,
190 double ignore_ratio, 299 double ignore_ratio,
191 const std::string& src_lang, 300 const std::string& src_lang,
192 const std::string& dst_lang, 301 const std::string& dst_lang,
193 const std::string& locale, 302 const std::string& locale,
194 const std::string& country) { 303 const std::string& country) {
304 DCHECK(IsCompatible(model));
195 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.CalculateScore"); 305 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.CalculateScore");
196 DCHECK(model_ != nullptr);
197 DCHECK(model_->has_logistic_regression_model());
198 const chrome_intelligence::TranslateRankerModel::LogisticRegressionModel& 306 const chrome_intelligence::TranslateRankerModel::LogisticRegressionModel&
199 logit = model_->logistic_regression_model(); 307 logit = model.logistic_regression_model();
200 double dot_product = 308 double dot_product =
201 (accept_ratio * logit.accept_ratio_weight()) + 309 (accept_ratio * logit.accept_ratio_weight()) +
202 (decline_ratio * logit.decline_ratio_weight()) + 310 (decline_ratio * logit.decline_ratio_weight()) +
203 (ignore_ratio * logit.ignore_ratio_weight()) + 311 (ignore_ratio * logit.ignore_ratio_weight()) +
204 ScoreComponent(logit.source_language_weight(), src_lang) + 312 ScoreComponent(logit.source_language_weight(), src_lang) +
205 ScoreComponent(logit.dest_language_weight(), dst_lang) + 313 ScoreComponent(logit.dest_language_weight(), dst_lang) +
206 ScoreComponent(logit.country_weight(), country) + 314 ScoreComponent(logit.country_weight(), country) +
207 ScoreComponent(logit.locale_weight(), locale); 315 ScoreComponent(logit.locale_weight(), locale);
208 return Sigmoid(dot_product + logit.bias()); 316 return Sigmoid(dot_product + logit.bias());
209 } 317 }
210 318
211 int TranslateRanker::GetModelVersion() const { 319 TranslateRanker::ConstSharedModelPtr TranslateRanker::GetSharedModelPtr()
212 return (model_ == nullptr) ? 0 : model_->version(); 320 const {
321 base::AutoLock auto_lock(lock_);
322 return shared_model_ptr_;
213 } 323 }
214 324
215 void TranslateRanker::FetchModelData() { 325 void TranslateRanker::SetSharedModelPtr(
216 // Exit if the model has already been successfully loaded. 326 std::unique_ptr<TranslateRankerModel> new_model) {
217 if (model_ != nullptr) { 327 DCHECK(!new_model || IsCompatible(*new_model));
218 return;
219 }
220 328
221 // Exit if the download has been throttled. 329 // Create a new shared model instance and swap the model contents into it.
222 if (base::Time::NowFromSystemTime() < next_earliest_download_time_) { 330 SharedModelPtr new_shared_model_ptr(
223 return; 331 new base::RefCountedData<TranslateRankerModel>());
224 } 332 new_shared_model_ptr->data.Swap(new_model.get());
225 333
226 // Create the model fetcher if it does not exist. 334 // Grab the lock and update the shared model pointer.
227 if (model_fetcher_ == nullptr) { 335 base::AutoLock auto_lock(lock_);
228 model_fetcher_.reset(new TranslateURLFetcher(kFetcherId)); 336 shared_model_ptr_ = new_shared_model_ptr;
229 model_fetcher_->set_max_retry_on_5xx(kMaxRetryOn5xx);
230 }
231
232 // If a request is already in flight, do not issue a new one.
233 if (model_fetcher_->state() == TranslateURLFetcher::REQUESTING) {
234 DVLOG(2) << "TranslateRanker: Download complete or in progress.";
235 return;
236 }
237
238 DVLOG(2) << "TranslateRanker: Downloading model...";
239
240 download_start_time_ = base::Time::Now();
241 bool result = model_fetcher_->Request(
242 GetTranslateRankerURL(),
243 base::Bind(&TranslateRanker::ParseModel, base::Unretained(this)));
244
245 if (!result) {
246 ReportModelStatus(MODEL_STATUS_DOWNLOAD_THROTTLED);
247 next_earliest_download_time_ =
248 base::Time::NowFromSystemTime() +
249 base::TimeDelta::FromMinutes(kDownloadRefractoryPeriodMin);
250 }
251 } 337 }
252 338
253 void TranslateRanker::ParseModel(int /* id */, 339 int TranslateRanker::GetModelVersion() const {
254 bool success, 340 base::AutoLock auto_lock(lock_);
255 const std::string& data) { 341 return (shared_model_ptr_ == nullptr) ? 0 : shared_model_ptr_->data.version();
256 UMA_HISTOGRAM_MEDIUM_TIMES("Translate.Ranker.Timer.DownloadModel",
257 base::Time::Now() - download_start_time_);
258
259 SCOPED_UMA_HISTOGRAM_TIMER("Translate.Ranker.Timer.ParseModel");
260
261 // We should not be here if the model has already been downloaded and parsed.
262 DCHECK(model_ == nullptr);
263
264 // On failure, we just abort. The TranslateRanker will retry on a subsequent
265 // translation opportunity. The TranslateURLFetcher enforces a limit for
266 // retried requests.
267 if (!success) {
268 ReportModelStatus(MODEL_STATUS_DOWNLOAD_FAILED);
269 return;
270 }
271
272 // Create a new model instance, parse and validate the data, and move it over
273 // to be used by the ranker.
274 std::unique_ptr<chrome_intelligence::TranslateRankerModel> new_model(
275 new chrome_intelligence::TranslateRankerModel());
276
277 bool is_parseable = new_model->ParseFromString(data);
278 if (!is_parseable) {
279 ReportModelStatus(MODEL_STATUS_PARSE_FAILED);
280 return;
281 }
282
283 bool is_valid = new_model->has_logistic_regression_model();
284 if (!is_valid) {
285 ReportModelStatus(MODEL_STATUS_VALIDATION_FAILED);
286 return;
287 }
288
289 ReportModelStatus(MODEL_STATUS_OK);
290 model_ = std::move(new_model);
291 model_fetcher_.reset();
292 } 342 }
293 343
294 void TranslateRanker::FlushTranslateEvents( 344 void TranslateRanker::FlushTranslateEvents(
295 std::vector<metrics::TranslateEventProto>* translate_events) { 345 std::vector<metrics::TranslateEventProto>* translate_events) {
296 if (IsLoggingEnabled()) { 346 if (IsLoggingEnabled()) {
297 translate_events->swap(translate_events_cache_); 347 translate_events->swap(translate_events_cache_);
298 translate_events_cache_.clear(); 348 translate_events_cache_.clear();
299 } 349 }
300 } 350 }
301 351
302 void TranslateRanker::RecordTranslateEvent( 352 void TranslateRanker::RecordTranslateEvent(
303 const metrics::TranslateEventProto& translate_event) { 353 const metrics::TranslateEventProto& translate_event) {
304 if (IsLoggingEnabled()) 354 if (IsLoggingEnabled())
305 translate_events_cache_.push_back(translate_event); 355 translate_events_cache_.push_back(translate_event);
306 } 356 }
307 357
308 } // namespace translate 358 } // namespace translate
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698