| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/sync/glue/bookmark_model_associator.h" | 5 #include "chrome/browser/sync/glue/bookmark_model_associator.h" |
| 6 | 6 |
| 7 #include <stack> | 7 #include <stack> |
| 8 | 8 |
| 9 #include "base/hash_tables.h" | 9 #include "base/hash_tables.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 *has_nodes = false; | 230 *has_nodes = false; |
| 231 int64 bookmark_bar_sync_id; | 231 int64 bookmark_bar_sync_id; |
| 232 if (!GetSyncIdForTaggedNode(kBookmarkBarTag, &bookmark_bar_sync_id)) { | 232 if (!GetSyncIdForTaggedNode(kBookmarkBarTag, &bookmark_bar_sync_id)) { |
| 233 return false; | 233 return false; |
| 234 } | 234 } |
| 235 int64 other_bookmarks_sync_id; | 235 int64 other_bookmarks_sync_id; |
| 236 if (!GetSyncIdForTaggedNode(kOtherBookmarksTag, &other_bookmarks_sync_id)) { | 236 if (!GetSyncIdForTaggedNode(kOtherBookmarksTag, &other_bookmarks_sync_id)) { |
| 237 return false; | 237 return false; |
| 238 } | 238 } |
| 239 | 239 |
| 240 sync_api::ReadTransaction trans( | 240 sync_api::ReadTransaction trans(sync_service_->GetUserShare()); |
| 241 sync_service_->backend()->GetUserShareHandle()); | |
| 242 | 241 |
| 243 sync_api::ReadNode bookmark_bar_node(&trans); | 242 sync_api::ReadNode bookmark_bar_node(&trans); |
| 244 if (!bookmark_bar_node.InitByIdLookup(bookmark_bar_sync_id)) { | 243 if (!bookmark_bar_node.InitByIdLookup(bookmark_bar_sync_id)) { |
| 245 return false; | 244 return false; |
| 246 } | 245 } |
| 247 | 246 |
| 248 sync_api::ReadNode other_bookmarks_node(&trans); | 247 sync_api::ReadNode other_bookmarks_node(&trans); |
| 249 if (!other_bookmarks_node.InitByIdLookup(other_bookmarks_sync_id)) { | 248 if (!other_bookmarks_node.InitByIdLookup(other_bookmarks_sync_id)) { |
| 250 return false; | 249 return false; |
| 251 } | 250 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 281 return true; | 280 return true; |
| 282 if (!GetSyncIdForTaggedNode(tag, &sync_id)) | 281 if (!GetSyncIdForTaggedNode(tag, &sync_id)) |
| 283 return false; | 282 return false; |
| 284 | 283 |
| 285 Associate(permanent_node, sync_id); | 284 Associate(permanent_node, sync_id); |
| 286 return true; | 285 return true; |
| 287 } | 286 } |
| 288 | 287 |
| 289 bool BookmarkModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, | 288 bool BookmarkModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, |
| 290 int64* sync_id) { | 289 int64* sync_id) { |
| 291 sync_api::ReadTransaction trans( | 290 sync_api::ReadTransaction trans(sync_service_->GetUserShare()); |
| 292 sync_service_->backend()->GetUserShareHandle()); | |
| 293 sync_api::ReadNode sync_node(&trans); | 291 sync_api::ReadNode sync_node(&trans); |
| 294 if (!sync_node.InitByTagLookup(tag.c_str())) | 292 if (!sync_node.InitByTagLookup(tag.c_str())) |
| 295 return false; | 293 return false; |
| 296 *sync_id = sync_node.GetId(); | 294 *sync_id = sync_node.GetId(); |
| 297 return true; | 295 return true; |
| 298 } | 296 } |
| 299 | 297 |
| 300 bool BookmarkModelAssociator::AssociateModels() { | 298 bool BookmarkModelAssociator::AssociateModels() { |
| 301 // Try to load model associations from persisted associations first. If that | 299 // Try to load model associations from persisted associations first. If that |
| 302 // succeeds, we don't need to run the complex model matching algorithm. | 300 // succeeds, we don't need to run the complex model matching algorithm. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 model->GetBookmarkBarNode()->id()); | 346 model->GetBookmarkBarNode()->id()); |
| 349 DCHECK(bookmark_bar_sync_id != sync_api::kInvalidId); | 347 DCHECK(bookmark_bar_sync_id != sync_api::kInvalidId); |
| 350 int64 other_bookmarks_sync_id = GetSyncIdFromChromeId( | 348 int64 other_bookmarks_sync_id = GetSyncIdFromChromeId( |
| 351 model->other_node()->id()); | 349 model->other_node()->id()); |
| 352 DCHECK(other_bookmarks_sync_id != sync_api::kInvalidId); | 350 DCHECK(other_bookmarks_sync_id != sync_api::kInvalidId); |
| 353 | 351 |
| 354 std::stack<int64> dfs_stack; | 352 std::stack<int64> dfs_stack; |
| 355 dfs_stack.push(other_bookmarks_sync_id); | 353 dfs_stack.push(other_bookmarks_sync_id); |
| 356 dfs_stack.push(bookmark_bar_sync_id); | 354 dfs_stack.push(bookmark_bar_sync_id); |
| 357 | 355 |
| 358 sync_api::WriteTransaction trans( | 356 sync_api::WriteTransaction trans(sync_service_->GetUserShare()); |
| 359 sync_service_->backend()->GetUserShareHandle()); | |
| 360 | 357 |
| 361 while (!dfs_stack.empty()) { | 358 while (!dfs_stack.empty()) { |
| 362 int64 sync_parent_id = dfs_stack.top(); | 359 int64 sync_parent_id = dfs_stack.top(); |
| 363 dfs_stack.pop(); | 360 dfs_stack.pop(); |
| 364 | 361 |
| 365 sync_api::ReadNode sync_parent(&trans); | 362 sync_api::ReadNode sync_parent(&trans); |
| 366 if (!sync_parent.InitByIdLookup(sync_parent_id)) { | 363 if (!sync_parent.InitByIdLookup(sync_parent_id)) { |
| 367 return false; | 364 return false; |
| 368 } | 365 } |
| 369 // Only folder nodes are pushed on to the stack. | 366 // Only folder nodes are pushed on to the stack. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 // ones that are not present in the parent sync node. So create them. | 409 // ones that are not present in the parent sync node. So create them. |
| 413 for (int i = index; i < parent_node->GetChildCount(); ++i) { | 410 for (int i = index; i < parent_node->GetChildCount(); ++i) { |
| 414 sync_child_id = BookmarkChangeProcessor::CreateSyncNode( | 411 sync_child_id = BookmarkChangeProcessor::CreateSyncNode( |
| 415 parent_node, model, i, &trans, this, sync_service_); | 412 parent_node, model, i, &trans, this, sync_service_); |
| 416 if (parent_node->GetChild(i)->is_folder()) | 413 if (parent_node->GetChild(i)->is_folder()) |
| 417 dfs_stack.push(sync_child_id); | 414 dfs_stack.push(sync_child_id); |
| 418 number_of_new_sync_nodes_created_at_association_++; | 415 number_of_new_sync_nodes_created_at_association_++; |
| 419 } | 416 } |
| 420 } | 417 } |
| 421 | 418 |
| 422 if (sync_service_->backend()->GetAutofillMigrationState() != | 419 if (sync_service_->GetAutofillMigrationState() != |
| 423 syncable::MIGRATED) { | 420 syncable::MIGRATED) { |
| 424 syncable::AutofillMigrationDebugInfo debug_info; | 421 syncable::AutofillMigrationDebugInfo debug_info; |
| 425 debug_info.bookmarks_added_during_migration = | 422 debug_info.bookmarks_added_during_migration = |
| 426 number_of_new_sync_nodes_created_at_association_; | 423 number_of_new_sync_nodes_created_at_association_; |
| 427 sync_service_->backend()->SetAutofillMigrationDebugInfo( | 424 sync_service_->SetAutofillMigrationDebugInfo( |
| 428 syncable::AutofillMigrationDebugInfo::BOOKMARK_ADDED, | 425 syncable::AutofillMigrationDebugInfo::BOOKMARK_ADDED, |
| 429 debug_info); | 426 debug_info); |
| 430 } | 427 } |
| 431 return true; | 428 return true; |
| 432 } | 429 } |
| 433 | 430 |
| 434 void BookmarkModelAssociator::PostPersistAssociationsTask() { | 431 void BookmarkModelAssociator::PostPersistAssociationsTask() { |
| 435 // No need to post a task if a task is already pending. | 432 // No need to post a task if a task is already pending. |
| 436 if (!persist_associations_.empty()) | 433 if (!persist_associations_.empty()) |
| 437 return; | 434 return; |
| 438 MessageLoop::current()->PostTask( | 435 MessageLoop::current()->PostTask( |
| 439 FROM_HERE, | 436 FROM_HERE, |
| 440 persist_associations_.NewRunnableMethod( | 437 persist_associations_.NewRunnableMethod( |
| 441 &BookmarkModelAssociator::PersistAssociations)); | 438 &BookmarkModelAssociator::PersistAssociations)); |
| 442 } | 439 } |
| 443 | 440 |
| 444 void BookmarkModelAssociator::PersistAssociations() { | 441 void BookmarkModelAssociator::PersistAssociations() { |
| 445 // If there are no dirty associations we have nothing to do. We handle this | 442 // If there are no dirty associations we have nothing to do. We handle this |
| 446 // explicity instead of letting the for loop do it to avoid creating a write | 443 // explicity instead of letting the for loop do it to avoid creating a write |
| 447 // transaction in this case. | 444 // transaction in this case. |
| 448 if (dirty_associations_sync_ids_.empty()) { | 445 if (dirty_associations_sync_ids_.empty()) { |
| 449 DCHECK(id_map_.empty()); | 446 DCHECK(id_map_.empty()); |
| 450 DCHECK(id_map_inverse_.empty()); | 447 DCHECK(id_map_inverse_.empty()); |
| 451 return; | 448 return; |
| 452 } | 449 } |
| 453 | 450 |
| 454 sync_api::WriteTransaction trans( | 451 sync_api::WriteTransaction trans(sync_service_->GetUserShare()); |
| 455 sync_service_->backend()->GetUserShareHandle()); | |
| 456 DirtyAssociationsSyncIds::iterator iter; | 452 DirtyAssociationsSyncIds::iterator iter; |
| 457 for (iter = dirty_associations_sync_ids_.begin(); | 453 for (iter = dirty_associations_sync_ids_.begin(); |
| 458 iter != dirty_associations_sync_ids_.end(); | 454 iter != dirty_associations_sync_ids_.end(); |
| 459 ++iter) { | 455 ++iter) { |
| 460 int64 sync_id = *iter; | 456 int64 sync_id = *iter; |
| 461 sync_api::WriteNode sync_node(&trans); | 457 sync_api::WriteNode sync_node(&trans); |
| 462 if (!sync_node.InitByIdLookup(sync_id)) { | 458 if (!sync_node.InitByIdLookup(sync_id)) { |
| 463 persist_ids_error_handler_->OnUnrecoverableError(FROM_HERE, | 459 persist_ids_error_handler_->OnUnrecoverableError(FROM_HERE, |
| 464 "Could not lookup bookmark node for ID persistence."); | 460 "Could not lookup bookmark node for ID persistence."); |
| 465 return; | 461 return; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 // Build a bookmark node ID index since we are going to repeatedly search for | 495 // Build a bookmark node ID index since we are going to repeatedly search for |
| 500 // bookmark nodes by their IDs. | 496 // bookmark nodes by their IDs. |
| 501 BookmarkNodeIdIndex id_index; | 497 BookmarkNodeIdIndex id_index; |
| 502 id_index.AddAll(model->GetBookmarkBarNode()); | 498 id_index.AddAll(model->GetBookmarkBarNode()); |
| 503 id_index.AddAll(model->other_node()); | 499 id_index.AddAll(model->other_node()); |
| 504 | 500 |
| 505 std::stack<int64> dfs_stack; | 501 std::stack<int64> dfs_stack; |
| 506 dfs_stack.push(other_bookmarks_id); | 502 dfs_stack.push(other_bookmarks_id); |
| 507 dfs_stack.push(bookmark_bar_id); | 503 dfs_stack.push(bookmark_bar_id); |
| 508 | 504 |
| 509 sync_api::ReadTransaction trans( | 505 sync_api::ReadTransaction trans(sync_service_->GetUserShare()); |
| 510 sync_service_->backend()->GetUserShareHandle()); | |
| 511 | 506 |
| 512 // Count total number of nodes in sync model so that we can compare that | 507 // Count total number of nodes in sync model so that we can compare that |
| 513 // with the total number of nodes in the bookmark model. | 508 // with the total number of nodes in the bookmark model. |
| 514 size_t sync_node_count = 0; | 509 size_t sync_node_count = 0; |
| 515 while (!dfs_stack.empty()) { | 510 while (!dfs_stack.empty()) { |
| 516 int64 parent_id = dfs_stack.top(); | 511 int64 parent_id = dfs_stack.top(); |
| 517 dfs_stack.pop(); | 512 dfs_stack.pop(); |
| 518 ++sync_node_count; | 513 ++sync_node_count; |
| 519 sync_api::ReadNode sync_parent(&trans); | 514 sync_api::ReadNode sync_parent(&trans); |
| 520 if (!sync_parent.InitByIdLookup(parent_id)) { | 515 if (!sync_parent.InitByIdLookup(parent_id)) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 | 548 |
| 554 // It's possible that the number of nodes in the bookmark model is not the | 549 // It's possible that the number of nodes in the bookmark model is not the |
| 555 // same as number of nodes in the sync model. This can happen when the sync | 550 // same as number of nodes in the sync model. This can happen when the sync |
| 556 // model doesn't get a chance to persist its changes, for example when | 551 // model doesn't get a chance to persist its changes, for example when |
| 557 // Chrome does not shut down gracefully. In such cases we can't trust the | 552 // Chrome does not shut down gracefully. In such cases we can't trust the |
| 558 // loaded associations. | 553 // loaded associations. |
| 559 return sync_node_count == id_index.count(); | 554 return sync_node_count == id_index.count(); |
| 560 } | 555 } |
| 561 | 556 |
| 562 } // namespace browser_sync | 557 } // namespace browser_sync |
| OLD | NEW |