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

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

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