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

Side by Side Diff: chrome/browser/value_store/leveldb_value_store.cc

Issue 10928227: Make database failures in LeveldbValueStore more descriptive. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove ternary ifs, ms doesnt like Created 8 years, 3 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
« no previous file with comments | « chrome/browser/value_store/leveldb_value_store.h ('k') | no next file » | 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 "chrome/browser/value_store/leveldb_value_store.h" 5 #include "chrome/browser/value_store/leveldb_value_store.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/stringprintf.h"
11 #include "base/sys_string_conversions.h" 12 #include "base/sys_string_conversions.h"
12 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
13 #include "third_party/leveldatabase/src/include/leveldb/iterator.h" 14 #include "third_party/leveldatabase/src/include/leveldb/iterator.h"
14 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 15 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
15 16
16 using content::BrowserThread; 17 using content::BrowserThread;
17 18
18 namespace { 19 namespace {
19 20
20 // Generic error message on failure. 21 const char* kInvalidJson = "Invalid JSON";
21 const char kGenericOnFailureMessage[] = "Failure accessing database"; 22
23 ValueStore::ReadResult ReadFailure(const std::string& action,
24 const std::string& reason) {
25 CHECK_NE("", reason);
26 return ValueStore::MakeReadResult(base::StringPrintf(
27 "Failure to %s: %s", action.c_str(), reason.c_str()));
28 }
29
30 ValueStore::ReadResult ReadFailureForKey(const std::string& action,
31 const std::string& key,
32 const std::string& reason) {
33 CHECK_NE("", reason);
34 return ValueStore::MakeReadResult(base::StringPrintf(
35 "Failure to %s for key %s: %s",
36 action.c_str(), key.c_str(), reason.c_str()));
37 }
38
39 ValueStore::WriteResult WriteFailure(const std::string& action,
40 const std::string& reason) {
41 CHECK_NE("", reason);
42 return ValueStore::MakeWriteResult(base::StringPrintf(
43 "Failure to %s: %s", action.c_str(), reason.c_str()));
44 }
45
46 ValueStore::WriteResult WriteFailureForKey(const std::string& action,
47 const std::string& key,
48 const std::string& reason) {
49 CHECK_NE("", reason);
50 return ValueStore::MakeWriteResult(base::StringPrintf(
51 "Failure to %s for key %s: %s",
52 action.c_str(), key.c_str(), reason.c_str()));
53 }
22 54
23 // Scoped leveldb snapshot which releases the snapshot on destruction. 55 // Scoped leveldb snapshot which releases the snapshot on destruction.
24 class ScopedSnapshot { 56 class ScopedSnapshot {
25 public: 57 public:
26 explicit ScopedSnapshot(leveldb::DB* db) 58 explicit ScopedSnapshot(leveldb::DB* db)
27 : db_(db), snapshot_(db->GetSnapshot()) {} 59 : db_(db), snapshot_(db->GetSnapshot()) {}
28 60
29 ~ScopedSnapshot() { 61 ~ScopedSnapshot() {
30 db_->ReleaseSnapshot(snapshot_); 62 db_->ReleaseSnapshot(snapshot_);
31 } 63 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 NOTREACHED() << "Not implemented"; 130 NOTREACHED() << "Not implemented";
99 return 0; 131 return 0;
100 } 132 }
101 133
102 size_t LeveldbValueStore::GetBytesInUse() { 134 size_t LeveldbValueStore::GetBytesInUse() {
103 // Let SettingsStorageQuotaEnforcer implement this. 135 // Let SettingsStorageQuotaEnforcer implement this.
104 NOTREACHED() << "Not implemented"; 136 NOTREACHED() << "Not implemented";
105 return 0; 137 return 0;
106 } 138 }
107 139
108 ValueStore::ReadResult LeveldbValueStore::Get( 140 ValueStore::ReadResult LeveldbValueStore::Get(const std::string& key) {
109 const std::string& key) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
142
111 scoped_ptr<Value> setting; 143 scoped_ptr<Value> setting;
112 if (!ReadFromDb(leveldb::ReadOptions(), key, &setting)) { 144 std::string error = ReadFromDb(leveldb::ReadOptions(), key, &setting);
113 return MakeReadResult(kGenericOnFailureMessage); 145 if (!error.empty())
114 } 146 return ReadFailureForKey("get", key, error);
147
115 DictionaryValue* settings = new DictionaryValue(); 148 DictionaryValue* settings = new DictionaryValue();
116 if (setting.get()) { 149 if (setting.get())
117 settings->SetWithoutPathExpansion(key, setting.release()); 150 settings->SetWithoutPathExpansion(key, setting.release());
118 }
119 return MakeReadResult(settings); 151 return MakeReadResult(settings);
120 } 152 }
121 153
122 ValueStore::ReadResult LeveldbValueStore::Get( 154 ValueStore::ReadResult LeveldbValueStore::Get(
123 const std::vector<std::string>& keys) { 155 const std::vector<std::string>& keys) {
124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
157
125 leveldb::ReadOptions options; 158 leveldb::ReadOptions options;
126 scoped_ptr<DictionaryValue> settings(new DictionaryValue()); 159 scoped_ptr<DictionaryValue> settings(new DictionaryValue());
127 160
128 // All interaction with the db is done on the same thread, so snapshotting 161 // All interaction with the db is done on the same thread, so snapshotting
129 // isn't strictly necessary. This is just defensive. 162 // isn't strictly necessary. This is just defensive.
130 ScopedSnapshot snapshot(db_.get()); 163 ScopedSnapshot snapshot(db_.get());
131 options.snapshot = snapshot.get(); 164 options.snapshot = snapshot.get();
132 for (std::vector<std::string>::const_iterator it = keys.begin(); 165 for (std::vector<std::string>::const_iterator it = keys.begin();
133 it != keys.end(); ++it) { 166 it != keys.end(); ++it) {
134 scoped_ptr<Value> setting; 167 scoped_ptr<Value> setting;
135 if (!ReadFromDb(options, *it, &setting)) { 168 std::string error = ReadFromDb(options, *it, &setting);
136 return MakeReadResult(kGenericOnFailureMessage); 169 if (!error.empty())
137 } 170 return ReadFailureForKey("get multiple items", *it, error);
138 if (setting.get()) { 171 if (setting.get())
139 settings->SetWithoutPathExpansion(*it, setting.release()); 172 settings->SetWithoutPathExpansion(*it, setting.release());
140 }
141 } 173 }
142 174
143 return MakeReadResult(settings.release()); 175 return MakeReadResult(settings.release());
144 } 176 }
145 177
146 ValueStore::ReadResult LeveldbValueStore::Get() { 178 ValueStore::ReadResult LeveldbValueStore::Get() {
147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
180
148 base::JSONReader json_reader; 181 base::JSONReader json_reader;
149 leveldb::ReadOptions options = leveldb::ReadOptions(); 182 leveldb::ReadOptions options = leveldb::ReadOptions();
150 // All interaction with the db is done on the same thread, so snapshotting 183 // All interaction with the db is done on the same thread, so snapshotting
151 // isn't strictly necessary. This is just defensive. 184 // isn't strictly necessary. This is just defensive.
152 scoped_ptr<DictionaryValue> settings(new DictionaryValue()); 185 scoped_ptr<DictionaryValue> settings(new DictionaryValue());
153 186
154 ScopedSnapshot snapshot(db_.get()); 187 ScopedSnapshot snapshot(db_.get());
155 options.snapshot = snapshot.get(); 188 options.snapshot = snapshot.get();
156 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(options)); 189 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(options));
157 for (it->SeekToFirst(); it->Valid(); it->Next()) { 190 for (it->SeekToFirst(); it->Valid(); it->Next()) {
191 std::string key = it->key().ToString();
158 Value* value = json_reader.ReadToValue(it->value().ToString()); 192 Value* value = json_reader.ReadToValue(it->value().ToString());
159 if (value != NULL) { 193 if (value == NULL) {
160 settings->SetWithoutPathExpansion(it->key().ToString(), value);
161 } else {
162 // TODO(kalman): clear the offending non-JSON value from the database. 194 // TODO(kalman): clear the offending non-JSON value from the database.
163 LOG(ERROR) << "Invalid JSON: " << it->value().ToString(); 195 return ReadFailureForKey("get all", key, kInvalidJson);
164 } 196 }
197 settings->SetWithoutPathExpansion(key, value);
165 } 198 }
166 199
167 if (!it->status().ok()) { 200 if (it->status().IsNotFound()) {
168 LOG(ERROR) << "DB iteration failed: " << it->status().ToString(); 201 NOTREACHED() << "IsNotFound() but iterating over all keys?!";
169 return MakeReadResult(kGenericOnFailureMessage); 202 return MakeReadResult(settings.release());
170 } 203 }
171 204
205 if (!it->status().ok())
206 return ReadFailure("get all items", it->status().ToString());
207
172 return MakeReadResult(settings.release()); 208 return MakeReadResult(settings.release());
173 } 209 }
174 210
175 ValueStore::WriteResult LeveldbValueStore::Set( 211 ValueStore::WriteResult LeveldbValueStore::Set(
176 WriteOptions options, const std::string& key, const Value& value) { 212 WriteOptions options, const std::string& key, const Value& value) {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
178 214
179 leveldb::WriteBatch batch; 215 leveldb::WriteBatch batch;
180 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList()); 216 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
181 AddToBatch(options, key, value, &batch, changes.get()); 217 std::string read_error =
182 return WriteToDb(&batch, changes.Pass()); 218 AddToBatch(options, key, value, &batch, changes.get());
219 if (!read_error.empty())
220 return WriteFailureForKey("find changes to set", key, read_error);
221
222 std::string write_error = WriteToDb(&batch);
223 if (!write_error.empty())
224 return WriteFailureForKey("set", key, write_error);
225 return MakeWriteResult(changes.release());
183 } 226 }
184 227
185 ValueStore::WriteResult LeveldbValueStore::Set( 228 ValueStore::WriteResult LeveldbValueStore::Set(
186 WriteOptions options, const DictionaryValue& settings) { 229 WriteOptions options, const DictionaryValue& settings) {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
188 231
189 leveldb::WriteBatch batch; 232 leveldb::WriteBatch batch;
190 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList()); 233 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
191 234
192 for (DictionaryValue::Iterator it(settings); it.HasNext(); it.Advance()) { 235 for (DictionaryValue::Iterator it(settings); it.HasNext(); it.Advance()) {
193 if (!AddToBatch(options, it.key(), it.value(), &batch, changes.get())) 236 std::string read_error =
194 return MakeWriteResult(kGenericOnFailureMessage); 237 AddToBatch(options, it.key(), it.value(), &batch, changes.get());
238 if (!read_error.empty()) {
239 return WriteFailureForKey("find changes to set multiple items",
240 it.key(),
241 read_error);
242 }
195 } 243 }
196 244
197 return WriteToDb(&batch, changes.Pass()); 245 std::string write_error = WriteToDb(&batch);
246 if (!write_error.empty())
247 return WriteFailure("set multiple items", write_error);
248 return MakeWriteResult(changes.release());
249 }
250
251 ValueStore::WriteResult LeveldbValueStore::Remove(const std::string& key) {
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
253 return Remove(std::vector<std::string>(1, key));
198 } 254 }
199 255
200 ValueStore::WriteResult LeveldbValueStore::Remove( 256 ValueStore::WriteResult LeveldbValueStore::Remove(
201 const std::string& key) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
203 std::vector<std::string> keys;
204 keys.push_back(key);
205 return Remove(keys);
206 }
207
208 ValueStore::WriteResult LeveldbValueStore::Remove(
209 const std::vector<std::string>& keys) { 257 const std::vector<std::string>& keys) {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
211 259
212 leveldb::WriteBatch batch; 260 leveldb::WriteBatch batch;
213 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList()); 261 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
214 262
215 for (std::vector<std::string>::const_iterator it = keys.begin(); 263 for (std::vector<std::string>::const_iterator it = keys.begin();
216 it != keys.end(); ++it) { 264 it != keys.end(); ++it) {
217 scoped_ptr<Value> old_value; 265 scoped_ptr<Value> old_value;
218 if (!ReadFromDb(leveldb::ReadOptions(), *it, &old_value)) { 266 std::string read_error =
219 return MakeWriteResult(kGenericOnFailureMessage); 267 ReadFromDb(leveldb::ReadOptions(), *it, &old_value);
268 if (!read_error.empty()) {
269 return WriteFailureForKey("find changes to remove multiple items",
270 *it,
271 read_error);
220 } 272 }
221 273
222 if (old_value.get()) { 274 if (old_value.get()) {
223 changes->push_back( 275 changes->push_back(ValueStoreChange(*it, old_value.release(), NULL));
224 ValueStoreChange(*it, old_value.release(), NULL));
225 batch.Delete(*it); 276 batch.Delete(*it);
226 } 277 }
227 } 278 }
228 279
229 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); 280 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch);
230 if (!status.ok() && !status.IsNotFound()) { 281 if (!status.ok() && !status.IsNotFound())
231 LOG(WARNING) << "DB batch delete failed: " << status.ToString(); 282 return WriteFailure("remove multiple items", status.ToString());
232 return MakeWriteResult(kGenericOnFailureMessage);
233 }
234
235 return MakeWriteResult(changes.release()); 283 return MakeWriteResult(changes.release());
236 } 284 }
237 285
238 ValueStore::WriteResult LeveldbValueStore::Clear() { 286 ValueStore::WriteResult LeveldbValueStore::Clear() {
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
240 288
241 leveldb::ReadOptions read_options; 289 leveldb::ReadOptions read_options;
242 // All interaction with the db is done on the same thread, so snapshotting 290 // All interaction with the db is done on the same thread, so snapshotting
243 // isn't strictly necessary. This is just defensive. 291 // isn't strictly necessary. This is just defensive.
244 leveldb::WriteBatch batch; 292 leveldb::WriteBatch batch;
245 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList()); 293 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
246 294
247 ScopedSnapshot snapshot(db_.get()); 295 ScopedSnapshot snapshot(db_.get());
248 read_options.snapshot = snapshot.get(); 296 read_options.snapshot = snapshot.get();
249 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(read_options)); 297 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(read_options));
250 for (it->SeekToFirst(); it->Valid(); it->Next()) { 298 for (it->SeekToFirst(); it->Valid(); it->Next()) {
251 const std::string key = it->key().ToString(); 299 const std::string key = it->key().ToString();
252 const std::string old_value_json = it->value().ToString(); 300 const std::string old_value_json = it->value().ToString();
253 Value* old_value = base::JSONReader().ReadToValue(old_value_json); 301 Value* old_value = base::JSONReader().ReadToValue(old_value_json);
254 if (old_value) { 302 if (!old_value) {
255 changes->push_back(ValueStoreChange(key, old_value, NULL)); 303 // TODO: delete the bad JSON.
256 } else { 304 return WriteFailureForKey("find changes to clear", key, kInvalidJson);
257 LOG(ERROR) << "Invalid JSON in database: " << old_value_json;
258 } 305 }
306 changes->push_back(ValueStoreChange(key, old_value, NULL));
259 batch.Delete(key); 307 batch.Delete(key);
260 } 308 }
261 309
262 if (!it->status().ok()) { 310 if (it->status().IsNotFound())
263 LOG(WARNING) << "Clear iteration failed: " << it->status().ToString(); 311 NOTREACHED() << "IsNotFound() but clearing?!";
264 return MakeWriteResult(kGenericOnFailureMessage); 312 else if (!it->status().ok())
265 } 313 return WriteFailure("find changes to clear", it->status().ToString());
266 314
267 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); 315 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch);
268 if (!status.ok() && !status.IsNotFound()) { 316 if (status.IsNotFound()) {
269 LOG(WARNING) << "Clear failed: " << status.ToString(); 317 NOTREACHED() << "IsNotFound() but clearing?!";
270 return MakeWriteResult(kGenericOnFailureMessage); 318 return MakeWriteResult(changes.release());
271 } 319 }
272 320 if (!status.ok())
321 return WriteFailure("clear", status.ToString());
273 return MakeWriteResult(changes.release()); 322 return MakeWriteResult(changes.release());
274 } 323 }
275 324
276 bool LeveldbValueStore::ReadFromDb( 325 std::string LeveldbValueStore::ReadFromDb(
277 leveldb::ReadOptions options, 326 leveldb::ReadOptions options,
278 const std::string& key, 327 const std::string& key,
279 scoped_ptr<Value>* setting) { 328 scoped_ptr<Value>* setting) {
280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
281 DCHECK(setting != NULL); 330 DCHECK(setting != NULL);
282 std::string value_as_json; 331 std::string value_as_json;
283 leveldb::Status s = db_->Get(options, key, &value_as_json); 332 leveldb::Status s = db_->Get(options, key, &value_as_json);
284 333
285 if (s.IsNotFound()) { 334 if (s.IsNotFound()) {
286 // Despite there being no value, it was still a success. 335 // Despite there being no value, it was still a success.
287 return true; 336 // Check this first because ok() is false on IsNotFound.
337 return "";
288 } 338 }
289 339
290 if (!s.ok()) { 340 if (!s.ok())
291 LOG(ERROR) << "Error reading from database: " << s.ToString(); 341 return s.ToString();
292 return false;
293 }
294 342
295 Value* value = base::JSONReader().ReadToValue(value_as_json); 343 Value* value = base::JSONReader().ReadToValue(value_as_json);
296 if (value == NULL) { 344 if (value == NULL) {
297 // TODO(kalman): clear the offending non-JSON value from the database. 345 // TODO(kalman): clear the offending non-JSON value from the database.
298 LOG(ERROR) << "Invalid JSON in database: " << value_as_json; 346 return kInvalidJson;
299 return false;
300 } 347 }
301 348
302 setting->reset(value); 349 setting->reset(value);
303 return true; 350 return "";
304 } 351 }
305 352
306 bool LeveldbValueStore::AddToBatch( 353 std::string LeveldbValueStore::AddToBatch(
307 ValueStore::WriteOptions options, 354 ValueStore::WriteOptions options,
308 const std::string& key, 355 const std::string& key,
309 const base::Value& value, 356 const base::Value& value,
310 leveldb::WriteBatch* batch, 357 leveldb::WriteBatch* batch,
311 ValueStoreChangeList* changes) { 358 ValueStoreChangeList* changes) {
312 scoped_ptr<Value> old_value; 359 scoped_ptr<Value> old_value;
313 if (!(options & NO_CHECK_OLD_VALUE)) { 360 if (!(options & NO_CHECK_OLD_VALUE)) {
314 if (!ReadFromDb(leveldb::ReadOptions(), key, &old_value)) 361 std::string error = ReadFromDb(leveldb::ReadOptions(), key, &old_value);
315 return false; 362 if (!error.empty())
363 return error;
316 } 364 }
317 365
318 if (!old_value.get() || !old_value->Equals(&value)) { 366 if (!old_value.get() || !old_value->Equals(&value)) {
319 if (!(options & NO_GENERATE_CHANGES)) { 367 if (!(options & NO_GENERATE_CHANGES)) {
320 changes->push_back( 368 changes->push_back(
321 ValueStoreChange(key, old_value.release(), value.DeepCopy())); 369 ValueStoreChange(key, old_value.release(), value.DeepCopy()));
322 } 370 }
323 std::string value_as_json; 371 std::string value_as_json;
324 base::JSONWriter::Write(&value, &value_as_json); 372 base::JSONWriter::Write(&value, &value_as_json);
325 batch->Put(key, value_as_json); 373 batch->Put(key, value_as_json);
326 } 374 }
327 375
328 return true; 376 return "";
329 } 377 }
330 378
331 ValueStore::WriteResult LeveldbValueStore::WriteToDb( 379 std::string LeveldbValueStore::WriteToDb(leveldb::WriteBatch* batch) {
332 leveldb::WriteBatch* batch,
333 scoped_ptr<ValueStoreChangeList> changes) {
334 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch); 380 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch);
335 if (!status.ok()) { 381 if (status.IsNotFound()) {
336 LOG(WARNING) << "DB batch write failed: " << status.ToString(); 382 NOTREACHED() << "IsNotFound() but writing?!";
337 return MakeWriteResult(kGenericOnFailureMessage); 383 return "";
338 } 384 }
339 385 return status.ok() ? "" : status.ToString();
340 return MakeWriteResult(changes.release());
341 } 386 }
342 387
343 bool LeveldbValueStore::IsEmpty() { 388 bool LeveldbValueStore::IsEmpty() {
344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 389 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
345 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); 390 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions()));
346 391
347 it->SeekToFirst(); 392 it->SeekToFirst();
348 bool is_empty = !it->Valid(); 393 bool is_empty = !it->Valid();
349 if (!it->status().ok()) { 394 if (!it->status().ok()) {
350 LOG(ERROR) << "Checking DB emptiness failed: " << it->status().ToString(); 395 LOG(ERROR) << "Checking DB emptiness failed: " << it->status().ToString();
351 return false; 396 return false;
352 } 397 }
353 return is_empty; 398 return is_empty;
354 } 399 }
OLDNEW
« no previous file with comments | « chrome/browser/value_store/leveldb_value_store.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698