OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/prefs/json_pref_store.h" | 5 #include "base/prefs/json_pref_store.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/files/file_util.h" | 12 #include "base/files/file_util.h" |
13 #include "base/json/json_file_value_serializer.h" | 13 #include "base/json/json_file_value_serializer.h" |
14 #include "base/json/json_string_value_serializer.h" | 14 #include "base/json/json_string_value_serializer.h" |
15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
17 #include "base/prefs/pref_filter.h" | 17 #include "base/prefs/pref_filter.h" |
18 #include "base/sequenced_task_runner.h" | 18 #include "base/sequenced_task_runner.h" |
19 #include "base/strings/string_number_conversions.h" | |
19 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
20 #include "base/task_runner_util.h" | 21 #include "base/task_runner_util.h" |
21 #include "base/threading/sequenced_worker_pool.h" | 22 #include "base/threading/sequenced_worker_pool.h" |
22 #include "base/values.h" | 23 #include "base/values.h" |
23 | 24 |
24 // Result returned from internal read tasks. | 25 // Result returned from internal read tasks. |
25 struct JsonPrefStore::ReadResult { | 26 struct JsonPrefStore::ReadResult { |
26 public: | 27 public: |
27 ReadResult(); | 28 ReadResult(); |
28 ~ReadResult(); | 29 ~ReadResult(); |
29 | 30 |
30 scoped_ptr<base::Value> value; | 31 scoped_ptr<base::Value> value; |
31 PrefReadError error; | 32 PrefReadError error; |
32 bool no_dir; | 33 bool no_dir; |
33 | 34 |
34 private: | 35 private: |
35 DISALLOW_COPY_AND_ASSIGN(ReadResult); | 36 DISALLOW_COPY_AND_ASSIGN(ReadResult); |
36 }; | 37 }; |
37 | 38 |
38 JsonPrefStore::ReadResult::ReadResult() | 39 JsonPrefStore::ReadResult::ReadResult() |
39 : error(PersistentPrefStore::PREF_READ_ERROR_NONE), no_dir(false) { | 40 : error(PersistentPrefStore::PREF_READ_ERROR_NONE), no_dir(false) { |
40 } | 41 } |
41 | 42 |
42 JsonPrefStore::ReadResult::~ReadResult() { | 43 JsonPrefStore::ReadResult::~ReadResult() { |
43 } | 44 } |
44 | 45 |
46 class JsonPrefStore::WriteCountHistogram { | |
47 public: | |
48 WriteCountHistogram(const base::TimeDelta& commit_interval, | |
49 const base::TimeDelta& report_interval, | |
50 const base::FilePath& path); | |
51 ~WriteCountHistogram(); | |
52 | |
53 void RecordWriteOccured(); | |
54 | |
55 private: | |
56 base::HistogramBase* GetHistogram(); | |
57 | |
58 // The minimum interval at which writes can occur. | |
59 const base::TimeDelta commit_interval_; | |
60 | |
61 // The interval at which to report write counts. | |
62 const base::TimeDelta report_interval_; | |
63 | |
64 // The path to the file. | |
65 const base::FilePath path_; | |
66 | |
67 // The time at which the last histogram value was reported for the number | |
68 // of write counts. | |
69 base::Time last_report_time_; | |
70 | |
71 // The number of writes that have occured since the last write count was | |
72 // reported. | |
73 uint32_t writes_since_last_report_; | |
74 | |
75 DISALLOW_COPY_AND_ASSIGN(WriteCountHistogram); | |
76 }; | |
77 | |
45 namespace { | 78 namespace { |
46 | 79 |
80 const int32 kHistogramWriteReportIntervalInMins = 5; | |
81 | |
47 // Some extensions we'll tack on to copies of the Preferences files. | 82 // Some extensions we'll tack on to copies of the Preferences files. |
48 const base::FilePath::CharType kBadExtension[] = FILE_PATH_LITERAL("bad"); | 83 const base::FilePath::CharType kBadExtension[] = FILE_PATH_LITERAL("bad"); |
49 | 84 |
50 PersistentPrefStore::PrefReadError HandleReadErrors( | 85 PersistentPrefStore::PrefReadError HandleReadErrors( |
51 const base::Value* value, | 86 const base::Value* value, |
52 const base::FilePath& path, | 87 const base::FilePath& path, |
53 int error_code, | 88 int error_code, |
54 const std::string& error_msg) { | 89 const std::string& error_msg) { |
55 if (!value) { | 90 if (!value) { |
56 DVLOG(1) << "Error while loading JSON file: " << error_msg | 91 DVLOG(1) << "Error while loading JSON file: " << error_msg |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 : path_(filename), | 186 : path_(filename), |
152 sequenced_task_runner_(sequenced_task_runner), | 187 sequenced_task_runner_(sequenced_task_runner), |
153 prefs_(new base::DictionaryValue()), | 188 prefs_(new base::DictionaryValue()), |
154 read_only_(false), | 189 read_only_(false), |
155 writer_(filename, sequenced_task_runner), | 190 writer_(filename, sequenced_task_runner), |
156 pref_filter_(pref_filter.Pass()), | 191 pref_filter_(pref_filter.Pass()), |
157 initialized_(false), | 192 initialized_(false), |
158 filtering_in_progress_(false), | 193 filtering_in_progress_(false), |
159 read_error_(PREF_READ_ERROR_NONE) { | 194 read_error_(PREF_READ_ERROR_NONE) { |
160 DCHECK(!path_.empty()); | 195 DCHECK(!path_.empty()); |
196 | |
197 write_count_histogram_.reset(new WriteCountHistogram( | |
Mattias Nissler (ping if slow)
2015/04/20 09:43:47
looks like there's no good reason to keep this in
| |
198 writer_.commit_interval(), | |
199 base::TimeDelta::FromMinutes(kHistogramWriteReportIntervalInMins), | |
200 path_)); | |
161 } | 201 } |
162 | 202 |
163 JsonPrefStore::JsonPrefStore( | 203 JsonPrefStore::JsonPrefStore( |
164 const base::FilePath& filename, | 204 const base::FilePath& filename, |
165 const base::FilePath& alternate_filename, | 205 const base::FilePath& alternate_filename, |
166 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, | 206 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, |
167 scoped_ptr<PrefFilter> pref_filter) | 207 scoped_ptr<PrefFilter> pref_filter) |
168 : path_(filename), | 208 : path_(filename), |
169 alternate_path_(alternate_filename), | 209 alternate_path_(alternate_filename), |
170 sequenced_task_runner_(sequenced_task_runner), | 210 sequenced_task_runner_(sequenced_task_runner), |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
387 } | 427 } |
388 } | 428 } |
389 | 429 |
390 JsonPrefStore::~JsonPrefStore() { | 430 JsonPrefStore::~JsonPrefStore() { |
391 CommitPendingWrite(); | 431 CommitPendingWrite(); |
392 } | 432 } |
393 | 433 |
394 bool JsonPrefStore::SerializeData(std::string* output) { | 434 bool JsonPrefStore::SerializeData(std::string* output) { |
395 DCHECK(CalledOnValidThread()); | 435 DCHECK(CalledOnValidThread()); |
396 | 436 |
437 write_count_histogram_->RecordWriteOccured(); | |
438 | |
397 if (pref_filter_) | 439 if (pref_filter_) |
398 pref_filter_->FilterSerializeData(prefs_.get()); | 440 pref_filter_->FilterSerializeData(prefs_.get()); |
399 | 441 |
400 JSONStringValueSerializer serializer(output); | 442 JSONStringValueSerializer serializer(output); |
401 // Not pretty-printing prefs shrinks pref file size by ~30%. To obtain | 443 // Not pretty-printing prefs shrinks pref file size by ~30%. To obtain |
402 // readable prefs for debugging purposes, you can dump your prefs into any | 444 // readable prefs for debugging purposes, you can dump your prefs into any |
403 // command-line or online JSON pretty printing tool. | 445 // command-line or online JSON pretty printing tool. |
404 serializer.set_pretty_print(false); | 446 serializer.set_pretty_print(false); |
405 return serializer.Serialize(*prefs_); | 447 return serializer.Serialize(*prefs_); |
406 } | 448 } |
(...skipping 21 matching lines...) Expand all Loading... | |
428 | 470 |
429 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE) | 471 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE) |
430 error_delegate_->OnError(read_error_); | 472 error_delegate_->OnError(read_error_); |
431 | 473 |
432 FOR_EACH_OBSERVER(PrefStore::Observer, | 474 FOR_EACH_OBSERVER(PrefStore::Observer, |
433 observers_, | 475 observers_, |
434 OnInitializationCompleted(true)); | 476 OnInitializationCompleted(true)); |
435 | 477 |
436 return; | 478 return; |
437 } | 479 } |
480 | |
481 JsonPrefStore::WriteCountHistogram::WriteCountHistogram( | |
482 const base::TimeDelta& commit_interval, | |
483 const base::TimeDelta& report_interval, | |
484 const base::FilePath& path) | |
485 : commit_interval_(commit_interval), | |
486 report_interval_(report_interval), | |
487 path_(path), | |
488 last_report_time_(base::Time::Now()), | |
489 writes_since_last_report_(0) { | |
490 } | |
491 | |
492 JsonPrefStore::WriteCountHistogram::~WriteCountHistogram() { | |
493 // Record any outstanding writes before shutdown. | |
494 GetHistogram()->Add(writes_since_last_report_); | |
495 } | |
496 | |
497 void JsonPrefStore::WriteCountHistogram::RecordWriteOccured() { | |
498 base::Time current_time = base::Time::Now(); | |
499 base::TimeDelta time_since_last_report = current_time - last_report_time_; | |
500 base::HistogramBase* histogram = GetHistogram(); | |
501 | |
502 // If the time since the last report exceeds the report interval, we report | |
503 // all of the fully elapsed intervals up to the current time. | |
504 while (time_since_last_report > report_interval_) { | |
505 histogram->Add(writes_since_last_report_); | |
506 | |
507 writes_since_last_report_ = 0; | |
508 last_report_time_ += report_interval_; | |
509 time_since_last_report = current_time - last_report_time_; | |
510 } | |
511 | |
512 writes_since_last_report_++; | |
513 } | |
514 | |
515 base::HistogramBase* JsonPrefStore::WriteCountHistogram::GetHistogram() { | |
516 std::string spaceless_basename; | |
517 base::ReplaceChars(path_.BaseName().MaybeAsASCII(), " ", "_", | |
518 &spaceless_basename); | |
519 std::string histogram_name = | |
520 "Settings.JsonDataWriteCount." + spaceless_basename; | |
521 | |
522 // The min value for a histogram is 1. The max value is the maximum number of | |
523 // writes that can occur in the window being recorded. The number of buckets | |
524 // used is the max value (plus the underflow/overflow buckets). | |
525 int32_t min_value = 1; | |
526 int32_t max_value = report_interval_ / commit_interval_; | |
527 int32_t num_buckets = max_value + 2; | |
528 | |
529 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS | |
530 // macro adapted to allow for a dynamically suffixed histogram name. | |
531 // Note: The factory creates and owns the histogram. | |
532 base::HistogramBase* histogram = base::Histogram::FactoryGet( | |
533 histogram_name, min_value, max_value, num_buckets, | |
534 base::HistogramBase::kUmaTargetedHistogramFlag); | |
535 return histogram; | |
536 } | |
OLD | NEW |