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

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: fix inverted condition 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(
109 const std::string& key) { 141 const std::string& key) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
143
111 scoped_ptr<Value> setting; 144 scoped_ptr<Value> setting;
112 if (!ReadFromDb(leveldb::ReadOptions(), key, &setting)) { 145 std::string error = ReadFromDb(leveldb::ReadOptions(), key, &setting);
113 return MakeReadResult(kGenericOnFailureMessage); 146 if (!error.empty())
114 } 147 return ReadFailureForKey("get", key, error);
148
115 DictionaryValue* settings = new DictionaryValue(); 149 DictionaryValue* settings = new DictionaryValue();
116 if (setting.get()) { 150 if (setting.get())
117 settings->SetWithoutPathExpansion(key, setting.release()); 151 settings->SetWithoutPathExpansion(key, setting.release());
118 }
119 return MakeReadResult(settings); 152 return MakeReadResult(settings);
120 } 153 }
121 154
122 ValueStore::ReadResult LeveldbValueStore::Get( 155 ValueStore::ReadResult LeveldbValueStore::Get(
123 const std::vector<std::string>& keys) { 156 const std::vector<std::string>& keys) {
124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
158
125 leveldb::ReadOptions options; 159 leveldb::ReadOptions options;
126 scoped_ptr<DictionaryValue> settings(new DictionaryValue()); 160 scoped_ptr<DictionaryValue> settings(new DictionaryValue());
127 161
128 // All interaction with the db is done on the same thread, so snapshotting 162 // All interaction with the db is done on the same thread, so snapshotting
129 // isn't strictly necessary. This is just defensive. 163 // isn't strictly necessary. This is just defensive.
130 ScopedSnapshot snapshot(db_.get()); 164 ScopedSnapshot snapshot(db_.get());
131 options.snapshot = snapshot.get(); 165 options.snapshot = snapshot.get();
132 for (std::vector<std::string>::const_iterator it = keys.begin(); 166 for (std::vector<std::string>::const_iterator it = keys.begin();
133 it != keys.end(); ++it) { 167 it != keys.end(); ++it) {
134 scoped_ptr<Value> setting; 168 scoped_ptr<Value> setting;
135 if (!ReadFromDb(options, *it, &setting)) { 169 std::string error = ReadFromDb(options, *it, &setting);
136 return MakeReadResult(kGenericOnFailureMessage); 170 if (!error.empty())
137 } 171 return ReadFailureForKey("get multiple keys", *it, error);
138 if (setting.get()) { 172 if (setting.get())
139 settings->SetWithoutPathExpansion(*it, setting.release()); 173 settings->SetWithoutPathExpansion(*it, setting.release());
140 }
141 } 174 }
142 175
143 return MakeReadResult(settings.release()); 176 return MakeReadResult(settings.release());
144 } 177 }
145 178
146 ValueStore::ReadResult LeveldbValueStore::Get() { 179 ValueStore::ReadResult LeveldbValueStore::Get() {
147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
181
148 base::JSONReader json_reader; 182 base::JSONReader json_reader;
149 leveldb::ReadOptions options = leveldb::ReadOptions(); 183 leveldb::ReadOptions options = leveldb::ReadOptions();
150 // All interaction with the db is done on the same thread, so snapshotting 184 // All interaction with the db is done on the same thread, so snapshotting
151 // isn't strictly necessary. This is just defensive. 185 // isn't strictly necessary. This is just defensive.
152 scoped_ptr<DictionaryValue> settings(new DictionaryValue()); 186 scoped_ptr<DictionaryValue> settings(new DictionaryValue());
153 187
154 ScopedSnapshot snapshot(db_.get()); 188 ScopedSnapshot snapshot(db_.get());
155 options.snapshot = snapshot.get(); 189 options.snapshot = snapshot.get();
156 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(options)); 190 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(options));
157 for (it->SeekToFirst(); it->Valid(); it->Next()) { 191 for (it->SeekToFirst(); it->Valid(); it->Next()) {
192 std::string key = it->key().ToString();
158 Value* value = json_reader.ReadToValue(it->value().ToString()); 193 Value* value = json_reader.ReadToValue(it->value().ToString());
159 if (value != NULL) { 194 if (value == NULL) {
160 settings->SetWithoutPathExpansion(it->key().ToString(), value);
161 } else {
162 // TODO(kalman): clear the offending non-JSON value from the database. 195 // TODO(kalman): clear the offending non-JSON value from the database.
163 LOG(ERROR) << "Invalid JSON: " << it->value().ToString(); 196 return ReadFailureForKey("get all", key, kInvalidJson);
164 } 197 }
198 settings->SetWithoutPathExpansion(key, value);
165 } 199 }
166 200
167 if (!it->status().ok()) { 201 if (it->status().IsNotFound()) {
168 LOG(ERROR) << "DB iteration failed: " << it->status().ToString(); 202 NOTREACHED() << "IsNotFound() but iterating over all keys?!";
169 return MakeReadResult(kGenericOnFailureMessage); 203 return MakeReadResult(settings.release());
170 } 204 }
171 205
206 if (!it->status().ok())
207 return ReadFailure("get all", it->status().ToString());
208
172 return MakeReadResult(settings.release()); 209 return MakeReadResult(settings.release());
173 } 210 }
174 211
175 ValueStore::WriteResult LeveldbValueStore::Set( 212 ValueStore::WriteResult LeveldbValueStore::Set(
176 WriteOptions options, const std::string& key, const Value& value) { 213 WriteOptions options, const std::string& key, const Value& value) {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
178 215
179 leveldb::WriteBatch batch; 216 leveldb::WriteBatch batch;
180 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList()); 217 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
181 AddToBatch(options, key, value, &batch, changes.get()); 218 std::string read_error =
182 return WriteToDb(&batch, changes.Pass()); 219 AddToBatch(options, key, value, &batch, changes.get());
220 if (!read_error.empty())
221 return WriteFailureForKey("set (read)", key, read_error);
222
223 std::string write_error = WriteToDb(&batch);
224 return write_error.empty() ?
225 MakeWriteResult(changes.release()) :
226 WriteFailureForKey("set (write)", key, write_error);
183 } 227 }
184 228
185 ValueStore::WriteResult LeveldbValueStore::Set( 229 ValueStore::WriteResult LeveldbValueStore::Set(
186 WriteOptions options, const DictionaryValue& settings) { 230 WriteOptions options, const DictionaryValue& settings) {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 231 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
188 232
189 leveldb::WriteBatch batch; 233 leveldb::WriteBatch batch;
190 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList()); 234 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
191 235
192 for (DictionaryValue::Iterator it(settings); it.HasNext(); it.Advance()) { 236 for (DictionaryValue::Iterator it(settings); it.HasNext(); it.Advance()) {
193 if (!AddToBatch(options, it.key(), it.value(), &batch, changes.get())) 237 std::string read_error =
194 return MakeWriteResult(kGenericOnFailureMessage); 238 AddToBatch(options, it.key(), it.value(), &batch, changes.get());
239 if (!read_error.empty())
240 return WriteFailureForKey("set multi (read)", it.key(), read_error);
Matt Perry 2012/09/17 19:21:35 since this is a user-visible error, I would make i
not at google - send to devlin 2012/09/20 00:11:53 Done. The "read" is because it's the reading part
195 } 241 }
196 242
197 return WriteToDb(&batch, changes.Pass()); 243 std::string write_error = WriteToDb(&batch);
244 return write_error.empty() ?
245 MakeWriteResult(changes.release()) :
246 WriteFailure("set multi (write)", write_error);
198 } 247 }
199 248
200 ValueStore::WriteResult LeveldbValueStore::Remove( 249 ValueStore::WriteResult LeveldbValueStore::Remove(
201 const std::string& key) { 250 const std::string& key) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 251 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
203 std::vector<std::string> keys; 252 return Remove(std::vector<std::string>(1, key));
204 keys.push_back(key);
205 return Remove(keys);
206 } 253 }
207 254
208 ValueStore::WriteResult LeveldbValueStore::Remove( 255 ValueStore::WriteResult LeveldbValueStore::Remove(
209 const std::vector<std::string>& keys) { 256 const std::vector<std::string>& keys) {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 257 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
211 258
212 leveldb::WriteBatch batch; 259 leveldb::WriteBatch batch;
213 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList()); 260 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
214 261
215 for (std::vector<std::string>::const_iterator it = keys.begin(); 262 for (std::vector<std::string>::const_iterator it = keys.begin();
216 it != keys.end(); ++it) { 263 it != keys.end(); ++it) {
217 scoped_ptr<Value> old_value; 264 scoped_ptr<Value> old_value;
218 if (!ReadFromDb(leveldb::ReadOptions(), *it, &old_value)) { 265 std::string read_error =
219 return MakeWriteResult(kGenericOnFailureMessage); 266 ReadFromDb(leveldb::ReadOptions(), *it, &old_value);
220 } 267 if (!read_error.empty())
268 return WriteFailureForKey("remove multi (read)", *it, read_error);
221 269
222 if (old_value.get()) { 270 if (old_value.get()) {
223 changes->push_back( 271 changes->push_back(ValueStoreChange(*it, old_value.release(), NULL));
224 ValueStoreChange(*it, old_value.release(), NULL));
225 batch.Delete(*it); 272 batch.Delete(*it);
226 } 273 }
227 } 274 }
228 275
229 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); 276 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch);
230 if (!status.ok() && !status.IsNotFound()) { 277 return (status.ok() || status.IsNotFound()) ?
231 LOG(WARNING) << "DB batch delete failed: " << status.ToString(); 278 MakeWriteResult(changes.release()) :
232 return MakeWriteResult(kGenericOnFailureMessage); 279 WriteFailure("remove multi (write)", status.ToString());
233 }
234
235 return MakeWriteResult(changes.release());
236 } 280 }
237 281
238 ValueStore::WriteResult LeveldbValueStore::Clear() { 282 ValueStore::WriteResult LeveldbValueStore::Clear() {
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
240 284
241 leveldb::ReadOptions read_options; 285 leveldb::ReadOptions read_options;
242 // All interaction with the db is done on the same thread, so snapshotting 286 // All interaction with the db is done on the same thread, so snapshotting
243 // isn't strictly necessary. This is just defensive. 287 // isn't strictly necessary. This is just defensive.
244 leveldb::WriteBatch batch; 288 leveldb::WriteBatch batch;
245 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList()); 289 scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
246 290
247 ScopedSnapshot snapshot(db_.get()); 291 ScopedSnapshot snapshot(db_.get());
248 read_options.snapshot = snapshot.get(); 292 read_options.snapshot = snapshot.get();
249 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(read_options)); 293 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(read_options));
250 for (it->SeekToFirst(); it->Valid(); it->Next()) { 294 for (it->SeekToFirst(); it->Valid(); it->Next()) {
251 const std::string key = it->key().ToString(); 295 const std::string key = it->key().ToString();
252 const std::string old_value_json = it->value().ToString(); 296 const std::string old_value_json = it->value().ToString();
253 Value* old_value = base::JSONReader().ReadToValue(old_value_json); 297 Value* old_value = base::JSONReader().ReadToValue(old_value_json);
254 if (old_value) { 298 if (!old_value) {
255 changes->push_back(ValueStoreChange(key, old_value, NULL)); 299 // TODO: delete the bad JSON.
256 } else { 300 return WriteFailureForKey("clear (read)", key, kInvalidJson);
257 LOG(ERROR) << "Invalid JSON in database: " << old_value_json;
258 } 301 }
302 changes->push_back(ValueStoreChange(key, old_value, NULL));
259 batch.Delete(key); 303 batch.Delete(key);
260 } 304 }
261 305
262 if (!it->status().ok()) { 306 if (it->status().IsNotFound())
263 LOG(WARNING) << "Clear iteration failed: " << it->status().ToString(); 307 NOTREACHED() << "IsNotFound() but clearing?!";
264 return MakeWriteResult(kGenericOnFailureMessage); 308 else if (!it->status().ok())
265 } 309 return WriteFailure("clear (read)", it->status().ToString());
266 310
267 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); 311 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch);
268 if (!status.ok() && !status.IsNotFound()) { 312 if (status.IsNotFound()) {
269 LOG(WARNING) << "Clear failed: " << status.ToString(); 313 NOTREACHED() << "IsNotFound() but clearing?!";
270 return MakeWriteResult(kGenericOnFailureMessage); 314 return MakeWriteResult(changes.release());
271 } 315 }
272 316 return status.ok() ?
273 return MakeWriteResult(changes.release()); 317 MakeWriteResult(changes.release()) :
318 WriteFailure("clear", status.ToString());
274 } 319 }
275 320
276 bool LeveldbValueStore::ReadFromDb( 321 std::string LeveldbValueStore::ReadFromDb(
277 leveldb::ReadOptions options, 322 leveldb::ReadOptions options,
278 const std::string& key, 323 const std::string& key,
279 scoped_ptr<Value>* setting) { 324 scoped_ptr<Value>* setting) {
280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 325 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
281 DCHECK(setting != NULL); 326 DCHECK(setting != NULL);
282 std::string value_as_json; 327 std::string value_as_json;
283 leveldb::Status s = db_->Get(options, key, &value_as_json); 328 leveldb::Status s = db_->Get(options, key, &value_as_json);
284 329
285 if (s.IsNotFound()) { 330 if (s.IsNotFound()) {
286 // Despite there being no value, it was still a success. 331 // Despite there being no value, it was still a success.
287 return true; 332 // Check this first because ok() is false on IsNotFound.
333 return "";
288 } 334 }
289 335
290 if (!s.ok()) { 336 if (!s.ok())
291 LOG(ERROR) << "Error reading from database: " << s.ToString(); 337 return s.ToString();
292 return false;
293 }
294 338
295 Value* value = base::JSONReader().ReadToValue(value_as_json); 339 Value* value = base::JSONReader().ReadToValue(value_as_json);
296 if (value == NULL) { 340 if (value == NULL) {
297 // TODO(kalman): clear the offending non-JSON value from the database. 341 // TODO(kalman): clear the offending non-JSON value from the database.
298 LOG(ERROR) << "Invalid JSON in database: " << value_as_json; 342 return kInvalidJson;
299 return false;
300 } 343 }
301 344
302 setting->reset(value); 345 setting->reset(value);
303 return true; 346 return "";
304 } 347 }
305 348
306 bool LeveldbValueStore::AddToBatch( 349 std::string LeveldbValueStore::AddToBatch(
307 ValueStore::WriteOptions options, 350 ValueStore::WriteOptions options,
308 const std::string& key, 351 const std::string& key,
309 const base::Value& value, 352 const base::Value& value,
310 leveldb::WriteBatch* batch, 353 leveldb::WriteBatch* batch,
311 ValueStoreChangeList* changes) { 354 ValueStoreChangeList* changes) {
312 scoped_ptr<Value> old_value; 355 scoped_ptr<Value> old_value;
313 if (!(options & NO_CHECK_OLD_VALUE)) { 356 if (!(options & NO_CHECK_OLD_VALUE)) {
314 if (!ReadFromDb(leveldb::ReadOptions(), key, &old_value)) 357 std::string error = ReadFromDb(leveldb::ReadOptions(), key, &old_value);
315 return false; 358 if (!error.empty())
359 return error;
316 } 360 }
317 361
318 if (!old_value.get() || !old_value->Equals(&value)) { 362 if (!old_value.get() || !old_value->Equals(&value)) {
319 if (!(options & NO_GENERATE_CHANGES)) { 363 if (!(options & NO_GENERATE_CHANGES)) {
320 changes->push_back( 364 changes->push_back(
321 ValueStoreChange(key, old_value.release(), value.DeepCopy())); 365 ValueStoreChange(key, old_value.release(), value.DeepCopy()));
322 } 366 }
323 std::string value_as_json; 367 std::string value_as_json;
324 base::JSONWriter::Write(&value, &value_as_json); 368 base::JSONWriter::Write(&value, &value_as_json);
325 batch->Put(key, value_as_json); 369 batch->Put(key, value_as_json);
326 } 370 }
327 371
328 return true; 372 return "";
329 } 373 }
330 374
331 ValueStore::WriteResult LeveldbValueStore::WriteToDb( 375 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); 376 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch);
335 if (!status.ok()) { 377 if (status.IsNotFound()) {
336 LOG(WARNING) << "DB batch write failed: " << status.ToString(); 378 NOTREACHED() << "IsNotFound() but writing?!";
not at google - send to devlin 2012/09/17 22:17:36 Here (and a few other places checking IsNotFound)
337 return MakeWriteResult(kGenericOnFailureMessage); 379 return "";
338 } 380 }
339 381 return status.ok() ? "" : status.ToString();
340 return MakeWriteResult(changes.release());
341 } 382 }
342 383
343 bool LeveldbValueStore::IsEmpty() { 384 bool LeveldbValueStore::IsEmpty() {
344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 385 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
345 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); 386 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions()));
346 387
347 it->SeekToFirst(); 388 it->SeekToFirst();
348 bool is_empty = !it->Valid(); 389 bool is_empty = !it->Valid();
349 if (!it->status().ok()) { 390 if (!it->status().ok()) {
350 LOG(ERROR) << "Checking DB emptiness failed: " << it->status().ToString(); 391 LOG(ERROR) << "Checking DB emptiness failed: " << it->status().ToString();
351 return false; 392 return false;
352 } 393 }
353 return is_empty; 394 return is_empty;
354 } 395 }
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