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

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

Issue 169323003: Implementation of leveldb-backed PrefStore (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/prefs/leveldb_pref_store.h"
6
7 #include <algorithm>
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 unused?
8 #include <set>
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 unused?
9
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "base/file_util.h"
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 unused?
dgrogan 2014/02/25 03:32:08 Needed, but the rest were not.
13 #include "base/json/json_file_value_serializer.h"
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 unused?
14 #include "base/json/json_string_value_serializer.h"
15 #include "base/location.h"
16 #include "base/memory/ref_counted.h"
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 unused?
17 #include "base/message_loop/message_loop_proxy.h"
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 Unused?
18 #include "base/prefs/pref_filter.h"
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 unused?
19 #include "base/sequenced_task_runner.h"
20 #include "base/threading/sequenced_worker_pool.h"
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 unused?
21 #include "base/values.h"
22 #include "third_party/leveldatabase/src/include/leveldb/db.h"
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 Also in .h, but that might be able to use a forwar
23
24 LevelDBPrefStore::LevelDBPrefStore(
25 const base::FilePath& filename,
26 base::SequencedTaskRunner* sequenced_task_runner)
27 : path_(filename),
28 sequenced_task_runner_(sequenced_task_runner),
29 read_only_(false),
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 What's the use case for this?
30 initialized_(false),
31 read_error_(PREF_READ_ERROR_OTHER) {}
32
33 bool LevelDBPrefStore::GetValue(const std::string& key,
34 const base::Value** result) const {
35 const base::Value* tmp = NULL;
36 if (!prefs_.GetValue(key, &tmp)) {
37 return false;
38 }
39
40 if (result)
41 *result = tmp;
42 return true;
43 }
44
45 // Callers of GetMutableValue have to call ReportValueChanged in order for the
46 // new value to be persisted.
47 bool LevelDBPrefStore::GetMutableValue(const std::string& key,
48 base::Value** result) {
49 return prefs_.GetValue(key, result);
50 }
51
52 void LevelDBPrefStore::AddObserver(PrefStore::Observer* observer) {
53 observers_.AddObserver(observer);
54 }
55
56 void LevelDBPrefStore::RemoveObserver(PrefStore::Observer* observer) {
57 observers_.RemoveObserver(observer);
58 }
59
60 bool LevelDBPrefStore::HasObservers() const {
61 return observers_.might_have_observers();
62 }
63
64 bool LevelDBPrefStore::IsInitializationComplete() const { return initialized_; }
65
66 void LevelDBPrefStore::PersistOnFileThread(const std::string& key,
67 const std::string& value) {
68 DCHECK(sequenced_task_runner_->RunsTasksOnCurrentThread());
69
70 leveldb::Status status = db_->Put(leveldb::WriteOptions(), key, value);
71 DCHECK(status.ok());
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 Is this OK? What kind of errors can happen here? E
dgrogan 2014/02/25 03:32:08 The corresponding error in JSONPrefStore is ignore
72 }
73
74 void LevelDBPrefStore::PersistFromUIThread(const std::string& key,
75 base::Value* value) {
76 if (read_only_)
77 return;
78 std::string value_string;
79 JSONStringValueSerializer serializer(&value_string);
80 DCHECK(serializer.Serialize(*value));
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 Please no production code in DCHECK, it won't get
dgrogan 2014/02/25 03:32:08 Done.
81
82 sequenced_task_runner_->PostTask(
83 FROM_HERE,
84 base::Bind(
85 &LevelDBPrefStore::PersistOnFileThread, this, key, value_string));
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 How do you make sure |this| is still alive when Pe
dgrogan 2014/02/25 03:32:08 If I'm reading https://code.google.com/p/chromium/
Mattias Nissler (ping if slow) 2014/02/25 10:51:44 Note that PrefStore inherits from base::RefCounted
dgrogan 2014/02/26 07:10:47 Wouldn't this just move the problem to the interna
Mattias Nissler (ping if slow) 2014/02/26 08:35:00 The difference is that you can destroy that object
86 }
87
88 void LevelDBPrefStore::SetValue(const std::string& key, base::Value* value) {
89 DCHECK(value);
90 scoped_ptr<base::Value> new_value(value);
91 base::Value* old_value = NULL;
92 bool found = prefs_.GetValue(key, &old_value);
93 if (!found || !value->Equals(old_value)) {
94 PersistFromUIThread(key, new_value.get());
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 JSONPrefStore batches writes and hits the file onl
dgrogan 2014/02/25 03:32:08 LevelDB does not do this internally. I thought one
Mattias Nissler (ping if slow) 2014/02/25 10:51:44 OK, are you planning to run performance tests on t
dgrogan 2014/03/05 03:06:57 Yes. Note that I don't yet know how, but it's on m
95 prefs_.SetValue(key, new_value.release());
96 }
97 }
98
99 void LevelDBPrefStore::SetValueSilently(const std::string& key,
100 base::Value* value) {
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 implement?
101 }
102
103 void LevelDBPrefStore::RemoveValue(const std::string& key) {
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 implement?
104 }
105
106 bool LevelDBPrefStore::ReadOnly() const { return read_only_; }
107
108 PersistentPrefStore::PrefReadError LevelDBPrefStore::GetReadError() const {
109 return read_error_;
110 }
111
112 PersistentPrefStore::PrefReadError LevelDBPrefStore::ReadPrefs() {
113 DCHECK(!db_);
114 if (path_.empty()) {
115 OnStorageRead(PREF_READ_ERROR_FILE_NOT_SPECIFIED, false);
116 return PREF_READ_ERROR_FILE_NOT_SPECIFIED;
117 }
118
119 bool no_dir = !base::PathExists(path_.DirName());
120
121 leveldb::DB* db;
122 leveldb::Options options;
123 options.create_if_missing = true;
124 leveldb::Status status =
125 leveldb::DB::Open(options, path_.AsUTF8Unsafe(), &db);
126 if (!status.ok()) {
127 // TODO(dgrogan): Add error histogram and call RepairDB.
128 OnStorageRead(PREF_READ_ERROR_FILE_OTHER, no_dir);
129 return PREF_READ_ERROR_FILE_OTHER;
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 Is it possible to get some more information about
dgrogan 2014/03/05 03:06:57 Done.
130 }
131 db_.reset(db);
132
133 scoped_ptr<leveldb::Iterator> it(db->NewIterator(leveldb::ReadOptions()));
134 for (it->SeekToFirst(); it->Valid(); it->Next()) {
135 const std::string value_string = it->value().ToString();
136 JSONStringValueSerializer deserializer(value_string);
137 std::string error_message;
138 int error_code;
139 base::Value* json_value =
140 deserializer.Deserialize(&error_code, &error_message);
141 DCHECK(json_value) << error_message;
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 This should probably not be a DCHECK (unless level
dgrogan 2014/02/25 03:32:08 Done.
142 prefs_.SetValue(it->key().ToString(), json_value);
143 }
144
145 PersistentPrefStore::PrefReadError error = PREF_READ_ERROR_NONE;
146 if (!it->status().ok()) {
147 // TODO(dgrogan): Add error histogram?
148 error = PREF_READ_ERROR_FILE_OTHER;
149 }
150 OnStorageRead(error, no_dir);
151 return error;
152 }
153
154 void LevelDBPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) {
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 implement?
155 }
156
157 void LevelDBPrefStore::CommitPendingWrite() {
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 If this is not needed, please add a comment explai
dgrogan 2014/02/25 03:32:08 Done.
158 }
159
160 void LevelDBPrefStore::ReportValueChanged(const std::string& key) {
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 implement?
161 }
162
163 void LevelDBPrefStore::OnStorageRead(PersistentPrefStore::PrefReadError error,
164 bool no_dir) {
Mattias Nissler (ping if slow) 2014/02/24 09:00:40 implement?
165 }
166
167 LevelDBPrefStore::~LevelDBPrefStore() {}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698