| OLD | NEW |
| 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/chromeos/contacts/contact_database.h" | 5 #include "chrome/browser/chromeos/contacts/contact_database.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 base::Bind(&ContactDatabase::InitFromTaskRunner, | 79 base::Bind(&ContactDatabase::InitFromTaskRunner, |
| 80 base::Unretained(this), | 80 base::Unretained(this), |
| 81 database_dir, | 81 database_dir, |
| 82 success), | 82 success), |
| 83 base::Bind(&ContactDatabase::RunInitCallback, | 83 base::Bind(&ContactDatabase::RunInitCallback, |
| 84 weak_ptr_factory_.GetWeakPtr(), | 84 weak_ptr_factory_.GetWeakPtr(), |
| 85 callback, | 85 callback, |
| 86 base::Owned(success))); | 86 base::Owned(success))); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void ContactDatabase::SaveContacts(scoped_ptr<ContactPointers> contacts, | 89 void ContactDatabase::SaveContacts(scoped_ptr<ContactPointers> contacts_to_save, |
| 90 scoped_ptr<ContactIds> contact_ids_to_delete, |
| 90 scoped_ptr<UpdateMetadata> metadata, | 91 scoped_ptr<UpdateMetadata> metadata, |
| 91 bool is_full_update, | 92 bool is_full_update, |
| 92 SaveCallback callback) { | 93 SaveCallback callback) { |
| 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 94 bool* success = new bool(false); | 95 bool* success = new bool(false); |
| 95 task_runner_->PostTaskAndReply( | 96 task_runner_->PostTaskAndReply( |
| 96 FROM_HERE, | 97 FROM_HERE, |
| 97 base::Bind(&ContactDatabase::SaveContactsFromTaskRunner, | 98 base::Bind(&ContactDatabase::SaveContactsFromTaskRunner, |
| 98 base::Unretained(this), | 99 base::Unretained(this), |
| 99 base::Passed(contacts.Pass()), | 100 base::Passed(contacts_to_save.Pass()), |
| 101 base::Passed(contact_ids_to_delete.Pass()), |
| 100 base::Passed(metadata.Pass()), | 102 base::Passed(metadata.Pass()), |
| 101 is_full_update, | 103 is_full_update, |
| 102 success), | 104 success), |
| 103 base::Bind(&ContactDatabase::RunSaveCallback, | 105 base::Bind(&ContactDatabase::RunSaveCallback, |
| 104 weak_ptr_factory_.GetWeakPtr(), | 106 weak_ptr_factory_.GetWeakPtr(), |
| 105 callback, | 107 callback, |
| 106 base::Owned(success))); | 108 base::Owned(success))); |
| 107 } | 109 } |
| 108 | 110 |
| 109 void ContactDatabase::LoadContacts(LoadCallback callback) { | 111 void ContactDatabase::LoadContacts(LoadCallback callback) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 break; | 208 break; |
| 207 } | 209 } |
| 208 } | 210 } |
| 209 | 211 |
| 210 UMA_HISTOGRAM_ENUMERATION("Contacts.DatabaseInitResult", | 212 UMA_HISTOGRAM_ENUMERATION("Contacts.DatabaseInitResult", |
| 211 histogram_result, | 213 histogram_result, |
| 212 HISTOGRAM_INIT_RESULT_MAX_VALUE); | 214 HISTOGRAM_INIT_RESULT_MAX_VALUE); |
| 213 } | 215 } |
| 214 | 216 |
| 215 void ContactDatabase::SaveContactsFromTaskRunner( | 217 void ContactDatabase::SaveContactsFromTaskRunner( |
| 216 scoped_ptr<ContactPointers> contacts, | 218 scoped_ptr<ContactPointers> contacts_to_save, |
| 219 scoped_ptr<ContactIds> contact_ids_to_delete, |
| 217 scoped_ptr<UpdateMetadata> metadata, | 220 scoped_ptr<UpdateMetadata> metadata, |
| 218 bool is_full_update, | 221 bool is_full_update, |
| 219 bool* success) { | 222 bool* success) { |
| 220 DCHECK(IsRunByTaskRunner()); | 223 DCHECK(IsRunByTaskRunner()); |
| 221 DCHECK(success); | 224 DCHECK(success); |
| 222 VLOG(1) << "Saving " << contacts->size() << " contact(s) to database as " | 225 VLOG(1) << "Saving " << contacts_to_save->size() << " contact(s) to database " |
| 226 << "and deleting " << contact_ids_to_delete->size() << " as " |
| 223 << (is_full_update ? "full" : "incremental") << " update"; | 227 << (is_full_update ? "full" : "incremental") << " update"; |
| 224 | 228 |
| 225 *success = false; | 229 *success = false; |
| 226 | 230 |
| 227 // If we're doing a full update, find all of the existing keys first so we can | 231 // If we're doing a full update, find all of the existing keys first so we can |
| 228 // delete ones that aren't present in the new set of contacts. | 232 // delete ones that aren't present in the new set of contacts. |
| 229 std::set<std::string> keys_to_delete; | 233 std::set<std::string> keys_to_delete; |
| 230 if (is_full_update) { | 234 if (is_full_update) { |
| 231 leveldb::ReadOptions options; | 235 leveldb::ReadOptions options; |
| 232 scoped_ptr<leveldb::Iterator> db_iterator(db_->NewIterator(options)); | 236 scoped_ptr<leveldb::Iterator> db_iterator(db_->NewIterator(options)); |
| 233 db_iterator->SeekToFirst(); | 237 db_iterator->SeekToFirst(); |
| 234 while (db_iterator->Valid()) { | 238 while (db_iterator->Valid()) { |
| 235 std::string key = db_iterator->key().ToString(); | 239 std::string key = db_iterator->key().ToString(); |
| 236 if (key != kUpdateMetadataKey) | 240 if (key != kUpdateMetadataKey) |
| 237 keys_to_delete.insert(key); | 241 keys_to_delete.insert(key); |
| 238 db_iterator->Next(); | 242 db_iterator->Next(); |
| 239 } | 243 } |
| 244 } else { |
| 245 for (ContactIds::const_iterator it = contact_ids_to_delete->begin(); |
| 246 it != contact_ids_to_delete->end(); ++it) { |
| 247 keys_to_delete.insert(*it); |
| 248 } |
| 240 } | 249 } |
| 241 | 250 |
| 242 // TODO(derat): Serializing all of the contacts and so we can write them in a | 251 // TODO(derat): Serializing all of the contacts and so we can write them in a |
| 243 // single batch may be expensive, memory-wise. Consider writing them in | 252 // single batch may be expensive, memory-wise. Consider writing them in |
| 244 // several batches instead. (To avoid using partial writes in the event of a | 253 // several batches instead. (To avoid using partial writes in the event of a |
| 245 // crash, maybe add a dummy "write completed" contact that's removed in the | 254 // crash, maybe add a dummy "write completed" contact that's removed in the |
| 246 // first batch and added in the last.) | 255 // first batch and added in the last.) |
| 247 leveldb::WriteBatch updates; | 256 leveldb::WriteBatch updates; |
| 248 for (ContactPointers::const_iterator it = contacts->begin(); | 257 for (ContactPointers::const_iterator it = contacts_to_save->begin(); |
| 249 it != contacts->end(); ++it) { | 258 it != contacts_to_save->end(); ++it) { |
| 250 const contacts::Contact& contact = **it; | 259 const contacts::Contact& contact = **it; |
| 251 if (contact.contact_id() == kUpdateMetadataKey) { | 260 if (contact.contact_id() == kUpdateMetadataKey) { |
| 252 LOG(WARNING) << "Skipping contact with reserved ID " | 261 LOG(WARNING) << "Skipping contact with reserved ID " |
| 253 << contact.contact_id(); | 262 << contact.contact_id(); |
| 254 continue; | 263 continue; |
| 255 } | 264 } |
| 256 updates.Put(leveldb::Slice(contact.contact_id()), | 265 updates.Put(leveldb::Slice(contact.contact_id()), |
| 257 leveldb::Slice(contact.SerializeAsString())); | 266 leveldb::Slice(contact.SerializeAsString())); |
| 258 if (is_full_update) | 267 if (is_full_update) |
| 259 keys_to_delete.erase(contact.contact_id()); | 268 keys_to_delete.erase(contact.contact_id()); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 db_iterator->Next(); | 333 db_iterator->Next(); |
| 325 } | 334 } |
| 326 | 335 |
| 327 *success = true; | 336 *success = true; |
| 328 UMA_HISTOGRAM_ENUMERATION("Contacts.DatabaseLoadResult", | 337 UMA_HISTOGRAM_ENUMERATION("Contacts.DatabaseLoadResult", |
| 329 HISTOGRAM_LOAD_RESULT_SUCCESS, | 338 HISTOGRAM_LOAD_RESULT_SUCCESS, |
| 330 HISTOGRAM_LOAD_RESULT_MAX_VALUE); | 339 HISTOGRAM_LOAD_RESULT_MAX_VALUE); |
| 331 } | 340 } |
| 332 | 341 |
| 333 } // namespace contacts | 342 } // namespace contacts |
| OLD | NEW |