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 |