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

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
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)
164 : JsonPrefStore(
165 filename,
166 alternate_filename,
167 sequenced_task_runner,
168 scoped_ptr<base::ImportantFileWriter>(
169 new base::ImportantFileWriterImpl(filename,
170 sequenced_task_runner)),
171 pref_filter.Pass()) {
172 }
173
174 JsonPrefStore::JsonPrefStore(
175 const base::FilePath& filename,
176 const base::FilePath& alternate_filename,
177 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner,
178 scoped_ptr<base::ImportantFileWriter> file_writer,
179 scoped_ptr<PrefFilter> pref_filter)
171 : path_(filename), 180 : path_(filename),
172 alternate_path_(alternate_filename), 181 alternate_path_(alternate_filename),
173 sequenced_task_runner_(sequenced_task_runner), 182 sequenced_task_runner_(sequenced_task_runner),
174 prefs_(new base::DictionaryValue()), 183 prefs_(new base::DictionaryValue()),
175 read_only_(false), 184 read_only_(false),
176 writer_(filename, sequenced_task_runner), 185 writer_(file_writer.Pass()),
177 pref_filter_(pref_filter.Pass()), 186 pref_filter_(pref_filter.Pass()),
178 initialized_(false), 187 initialized_(false),
179 filtering_in_progress_(false), 188 filtering_in_progress_(false),
180 read_error_(PREF_READ_ERROR_NONE), 189 read_error_(PREF_READ_ERROR_NONE),
181 write_count_histogram_(writer_.commit_interval(), path_) { 190 write_count_histogram_(writer_->CommitInterval(), path_) {
182 DCHECK(!path_.empty()); 191 DCHECK(!path_.empty());
183 } 192 }
184 193
185 bool JsonPrefStore::GetValue(const std::string& key, 194 bool JsonPrefStore::GetValue(const std::string& key,
186 const base::Value** result) const { 195 const base::Value** result) const {
187 DCHECK(CalledOnValidThread()); 196 DCHECK(CalledOnValidThread());
188 197
189 base::Value* tmp = NULL; 198 base::Value* tmp = NULL;
190 if (!prefs_->Get(key, &tmp)) 199 if (!prefs_->Get(key, &tmp))
191 return false; 200 return false;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 base::Value* value, 254 base::Value* value,
246 uint32 flags) { 255 uint32 flags) {
247 DCHECK(CalledOnValidThread()); 256 DCHECK(CalledOnValidThread());
248 257
249 DCHECK(value); 258 DCHECK(value);
250 scoped_ptr<base::Value> new_value(value); 259 scoped_ptr<base::Value> new_value(value);
251 base::Value* old_value = NULL; 260 base::Value* old_value = NULL;
252 prefs_->Get(key, &old_value); 261 prefs_->Get(key, &old_value);
253 if (!old_value || !value->Equals(old_value)) { 262 if (!old_value || !value->Equals(old_value)) {
254 prefs_->Set(key, new_value.release()); 263 prefs_->Set(key, new_value.release());
255 if (!read_only_) 264 ScheduleWrite(flags);
256 writer_.ScheduleWrite(this);
257 } 265 }
258 } 266 }
259 267
260 void JsonPrefStore::RemoveValue(const std::string& key, uint32 flags) { 268 void JsonPrefStore::RemoveValue(const std::string& key, uint32 flags) {
261 DCHECK(CalledOnValidThread()); 269 DCHECK(CalledOnValidThread());
262 270
263 if (prefs_->RemovePath(key, NULL)) 271 if (prefs_->RemovePath(key, NULL))
264 ReportValueChanged(key, flags); 272 ReportValueChanged(key, flags);
265 } 273 }
266 274
267 void JsonPrefStore::RemoveValueSilently(const std::string& key, uint32 flags) { 275 void JsonPrefStore::RemoveValueSilently(const std::string& key, uint32 flags) {
268 DCHECK(CalledOnValidThread()); 276 DCHECK(CalledOnValidThread());
269 277
270 prefs_->RemovePath(key, NULL); 278 prefs_->RemovePath(key, NULL);
271 if (!read_only_) 279 ScheduleWrite(flags);
272 writer_.ScheduleWrite(this);
273 } 280 }
274 281
275 bool JsonPrefStore::ReadOnly() const { 282 bool JsonPrefStore::ReadOnly() const {
276 DCHECK(CalledOnValidThread()); 283 DCHECK(CalledOnValidThread());
277 284
278 return read_only_; 285 return read_only_;
279 } 286 }
280 287
281 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const { 288 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const {
282 DCHECK(CalledOnValidThread()); 289 DCHECK(CalledOnValidThread());
(...skipping 19 matching lines...) Expand all
302 base::PostTaskAndReplyWithResult( 309 base::PostTaskAndReplyWithResult(
303 sequenced_task_runner_.get(), 310 sequenced_task_runner_.get(),
304 FROM_HERE, 311 FROM_HERE,
305 base::Bind(&ReadPrefsFromDisk, path_, alternate_path_), 312 base::Bind(&ReadPrefsFromDisk, path_, alternate_path_),
306 base::Bind(&JsonPrefStore::OnFileRead, AsWeakPtr())); 313 base::Bind(&JsonPrefStore::OnFileRead, AsWeakPtr()));
307 } 314 }
308 315
309 void JsonPrefStore::CommitPendingWrite() { 316 void JsonPrefStore::CommitPendingWrite() {
310 DCHECK(CalledOnValidThread()); 317 DCHECK(CalledOnValidThread());
311 318
312 if (writer_.HasPendingWrite() && !read_only_) 319 // Schedule a write for any lossy writes that are outstanding to ensure that
313 writer_.DoScheduledWrite(); 320 // they get flushed when this function is called.
321 if (pending_lossy_write_)
322 writer_->ScheduleWrite(this);
323
324 if (writer_->HasPendingWrite() && !read_only_)
325 writer_->DoScheduledWrite();
314 } 326 }
315 327
316 void JsonPrefStore::ReportValueChanged(const std::string& key, uint32 flags) { 328 void JsonPrefStore::ReportValueChanged(const std::string& key, uint32 flags) {
317 DCHECK(CalledOnValidThread()); 329 DCHECK(CalledOnValidThread());
318 330
319 if (pref_filter_) 331 if (pref_filter_)
320 pref_filter_->FilterUpdate(key); 332 pref_filter_->FilterUpdate(key);
321 333
322 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); 334 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
323 335
324 if (!read_only_) 336 ScheduleWrite(flags);
325 writer_.ScheduleWrite(this);
326 } 337 }
327 338
328 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback( 339 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback(
329 const base::Closure& on_next_successful_write) { 340 const base::Closure& on_next_successful_write) {
330 DCHECK(CalledOnValidThread()); 341 DCHECK(CalledOnValidThread());
331 342
332 writer_.RegisterOnNextSuccessfulWriteCallback(on_next_successful_write); 343 writer_->RegisterOnNextSuccessfulWriteCallback(on_next_successful_write);
333 } 344 }
334 345
335 void JsonPrefStore::OnFileRead(scoped_ptr<ReadResult> read_result) { 346 void JsonPrefStore::OnFileRead(scoped_ptr<ReadResult> read_result) {
336 DCHECK(CalledOnValidThread()); 347 DCHECK(CalledOnValidThread());
337 348
338 DCHECK(read_result); 349 DCHECK(read_result);
339 350
340 scoped_ptr<base::DictionaryValue> unfiltered_prefs(new base::DictionaryValue); 351 scoped_ptr<base::DictionaryValue> unfiltered_prefs(new base::DictionaryValue);
341 352
342 read_error_ = read_result->error; 353 read_error_ = read_result->error;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 } 405 }
395 } 406 }
396 407
397 JsonPrefStore::~JsonPrefStore() { 408 JsonPrefStore::~JsonPrefStore() {
398 CommitPendingWrite(); 409 CommitPendingWrite();
399 } 410 }
400 411
401 bool JsonPrefStore::SerializeData(std::string* output) { 412 bool JsonPrefStore::SerializeData(std::string* output) {
402 DCHECK(CalledOnValidThread()); 413 DCHECK(CalledOnValidThread());
403 414
415 pending_lossy_write_ = false;
416
404 write_count_histogram_.RecordWriteOccured(); 417 write_count_histogram_.RecordWriteOccured();
405 418
406 if (pref_filter_) 419 if (pref_filter_)
407 pref_filter_->FilterSerializeData(prefs_.get()); 420 pref_filter_->FilterSerializeData(prefs_.get());
408 421
409 JSONStringValueSerializer serializer(output); 422 JSONStringValueSerializer serializer(output);
410 // Not pretty-printing prefs shrinks pref file size by ~30%. To obtain 423 // 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 424 // readable prefs for debugging purposes, you can dump your prefs into any
412 // command-line or online JSON pretty printing tool. 425 // command-line or online JSON pretty printing tool.
413 serializer.set_pretty_print(false); 426 serializer.set_pretty_print(false);
(...skipping 11 matching lines...) Expand all
425 FOR_EACH_OBSERVER(PrefStore::Observer, 438 FOR_EACH_OBSERVER(PrefStore::Observer,
426 observers_, 439 observers_,
427 OnInitializationCompleted(false)); 440 OnInitializationCompleted(false));
428 return; 441 return;
429 } 442 }
430 443
431 prefs_ = prefs.Pass(); 444 prefs_ = prefs.Pass();
432 445
433 initialized_ = true; 446 initialized_ = true;
434 447
435 if (schedule_write && !read_only_) 448 if (schedule_write)
436 writer_.ScheduleWrite(this); 449 ScheduleWrite(DEFAULT_PREF_WRITE_FLAGS);
437 450
438 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE) 451 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE)
439 error_delegate_->OnError(read_error_); 452 error_delegate_->OnError(read_error_);
440 453
441 FOR_EACH_OBSERVER(PrefStore::Observer, 454 FOR_EACH_OBSERVER(PrefStore::Observer,
442 observers_, 455 observers_,
443 OnInitializationCompleted(true)); 456 OnInitializationCompleted(true));
444 457
445 return; 458 return;
446 } 459 }
447 460
461 void JsonPrefStore::ScheduleWrite(uint32 flags) {
462 if (read_only_)
463 return;
464
465 if (flags & LOSSY_PREF_WRITE_FLAG)
466 pending_lossy_write_ = true;
467 else
468 writer_->ScheduleWrite(this);
469 }
470
448 // NOTE: This value should NOT be changed without renaming the histogram 471 // NOTE: This value should NOT be changed without renaming the histogram
449 // otherwise it will create incompatible buckets. 472 // otherwise it will create incompatible buckets.
450 const int32_t 473 const int32_t
451 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins = 5; 474 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins = 5;
452 475
453 JsonPrefStore::WriteCountHistogram::WriteCountHistogram( 476 JsonPrefStore::WriteCountHistogram::WriteCountHistogram(
454 const base::TimeDelta& commit_interval, 477 const base::TimeDelta& commit_interval,
455 const base::FilePath& path) 478 const base::FilePath& path)
456 : WriteCountHistogram(commit_interval, 479 : WriteCountHistogram(commit_interval,
457 path, 480 path,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 DCHECK_EQ(31, num_buckets); 548 DCHECK_EQ(31, num_buckets);
526 549
527 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS 550 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS
528 // macro adapted to allow for a dynamically suffixed histogram name. 551 // macro adapted to allow for a dynamically suffixed histogram name.
529 // Note: The factory creates and owns the histogram. 552 // Note: The factory creates and owns the histogram.
530 base::HistogramBase* histogram = base::Histogram::FactoryGet( 553 base::HistogramBase* histogram = base::Histogram::FactoryGet(
531 histogram_name, min_value, max_value, num_buckets, 554 histogram_name, min_value, max_value, num_buckets,
532 base::HistogramBase::kUmaTargetedHistogramFlag); 555 base::HistogramBase::kUmaTargetedHistogramFlag);
533 return histogram; 556 return histogram;
534 } 557 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698