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

Side by Side Diff: base/prefs/json_pref_store.cc

Issue 1127963002: Implement lossy pref behavior for JsonPrefStore. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@prefs-fix-flags
Patch Set: Created 5 years, 7 months 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
« no previous file with comments | « base/prefs/json_pref_store.h ('k') | base/prefs/json_pref_store_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 token.append(filename.AsUTF8Unsafe()); 143 token.append(filename.AsUTF8Unsafe());
144 return worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( 144 return worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
145 worker_pool->GetNamedSequenceToken(token), 145 worker_pool->GetNamedSequenceToken(token),
146 base::SequencedWorkerPool::BLOCK_SHUTDOWN); 146 base::SequencedWorkerPool::BLOCK_SHUTDOWN);
147 } 147 }
148 148
149 JsonPrefStore::JsonPrefStore( 149 JsonPrefStore::JsonPrefStore(
150 const base::FilePath& filename, 150 const base::FilePath& filename,
151 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, 151 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
152 scoped_ptr<PrefFilter> pref_filter) 152 scoped_ptr<PrefFilter> pref_filter)
153 : path_(filename), 153 : JsonPrefStore(filename,
154 sequenced_task_runner_(sequenced_task_runner), 154 base::FilePath(),
155 prefs_(new base::DictionaryValue()), 155 sequenced_task_runner,
156 read_only_(false), 156 pref_filter.Pass()) {
157 writer_(filename, sequenced_task_runner),
158 pref_filter_(pref_filter.Pass()),
159 initialized_(false),
160 filtering_in_progress_(false),
161 read_error_(PREF_READ_ERROR_NONE),
162 write_count_histogram_(writer_.commit_interval(), path_) {
163 DCHECK(!path_.empty());
164 } 157 }
165 158
166 JsonPrefStore::JsonPrefStore( 159 JsonPrefStore::JsonPrefStore(
167 const base::FilePath& filename, 160 const base::FilePath& filename,
168 const base::FilePath& alternate_filename, 161 const base::FilePath& alternate_filename,
169 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, 162 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
170 scoped_ptr<PrefFilter> pref_filter) 163 scoped_ptr<PrefFilter> pref_filter)
171 : path_(filename), 164 : path_(filename),
172 alternate_path_(alternate_filename), 165 alternate_path_(alternate_filename),
173 sequenced_task_runner_(sequenced_task_runner), 166 sequenced_task_runner_(sequenced_task_runner),
174 prefs_(new base::DictionaryValue()), 167 prefs_(new base::DictionaryValue()),
175 read_only_(false), 168 read_only_(false),
176 writer_(filename, sequenced_task_runner), 169 writer_(filename, sequenced_task_runner),
177 pref_filter_(pref_filter.Pass()), 170 pref_filter_(pref_filter.Pass()),
178 initialized_(false), 171 initialized_(false),
179 filtering_in_progress_(false), 172 filtering_in_progress_(false),
173 pending_lossy_write_(false),
180 read_error_(PREF_READ_ERROR_NONE), 174 read_error_(PREF_READ_ERROR_NONE),
181 write_count_histogram_(writer_.commit_interval(), path_) { 175 write_count_histogram_(writer_.commit_interval(), path_) {
182 DCHECK(!path_.empty()); 176 DCHECK(!path_.empty());
183 } 177 }
184 178
185 bool JsonPrefStore::GetValue(const std::string& key, 179 bool JsonPrefStore::GetValue(const std::string& key,
186 const base::Value** result) const { 180 const base::Value** result) const {
187 DCHECK(CalledOnValidThread()); 181 DCHECK(CalledOnValidThread());
188 182
189 base::Value* tmp = NULL; 183 base::Value* tmp = NULL;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 base::Value* value, 239 base::Value* value,
246 uint32 flags) { 240 uint32 flags) {
247 DCHECK(CalledOnValidThread()); 241 DCHECK(CalledOnValidThread());
248 242
249 DCHECK(value); 243 DCHECK(value);
250 scoped_ptr<base::Value> new_value(value); 244 scoped_ptr<base::Value> new_value(value);
251 base::Value* old_value = NULL; 245 base::Value* old_value = NULL;
252 prefs_->Get(key, &old_value); 246 prefs_->Get(key, &old_value);
253 if (!old_value || !value->Equals(old_value)) { 247 if (!old_value || !value->Equals(old_value)) {
254 prefs_->Set(key, new_value.release()); 248 prefs_->Set(key, new_value.release());
255 if (!read_only_) 249 ScheduleWrite(flags);
256 writer_.ScheduleWrite(this);
257 } 250 }
258 } 251 }
259 252
260 void JsonPrefStore::RemoveValue(const std::string& key, uint32 flags) { 253 void JsonPrefStore::RemoveValue(const std::string& key, uint32 flags) {
261 DCHECK(CalledOnValidThread()); 254 DCHECK(CalledOnValidThread());
262 255
263 if (prefs_->RemovePath(key, NULL)) 256 if (prefs_->RemovePath(key, NULL))
264 ReportValueChanged(key, flags); 257 ReportValueChanged(key, flags);
265 } 258 }
266 259
267 void JsonPrefStore::RemoveValueSilently(const std::string& key, uint32 flags) { 260 void JsonPrefStore::RemoveValueSilently(const std::string& key, uint32 flags) {
268 DCHECK(CalledOnValidThread()); 261 DCHECK(CalledOnValidThread());
269 262
270 prefs_->RemovePath(key, NULL); 263 prefs_->RemovePath(key, NULL);
271 if (!read_only_) 264 ScheduleWrite(flags);
272 writer_.ScheduleWrite(this);
273 } 265 }
274 266
275 bool JsonPrefStore::ReadOnly() const { 267 bool JsonPrefStore::ReadOnly() const {
276 DCHECK(CalledOnValidThread()); 268 DCHECK(CalledOnValidThread());
277 269
278 return read_only_; 270 return read_only_;
279 } 271 }
280 272
281 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const { 273 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const {
282 DCHECK(CalledOnValidThread()); 274 DCHECK(CalledOnValidThread());
(...skipping 19 matching lines...) Expand all
302 base::PostTaskAndReplyWithResult( 294 base::PostTaskAndReplyWithResult(
303 sequenced_task_runner_.get(), 295 sequenced_task_runner_.get(),
304 FROM_HERE, 296 FROM_HERE,
305 base::Bind(&ReadPrefsFromDisk, path_, alternate_path_), 297 base::Bind(&ReadPrefsFromDisk, path_, alternate_path_),
306 base::Bind(&JsonPrefStore::OnFileRead, AsWeakPtr())); 298 base::Bind(&JsonPrefStore::OnFileRead, AsWeakPtr()));
307 } 299 }
308 300
309 void JsonPrefStore::CommitPendingWrite() { 301 void JsonPrefStore::CommitPendingWrite() {
310 DCHECK(CalledOnValidThread()); 302 DCHECK(CalledOnValidThread());
311 303
304 // Schedule a write for any lossy writes that are outstanding to ensure that
305 // they get flushed when this function is called.
306 if (pending_lossy_write_)
307 writer_.ScheduleWrite(this);
308
312 if (writer_.HasPendingWrite() && !read_only_) 309 if (writer_.HasPendingWrite() && !read_only_)
313 writer_.DoScheduledWrite(); 310 writer_.DoScheduledWrite();
314 } 311 }
315 312
316 void JsonPrefStore::ReportValueChanged(const std::string& key, uint32 flags) { 313 void JsonPrefStore::ReportValueChanged(const std::string& key, uint32 flags) {
317 DCHECK(CalledOnValidThread()); 314 DCHECK(CalledOnValidThread());
318 315
319 if (pref_filter_) 316 if (pref_filter_)
320 pref_filter_->FilterUpdate(key); 317 pref_filter_->FilterUpdate(key);
321 318
322 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); 319 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
323 320
324 if (!read_only_) 321 ScheduleWrite(flags);
325 writer_.ScheduleWrite(this);
326 } 322 }
327 323
328 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback( 324 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback(
329 const base::Closure& on_next_successful_write) { 325 const base::Closure& on_next_successful_write) {
330 DCHECK(CalledOnValidThread()); 326 DCHECK(CalledOnValidThread());
331 327
332 writer_.RegisterOnNextSuccessfulWriteCallback(on_next_successful_write); 328 writer_.RegisterOnNextSuccessfulWriteCallback(on_next_successful_write);
333 } 329 }
334 330
335 void JsonPrefStore::OnFileRead(scoped_ptr<ReadResult> read_result) { 331 void JsonPrefStore::OnFileRead(scoped_ptr<ReadResult> read_result) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 } 390 }
395 } 391 }
396 392
397 JsonPrefStore::~JsonPrefStore() { 393 JsonPrefStore::~JsonPrefStore() {
398 CommitPendingWrite(); 394 CommitPendingWrite();
399 } 395 }
400 396
401 bool JsonPrefStore::SerializeData(std::string* output) { 397 bool JsonPrefStore::SerializeData(std::string* output) {
402 DCHECK(CalledOnValidThread()); 398 DCHECK(CalledOnValidThread());
403 399
400 pending_lossy_write_ = false;
401
404 write_count_histogram_.RecordWriteOccured(); 402 write_count_histogram_.RecordWriteOccured();
405 403
406 if (pref_filter_) 404 if (pref_filter_)
407 pref_filter_->FilterSerializeData(prefs_.get()); 405 pref_filter_->FilterSerializeData(prefs_.get());
408 406
409 JSONStringValueSerializer serializer(output); 407 JSONStringValueSerializer serializer(output);
410 // Not pretty-printing prefs shrinks pref file size by ~30%. To obtain 408 // Not pretty-printing prefs shrinks pref file size by ~30%. To obtain
411 // readable prefs for debugging purposes, you can dump your prefs into any 409 // readable prefs for debugging purposes, you can dump your prefs into any
412 // command-line or online JSON pretty printing tool. 410 // command-line or online JSON pretty printing tool.
413 serializer.set_pretty_print(false); 411 serializer.set_pretty_print(false);
(...skipping 11 matching lines...) Expand all
425 FOR_EACH_OBSERVER(PrefStore::Observer, 423 FOR_EACH_OBSERVER(PrefStore::Observer,
426 observers_, 424 observers_,
427 OnInitializationCompleted(false)); 425 OnInitializationCompleted(false));
428 return; 426 return;
429 } 427 }
430 428
431 prefs_ = prefs.Pass(); 429 prefs_ = prefs.Pass();
432 430
433 initialized_ = true; 431 initialized_ = true;
434 432
435 if (schedule_write && !read_only_) 433 if (schedule_write)
436 writer_.ScheduleWrite(this); 434 ScheduleWrite(DEFAULT_PREF_WRITE_FLAGS);
437 435
438 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE) 436 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE)
439 error_delegate_->OnError(read_error_); 437 error_delegate_->OnError(read_error_);
440 438
441 FOR_EACH_OBSERVER(PrefStore::Observer, 439 FOR_EACH_OBSERVER(PrefStore::Observer,
442 observers_, 440 observers_,
443 OnInitializationCompleted(true)); 441 OnInitializationCompleted(true));
444 442
445 return; 443 return;
446 } 444 }
447 445
446 void JsonPrefStore::ScheduleWrite(uint32 flags) {
447 if (read_only_)
448 return;
449
450 if (flags & LOSSY_PREF_WRITE_FLAG)
451 pending_lossy_write_ = true;
452 else
453 writer_.ScheduleWrite(this);
454 }
455
448 // NOTE: This value should NOT be changed without renaming the histogram 456 // NOTE: This value should NOT be changed without renaming the histogram
449 // otherwise it will create incompatible buckets. 457 // otherwise it will create incompatible buckets.
450 const int32_t 458 const int32_t
451 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins = 5; 459 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins = 5;
452 460
453 JsonPrefStore::WriteCountHistogram::WriteCountHistogram( 461 JsonPrefStore::WriteCountHistogram::WriteCountHistogram(
454 const base::TimeDelta& commit_interval, 462 const base::TimeDelta& commit_interval,
455 const base::FilePath& path) 463 const base::FilePath& path)
456 : WriteCountHistogram(commit_interval, 464 : WriteCountHistogram(commit_interval,
457 path, 465 path,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 DCHECK_EQ(31, num_buckets); 533 DCHECK_EQ(31, num_buckets);
526 534
527 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS 535 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS
528 // macro adapted to allow for a dynamically suffixed histogram name. 536 // macro adapted to allow for a dynamically suffixed histogram name.
529 // Note: The factory creates and owns the histogram. 537 // Note: The factory creates and owns the histogram.
530 base::HistogramBase* histogram = base::Histogram::FactoryGet( 538 base::HistogramBase* histogram = base::Histogram::FactoryGet(
531 histogram_name, min_value, max_value, num_buckets, 539 histogram_name, min_value, max_value, num_buckets,
532 base::HistogramBase::kUmaTargetedHistogramFlag); 540 base::HistogramBase::kUmaTargetedHistogramFlag);
533 return histogram; 541 return histogram;
534 } 542 }
OLDNEW
« no previous file with comments | « base/prefs/json_pref_store.h ('k') | base/prefs/json_pref_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698