| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "components/sync_bookmarks/bookmark_model_associator.h" | 5 #include "components/sync_bookmarks/bookmark_model_associator.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 74 explicit BookmarkNodeFinder(const BookmarkNode* parent_node); | 74 explicit BookmarkNodeFinder(const BookmarkNode* parent_node); |
| 75 | 75 |
| 76 // Finds the bookmark node that matches the given url, title and folder | 76 // Finds the bookmark node that matches the given url, title and folder |
| 77 // attribute. Returns the matching node if one exists; NULL otherwise. | 77 // attribute. Returns the matching node if one exists; NULL otherwise. |
| 78 // If there are multiple matches then a node with ID matching |preferred_id| | 78 // If there are multiple matches then a node with ID matching |preferred_id| |
| 79 // is returned; otherwise the first matching node is returned. | 79 // is returned; otherwise the first matching node is returned. |
| 80 // If a matching node is found, it's removed for further matches. | 80 // If a matching node is found, it's removed for further matches. |
| 81 const BookmarkNode* FindBookmarkNode(const GURL& url, | 81 const BookmarkNode* FindBookmarkNode(const GURL& url, |
| 82 const std::string& title, | 82 const std::string& title, |
| 83 bool is_folder, | 83 bool is_folder, |
| 84 int64 preferred_id); | 84 int64_t preferred_id); |
| 85 | 85 |
| 86 // Returns true if |bookmark_node| matches the specified |url|, | 86 // Returns true if |bookmark_node| matches the specified |url|, |
| 87 // |title|, and |is_folder| flags. | 87 // |title|, and |is_folder| flags. |
| 88 static bool NodeMatches(const BookmarkNode* bookmark_node, | 88 static bool NodeMatches(const BookmarkNode* bookmark_node, |
| 89 const GURL& url, | 89 const GURL& url, |
| 90 const std::string& title, | 90 const std::string& title, |
| 91 bool is_folder); | 91 bool is_folder); |
| 92 | 92 |
| 93 private: | 93 private: |
| 94 // Maps bookmark node titles to instances, duplicates allowed. | 94 // Maps bookmark node titles to instances, duplicates allowed. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 ConvertTitleToSyncInternalFormat(title, &title); | 136 ConvertTitleToSyncInternalFormat(title, &title); |
| 137 | 137 |
| 138 child_nodes_.insert(std::make_pair(title, child_node)); | 138 child_nodes_.insert(std::make_pair(title, child_node)); |
| 139 } | 139 } |
| 140 } | 140 } |
| 141 | 141 |
| 142 const BookmarkNode* BookmarkNodeFinder::FindBookmarkNode( | 142 const BookmarkNode* BookmarkNodeFinder::FindBookmarkNode( |
| 143 const GURL& url, | 143 const GURL& url, |
| 144 const std::string& title, | 144 const std::string& title, |
| 145 bool is_folder, | 145 bool is_folder, |
| 146 int64 preferred_id) { | 146 int64_t preferred_id) { |
| 147 const BookmarkNode* match = nullptr; | 147 const BookmarkNode* match = nullptr; |
| 148 | 148 |
| 149 // First lookup a range of bookmarks with the same title. | 149 // First lookup a range of bookmarks with the same title. |
| 150 std::string adjusted_title; | 150 std::string adjusted_title; |
| 151 ConvertTitleToSyncInternalFormat(title, &adjusted_title); | 151 ConvertTitleToSyncInternalFormat(title, &adjusted_title); |
| 152 BookmarkNodeRange range = child_nodes_.equal_range(adjusted_title); | 152 BookmarkNodeRange range = child_nodes_.equal_range(adjusted_title); |
| 153 BookmarkNodeMap::iterator match_iter = range.second; | 153 BookmarkNodeMap::iterator match_iter = range.second; |
| 154 for (BookmarkNodeMap::iterator iter = range.first; | 154 for (BookmarkNodeMap::iterator iter = range.first; |
| 155 iter != range.second; | 155 iter != range.second; |
| 156 ++iter) { | 156 ++iter) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 syncer::SyncMergeResult* local_merge_result, | 207 syncer::SyncMergeResult* local_merge_result, |
| 208 syncer::SyncMergeResult* syncer_merge_result) | 208 syncer::SyncMergeResult* syncer_merge_result) |
| 209 : local_merge_result_(local_merge_result), | 209 : local_merge_result_(local_merge_result), |
| 210 syncer_merge_result_(syncer_merge_result), | 210 syncer_merge_result_(syncer_merge_result), |
| 211 duplicate_count_(0), | 211 duplicate_count_(0), |
| 212 native_model_sync_state_(UNSET) {} | 212 native_model_sync_state_(UNSET) {} |
| 213 | 213 |
| 214 BookmarkModelAssociator::Context::~Context() { | 214 BookmarkModelAssociator::Context::~Context() { |
| 215 } | 215 } |
| 216 | 216 |
| 217 void BookmarkModelAssociator::Context::PushNode(int64 sync_id) { | 217 void BookmarkModelAssociator::Context::PushNode(int64_t sync_id) { |
| 218 dfs_stack_.push(sync_id); | 218 dfs_stack_.push(sync_id); |
| 219 } | 219 } |
| 220 | 220 |
| 221 bool BookmarkModelAssociator::Context::PopNode(int64* sync_id) { | 221 bool BookmarkModelAssociator::Context::PopNode(int64_t* sync_id) { |
| 222 if (dfs_stack_.empty()) { | 222 if (dfs_stack_.empty()) { |
| 223 *sync_id = 0; | 223 *sync_id = 0; |
| 224 return false; | 224 return false; |
| 225 } | 225 } |
| 226 *sync_id = dfs_stack_.top(); | 226 *sync_id = dfs_stack_.top(); |
| 227 dfs_stack_.pop(); | 227 dfs_stack_.pop(); |
| 228 return true; | 228 return true; |
| 229 } | 229 } |
| 230 | 230 |
| 231 void BookmarkModelAssociator::Context::SetPreAssociationVersions( | 231 void BookmarkModelAssociator::Context::SetPreAssociationVersions( |
| 232 int64 native_version, | 232 int64_t native_version, |
| 233 int64 sync_version) { | 233 int64_t sync_version) { |
| 234 local_merge_result_->set_pre_association_version(native_version); | 234 local_merge_result_->set_pre_association_version(native_version); |
| 235 syncer_merge_result_->set_pre_association_version(sync_version); | 235 syncer_merge_result_->set_pre_association_version(sync_version); |
| 236 } | 236 } |
| 237 | 237 |
| 238 void BookmarkModelAssociator::Context::SetNumItemsBeforeAssociation( | 238 void BookmarkModelAssociator::Context::SetNumItemsBeforeAssociation( |
| 239 int local_num, | 239 int local_num, |
| 240 int sync_num) { | 240 int sync_num) { |
| 241 local_merge_result_->set_num_items_before_association(local_num); | 241 local_merge_result_->set_num_items_before_association(local_num); |
| 242 syncer_merge_result_->set_num_items_before_association(sync_num); | 242 syncer_merge_result_->set_num_items_before_association(sync_num); |
| 243 } | 243 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 // This hash code already exists in the set. | 288 // This hash code already exists in the set. |
| 289 ++duplicate_count_; | 289 ++duplicate_count_; |
| 290 } | 290 } |
| 291 } | 291 } |
| 292 | 292 |
| 293 void BookmarkModelAssociator::Context::AddBookmarkRoot( | 293 void BookmarkModelAssociator::Context::AddBookmarkRoot( |
| 294 const bookmarks::BookmarkNode* root) { | 294 const bookmarks::BookmarkNode* root) { |
| 295 bookmark_roots_.push_back(root); | 295 bookmark_roots_.push_back(root); |
| 296 } | 296 } |
| 297 | 297 |
| 298 int64 BookmarkModelAssociator::Context::GetSyncPreAssociationVersion() const { | 298 int64_t BookmarkModelAssociator::Context::GetSyncPreAssociationVersion() const { |
| 299 return syncer_merge_result_->pre_association_version(); | 299 return syncer_merge_result_->pre_association_version(); |
| 300 } | 300 } |
| 301 | 301 |
| 302 void BookmarkModelAssociator::Context::MarkForVersionUpdate( | 302 void BookmarkModelAssociator::Context::MarkForVersionUpdate( |
| 303 const bookmarks::BookmarkNode* node) { | 303 const bookmarks::BookmarkNode* node) { |
| 304 bookmarks_for_version_update_.push_back(node); | 304 bookmarks_for_version_update_.push_back(node); |
| 305 } | 305 } |
| 306 | 306 |
| 307 BookmarkModelAssociator::BookmarkModelAssociator( | 307 BookmarkModelAssociator::BookmarkModelAssociator( |
| 308 BookmarkModel* bookmark_model, | 308 BookmarkModel* bookmark_model, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 325 DCHECK(thread_checker_.CalledOnValidThread()); | 325 DCHECK(thread_checker_.CalledOnValidThread()); |
| 326 } | 326 } |
| 327 | 327 |
| 328 syncer::SyncError BookmarkModelAssociator::DisassociateModels() { | 328 syncer::SyncError BookmarkModelAssociator::DisassociateModels() { |
| 329 id_map_.clear(); | 329 id_map_.clear(); |
| 330 id_map_inverse_.clear(); | 330 id_map_inverse_.clear(); |
| 331 dirty_associations_sync_ids_.clear(); | 331 dirty_associations_sync_ids_.clear(); |
| 332 return syncer::SyncError(); | 332 return syncer::SyncError(); |
| 333 } | 333 } |
| 334 | 334 |
| 335 int64 BookmarkModelAssociator::GetSyncIdFromChromeId(const int64& node_id) { | 335 int64_t BookmarkModelAssociator::GetSyncIdFromChromeId(const int64_t& node_id) { |
| 336 BookmarkIdToSyncIdMap::const_iterator iter = id_map_.find(node_id); | 336 BookmarkIdToSyncIdMap::const_iterator iter = id_map_.find(node_id); |
| 337 return iter == id_map_.end() ? syncer::kInvalidId : iter->second; | 337 return iter == id_map_.end() ? syncer::kInvalidId : iter->second; |
| 338 } | 338 } |
| 339 | 339 |
| 340 const BookmarkNode* BookmarkModelAssociator::GetChromeNodeFromSyncId( | 340 const BookmarkNode* BookmarkModelAssociator::GetChromeNodeFromSyncId( |
| 341 int64 sync_id) { | 341 int64_t sync_id) { |
| 342 SyncIdToBookmarkNodeMap::const_iterator iter = id_map_inverse_.find(sync_id); | 342 SyncIdToBookmarkNodeMap::const_iterator iter = id_map_inverse_.find(sync_id); |
| 343 return iter == id_map_inverse_.end() ? NULL : iter->second; | 343 return iter == id_map_inverse_.end() ? NULL : iter->second; |
| 344 } | 344 } |
| 345 | 345 |
| 346 bool BookmarkModelAssociator::InitSyncNodeFromChromeId( | 346 bool BookmarkModelAssociator::InitSyncNodeFromChromeId( |
| 347 const int64& node_id, | 347 const int64_t& node_id, |
| 348 syncer::BaseNode* sync_node) { | 348 syncer::BaseNode* sync_node) { |
| 349 DCHECK(sync_node); | 349 DCHECK(sync_node); |
| 350 int64 sync_id = GetSyncIdFromChromeId(node_id); | 350 int64_t sync_id = GetSyncIdFromChromeId(node_id); |
| 351 if (sync_id == syncer::kInvalidId) | 351 if (sync_id == syncer::kInvalidId) |
| 352 return false; | 352 return false; |
| 353 if (sync_node->InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) | 353 if (sync_node->InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) |
| 354 return false; | 354 return false; |
| 355 DCHECK(sync_node->GetId() == sync_id); | 355 DCHECK(sync_node->GetId() == sync_id); |
| 356 return true; | 356 return true; |
| 357 } | 357 } |
| 358 | 358 |
| 359 void BookmarkModelAssociator::AddAssociation(const BookmarkNode* node, | 359 void BookmarkModelAssociator::AddAssociation(const BookmarkNode* node, |
| 360 int64 sync_id) { | 360 int64_t sync_id) { |
| 361 DCHECK(thread_checker_.CalledOnValidThread()); | 361 DCHECK(thread_checker_.CalledOnValidThread()); |
| 362 int64 node_id = node->id(); | 362 int64_t node_id = node->id(); |
| 363 DCHECK_NE(sync_id, syncer::kInvalidId); | 363 DCHECK_NE(sync_id, syncer::kInvalidId); |
| 364 DCHECK(id_map_.find(node_id) == id_map_.end()); | 364 DCHECK(id_map_.find(node_id) == id_map_.end()); |
| 365 DCHECK(id_map_inverse_.find(sync_id) == id_map_inverse_.end()); | 365 DCHECK(id_map_inverse_.find(sync_id) == id_map_inverse_.end()); |
| 366 id_map_[node_id] = sync_id; | 366 id_map_[node_id] = sync_id; |
| 367 id_map_inverse_[sync_id] = node; | 367 id_map_inverse_[sync_id] = node; |
| 368 } | 368 } |
| 369 | 369 |
| 370 void BookmarkModelAssociator::Associate(const BookmarkNode* node, | 370 void BookmarkModelAssociator::Associate(const BookmarkNode* node, |
| 371 const syncer::BaseNode& sync_node) { | 371 const syncer::BaseNode& sync_node) { |
| 372 AddAssociation(node, sync_node.GetId()); | 372 AddAssociation(node, sync_node.GetId()); |
| 373 | 373 |
| 374 // The same check exists in PersistAssociations. However it is better to | 374 // The same check exists in PersistAssociations. However it is better to |
| 375 // do the check earlier to avoid the cost of decrypting nodes again | 375 // do the check earlier to avoid the cost of decrypting nodes again |
| 376 // in PersistAssociations. | 376 // in PersistAssociations. |
| 377 if (node->id() != sync_node.GetExternalId()) { | 377 if (node->id() != sync_node.GetExternalId()) { |
| 378 dirty_associations_sync_ids_.insert(sync_node.GetId()); | 378 dirty_associations_sync_ids_.insert(sync_node.GetId()); |
| 379 PostPersistAssociationsTask(); | 379 PostPersistAssociationsTask(); |
| 380 } | 380 } |
| 381 } | 381 } |
| 382 | 382 |
| 383 void BookmarkModelAssociator::Disassociate(int64 sync_id) { | 383 void BookmarkModelAssociator::Disassociate(int64_t sync_id) { |
| 384 DCHECK(thread_checker_.CalledOnValidThread()); | 384 DCHECK(thread_checker_.CalledOnValidThread()); |
| 385 SyncIdToBookmarkNodeMap::iterator iter = id_map_inverse_.find(sync_id); | 385 SyncIdToBookmarkNodeMap::iterator iter = id_map_inverse_.find(sync_id); |
| 386 if (iter == id_map_inverse_.end()) | 386 if (iter == id_map_inverse_.end()) |
| 387 return; | 387 return; |
| 388 id_map_.erase(iter->second->id()); | 388 id_map_.erase(iter->second->id()); |
| 389 id_map_inverse_.erase(iter); | 389 id_map_inverse_.erase(iter); |
| 390 dirty_associations_sync_ids_.erase(sync_id); | 390 dirty_associations_sync_ids_.erase(sync_id); |
| 391 } | 391 } |
| 392 | 392 |
| 393 bool BookmarkModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) { | 393 bool BookmarkModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 421 other_bookmarks_node.HasChildren() || | 421 other_bookmarks_node.HasChildren() || |
| 422 (has_mobile_folder && mobile_bookmarks_node.HasChildren()); | 422 (has_mobile_folder && mobile_bookmarks_node.HasChildren()); |
| 423 return true; | 423 return true; |
| 424 } | 424 } |
| 425 | 425 |
| 426 bool BookmarkModelAssociator::AssociateTaggedPermanentNode( | 426 bool BookmarkModelAssociator::AssociateTaggedPermanentNode( |
| 427 syncer::BaseTransaction* trans, | 427 syncer::BaseTransaction* trans, |
| 428 const BookmarkNode* permanent_node, | 428 const BookmarkNode* permanent_node, |
| 429 const std::string& tag) { | 429 const std::string& tag) { |
| 430 // Do nothing if |permanent_node| is already initialized and associated. | 430 // Do nothing if |permanent_node| is already initialized and associated. |
| 431 int64 sync_id = GetSyncIdFromChromeId(permanent_node->id()); | 431 int64_t sync_id = GetSyncIdFromChromeId(permanent_node->id()); |
| 432 if (sync_id != syncer::kInvalidId) | 432 if (sync_id != syncer::kInvalidId) |
| 433 return true; | 433 return true; |
| 434 | 434 |
| 435 syncer::ReadNode sync_node(trans); | 435 syncer::ReadNode sync_node(trans); |
| 436 if (sync_node.InitByTagLookupForBookmarks(tag) != syncer::BaseNode::INIT_OK) | 436 if (sync_node.InitByTagLookupForBookmarks(tag) != syncer::BaseNode::INIT_OK) |
| 437 return false; | 437 return false; |
| 438 | 438 |
| 439 Associate(permanent_node, sync_node); | 439 Associate(permanent_node, sync_node); |
| 440 return true; | 440 return true; |
| 441 } | 441 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 | 489 |
| 490 if (!AssociateTaggedPermanentNode(trans, bookmark_model_->mobile_node(), | 490 if (!AssociateTaggedPermanentNode(trans, bookmark_model_->mobile_node(), |
| 491 kMobileBookmarksTag) && | 491 kMobileBookmarksTag) && |
| 492 expect_mobile_bookmarks_folder_) { | 492 expect_mobile_bookmarks_folder_) { |
| 493 return unrecoverable_error_handler_->CreateAndUploadError( | 493 return unrecoverable_error_handler_->CreateAndUploadError( |
| 494 FROM_HERE, "Mobile bookmarks node not found", model_type()); | 494 FROM_HERE, "Mobile bookmarks node not found", model_type()); |
| 495 } | 495 } |
| 496 | 496 |
| 497 // Note: the root node may have additional extra nodes. Currently none of | 497 // Note: the root node may have additional extra nodes. Currently none of |
| 498 // them are meant to sync. | 498 // them are meant to sync. |
| 499 int64 bookmark_bar_sync_id = | 499 int64_t bookmark_bar_sync_id = |
| 500 GetSyncIdFromChromeId(bookmark_model_->bookmark_bar_node()->id()); | 500 GetSyncIdFromChromeId(bookmark_model_->bookmark_bar_node()->id()); |
| 501 DCHECK_NE(bookmark_bar_sync_id, syncer::kInvalidId); | 501 DCHECK_NE(bookmark_bar_sync_id, syncer::kInvalidId); |
| 502 context->AddBookmarkRoot(bookmark_model_->bookmark_bar_node()); | 502 context->AddBookmarkRoot(bookmark_model_->bookmark_bar_node()); |
| 503 int64 other_bookmarks_sync_id = | 503 int64_t other_bookmarks_sync_id = |
| 504 GetSyncIdFromChromeId(bookmark_model_->other_node()->id()); | 504 GetSyncIdFromChromeId(bookmark_model_->other_node()->id()); |
| 505 DCHECK_NE(other_bookmarks_sync_id, syncer::kInvalidId); | 505 DCHECK_NE(other_bookmarks_sync_id, syncer::kInvalidId); |
| 506 context->AddBookmarkRoot(bookmark_model_->other_node()); | 506 context->AddBookmarkRoot(bookmark_model_->other_node()); |
| 507 int64 mobile_bookmarks_sync_id = | 507 int64_t mobile_bookmarks_sync_id = |
| 508 GetSyncIdFromChromeId(bookmark_model_->mobile_node()->id()); | 508 GetSyncIdFromChromeId(bookmark_model_->mobile_node()->id()); |
| 509 if (expect_mobile_bookmarks_folder_) | 509 if (expect_mobile_bookmarks_folder_) |
| 510 DCHECK_NE(syncer::kInvalidId, mobile_bookmarks_sync_id); | 510 DCHECK_NE(syncer::kInvalidId, mobile_bookmarks_sync_id); |
| 511 if (mobile_bookmarks_sync_id != syncer::kInvalidId) | 511 if (mobile_bookmarks_sync_id != syncer::kInvalidId) |
| 512 context->AddBookmarkRoot(bookmark_model_->mobile_node()); | 512 context->AddBookmarkRoot(bookmark_model_->mobile_node()); |
| 513 | 513 |
| 514 // WARNING: The order in which we push these should match their order in the | 514 // WARNING: The order in which we push these should match their order in the |
| 515 // bookmark model (see BookmarkModel::DoneLoading(..)). | 515 // bookmark model (see BookmarkModel::DoneLoading(..)). |
| 516 context->PushNode(bookmark_bar_sync_id); | 516 context->PushNode(bookmark_bar_sync_id); |
| 517 context->PushNode(other_bookmarks_sync_id); | 517 context->PushNode(other_bookmarks_sync_id); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 } | 562 } |
| 563 context->SetNumItemsAfterAssociation( | 563 context->SetNumItemsAfterAssociation( |
| 564 bookmark_model_->root_node()->GetTotalNodeCount(), syncer_num); | 564 bookmark_model_->root_node()->GetTotalNodeCount(), syncer_num); |
| 565 } | 565 } |
| 566 | 566 |
| 567 syncer::SyncError BookmarkModelAssociator::BuildAssociations(Context* context) { | 567 syncer::SyncError BookmarkModelAssociator::BuildAssociations(Context* context) { |
| 568 DCHECK(bookmark_model_->loaded()); | 568 DCHECK(bookmark_model_->loaded()); |
| 569 DCHECK_NE(context->native_model_sync_state(), AHEAD); | 569 DCHECK_NE(context->native_model_sync_state(), AHEAD); |
| 570 | 570 |
| 571 int initial_duplicate_count = 0; | 571 int initial_duplicate_count = 0; |
| 572 int64 new_version = syncer::syncable::kInvalidTransactionVersion; | 572 int64_t new_version = syncer::syncable::kInvalidTransactionVersion; |
| 573 { | 573 { |
| 574 syncer::WriteTransaction trans(FROM_HERE, user_share_, &new_version); | 574 syncer::WriteTransaction trans(FROM_HERE, user_share_, &new_version); |
| 575 | 575 |
| 576 syncer::SyncError error = AssociatePermanentFolders(&trans, context); | 576 syncer::SyncError error = AssociatePermanentFolders(&trans, context); |
| 577 if (error.IsSet()) | 577 if (error.IsSet()) |
| 578 return error; | 578 return error; |
| 579 | 579 |
| 580 SetNumItemsBeforeAssociation(&trans, context); | 580 SetNumItemsBeforeAssociation(&trans, context); |
| 581 initial_duplicate_count = context->duplicate_count(); | 581 initial_duplicate_count = context->duplicate_count(); |
| 582 | 582 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 594 // position as the corresponding sync node. | 594 // position as the corresponding sync node. |
| 595 // If a matching node is found, update the properties of it from the | 595 // If a matching node is found, update the properties of it from the |
| 596 // corresponding sync node. | 596 // corresponding sync node. |
| 597 // * When all children sync nodes are done, add the extra children bookmark | 597 // * When all children sync nodes are done, add the extra children bookmark |
| 598 // nodes to the sync parent node. | 598 // nodes to the sync parent node. |
| 599 // | 599 // |
| 600 // The best match algorithm uses folder title or bookmark title/url to | 600 // The best match algorithm uses folder title or bookmark title/url to |
| 601 // perform the primary match. If there are multiple match candidates it | 601 // perform the primary match. If there are multiple match candidates it |
| 602 // selects the preferred one based on sync node external ID match to the | 602 // selects the preferred one based on sync node external ID match to the |
| 603 // bookmark folder ID. | 603 // bookmark folder ID. |
| 604 int64 sync_parent_id; | 604 int64_t sync_parent_id; |
| 605 while (context->PopNode(&sync_parent_id)) { | 605 while (context->PopNode(&sync_parent_id)) { |
| 606 syncer::ReadNode sync_parent(&trans); | 606 syncer::ReadNode sync_parent(&trans); |
| 607 if (sync_parent.InitByIdLookup(sync_parent_id) != | 607 if (sync_parent.InitByIdLookup(sync_parent_id) != |
| 608 syncer::BaseNode::INIT_OK) { | 608 syncer::BaseNode::INIT_OK) { |
| 609 return unrecoverable_error_handler_->CreateAndUploadError( | 609 return unrecoverable_error_handler_->CreateAndUploadError( |
| 610 FROM_HERE, "Failed to lookup node.", model_type()); | 610 FROM_HERE, "Failed to lookup node.", model_type()); |
| 611 } | 611 } |
| 612 // Only folder nodes are pushed on to the stack. | 612 // Only folder nodes are pushed on to the stack. |
| 613 DCHECK(sync_parent.GetIsFolder()); | 613 DCHECK(sync_parent.GetIsFolder()); |
| 614 | 614 |
| 615 const BookmarkNode* parent_node = GetChromeNodeFromSyncId(sync_parent_id); | 615 const BookmarkNode* parent_node = GetChromeNodeFromSyncId(sync_parent_id); |
| 616 if (!parent_node) { | 616 if (!parent_node) { |
| 617 return unrecoverable_error_handler_->CreateAndUploadError( | 617 return unrecoverable_error_handler_->CreateAndUploadError( |
| 618 FROM_HERE, "Failed to find bookmark node for sync id.", | 618 FROM_HERE, "Failed to find bookmark node for sync id.", |
| 619 model_type()); | 619 model_type()); |
| 620 } | 620 } |
| 621 DCHECK(parent_node->is_folder()); | 621 DCHECK(parent_node->is_folder()); |
| 622 | 622 |
| 623 std::vector<int64> children; | 623 std::vector<int64_t> children; |
| 624 sync_parent.GetChildIds(&children); | 624 sync_parent.GetChildIds(&children); |
| 625 | 625 |
| 626 error = BuildAssociations(&trans, parent_node, children, context); | 626 error = BuildAssociations(&trans, parent_node, children, context); |
| 627 if (error.IsSet()) | 627 if (error.IsSet()) |
| 628 return error; | 628 return error; |
| 629 } | 629 } |
| 630 | 630 |
| 631 SetNumItemsAfterAssociation(&trans, context); | 631 SetNumItemsAfterAssociation(&trans, context); |
| 632 } | 632 } |
| 633 | 633 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 655 context->native_model_sync_state(), | 655 context->native_model_sync_state(), |
| 656 NATIVE_MODEL_SYNC_STATE_COUNT); | 656 NATIVE_MODEL_SYNC_STATE_COUNT); |
| 657 } | 657 } |
| 658 | 658 |
| 659 return syncer::SyncError(); | 659 return syncer::SyncError(); |
| 660 } | 660 } |
| 661 | 661 |
| 662 syncer::SyncError BookmarkModelAssociator::BuildAssociations( | 662 syncer::SyncError BookmarkModelAssociator::BuildAssociations( |
| 663 syncer::WriteTransaction* trans, | 663 syncer::WriteTransaction* trans, |
| 664 const BookmarkNode* parent_node, | 664 const BookmarkNode* parent_node, |
| 665 const std::vector<int64>& sync_ids, | 665 const std::vector<int64_t>& sync_ids, |
| 666 Context* context) { | 666 Context* context) { |
| 667 BookmarkNodeFinder node_finder(parent_node); | 667 BookmarkNodeFinder node_finder(parent_node); |
| 668 | 668 |
| 669 int index = 0; | 669 int index = 0; |
| 670 for (std::vector<int64>::const_iterator it = sync_ids.begin(); | 670 for (std::vector<int64_t>::const_iterator it = sync_ids.begin(); |
| 671 it != sync_ids.end(); ++it) { | 671 it != sync_ids.end(); ++it) { |
| 672 int64 sync_child_id = *it; | 672 int64_t sync_child_id = *it; |
| 673 syncer::ReadNode sync_child_node(trans); | 673 syncer::ReadNode sync_child_node(trans); |
| 674 if (sync_child_node.InitByIdLookup(sync_child_id) != | 674 if (sync_child_node.InitByIdLookup(sync_child_id) != |
| 675 syncer::BaseNode::INIT_OK) { | 675 syncer::BaseNode::INIT_OK) { |
| 676 return unrecoverable_error_handler_->CreateAndUploadError( | 676 return unrecoverable_error_handler_->CreateAndUploadError( |
| 677 FROM_HERE, "Failed to lookup node.", model_type()); | 677 FROM_HERE, "Failed to lookup node.", model_type()); |
| 678 } | 678 } |
| 679 | 679 |
| 680 int64 external_id = sync_child_node.GetExternalId(); | 680 int64_t external_id = sync_child_node.GetExternalId(); |
| 681 GURL url(sync_child_node.GetBookmarkSpecifics().url()); | 681 GURL url(sync_child_node.GetBookmarkSpecifics().url()); |
| 682 const BookmarkNode* child_node = node_finder.FindBookmarkNode( | 682 const BookmarkNode* child_node = node_finder.FindBookmarkNode( |
| 683 url, sync_child_node.GetTitle(), sync_child_node.GetIsFolder(), | 683 url, sync_child_node.GetTitle(), sync_child_node.GetIsFolder(), |
| 684 external_id); | 684 external_id); |
| 685 if (child_node) { | 685 if (child_node) { |
| 686 // Skip local node update if the local model version matches and | 686 // Skip local node update if the local model version matches and |
| 687 // the node is already associated and in the right position. | 687 // the node is already associated and in the right position. |
| 688 bool is_in_sync = (context->native_model_sync_state() == IN_SYNC) && | 688 bool is_in_sync = (context->native_model_sync_state() == IN_SYNC) && |
| 689 (child_node->id() == external_id) && | 689 (child_node->id() == external_id) && |
| 690 (index < parent_node->child_count()) && | 690 (index < parent_node->child_count()) && |
| (...skipping 27 matching lines...) Expand all Loading... |
| 718 context->PushNode(sync_child_id); | 718 context->PushNode(sync_child_id); |
| 719 ++index; | 719 ++index; |
| 720 } | 720 } |
| 721 | 721 |
| 722 // At this point all the children nodes of the parent sync node have | 722 // At this point all the children nodes of the parent sync node have |
| 723 // corresponding children in the parent bookmark node and they are all in | 723 // corresponding children in the parent bookmark node and they are all in |
| 724 // the right positions: from 0 to index - 1. | 724 // the right positions: from 0 to index - 1. |
| 725 // So the children starting from index in the parent bookmark node are the | 725 // So the children starting from index in the parent bookmark node are the |
| 726 // ones that are not present in the parent sync node. So create them. | 726 // ones that are not present in the parent sync node. So create them. |
| 727 for (int i = index; i < parent_node->child_count(); ++i) { | 727 for (int i = index; i < parent_node->child_count(); ++i) { |
| 728 int64 sync_child_id = BookmarkChangeProcessor::CreateSyncNode( | 728 int64_t sync_child_id = BookmarkChangeProcessor::CreateSyncNode( |
| 729 parent_node, bookmark_model_, i, trans, this, | 729 parent_node, bookmark_model_, i, trans, this, |
| 730 unrecoverable_error_handler_); | 730 unrecoverable_error_handler_); |
| 731 if (syncer::kInvalidId == sync_child_id) { | 731 if (syncer::kInvalidId == sync_child_id) { |
| 732 return unrecoverable_error_handler_->CreateAndUploadError( | 732 return unrecoverable_error_handler_->CreateAndUploadError( |
| 733 FROM_HERE, "Failed to create sync node.", model_type()); | 733 FROM_HERE, "Failed to create sync node.", model_type()); |
| 734 } | 734 } |
| 735 | 735 |
| 736 context->IncrementSyncItemsAdded(); | 736 context->IncrementSyncItemsAdded(); |
| 737 const BookmarkNode* child_node = parent_node->GetChild(i); | 737 const BookmarkNode* child_node = parent_node->GetChild(i); |
| 738 context->MarkForVersionUpdate(child_node); | 738 context->MarkForVersionUpdate(child_node); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 model_type()); | 776 model_type()); |
| 777 return nullptr; | 777 return nullptr; |
| 778 } | 778 } |
| 779 | 779 |
| 780 context->UpdateDuplicateCount(bookmark_title, url); | 780 context->UpdateDuplicateCount(bookmark_title, url); |
| 781 return child_node; | 781 return child_node; |
| 782 } | 782 } |
| 783 | 783 |
| 784 int BookmarkModelAssociator::RemoveSyncNodeHierarchy( | 784 int BookmarkModelAssociator::RemoveSyncNodeHierarchy( |
| 785 syncer::WriteTransaction* trans, | 785 syncer::WriteTransaction* trans, |
| 786 int64 sync_id) { | 786 int64_t sync_id) { |
| 787 syncer::WriteNode sync_node(trans); | 787 syncer::WriteNode sync_node(trans); |
| 788 if (sync_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) { | 788 if (sync_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) { |
| 789 syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, | 789 syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, |
| 790 "Could not lookup bookmark node for ID deletion.", | 790 "Could not lookup bookmark node for ID deletion.", |
| 791 syncer::BOOKMARKS); | 791 syncer::BOOKMARKS); |
| 792 unrecoverable_error_handler_->OnSingleDataTypeUnrecoverableError(error); | 792 unrecoverable_error_handler_->OnSingleDataTypeUnrecoverableError(error); |
| 793 return 0; | 793 return 0; |
| 794 } | 794 } |
| 795 | 795 |
| 796 return BookmarkChangeProcessor::RemoveSyncNodeHierarchy(trans, &sync_node, | 796 return BookmarkChangeProcessor::RemoveSyncNodeHierarchy(trans, &sync_node, |
| 797 this); | 797 this); |
| 798 } | 798 } |
| 799 | 799 |
| 800 struct FolderInfo { | 800 struct FolderInfo { |
| 801 FolderInfo(const BookmarkNode* f, const BookmarkNode* p, int64 id) | 801 FolderInfo(const BookmarkNode* f, const BookmarkNode* p, int64_t id) |
| 802 : folder(f), parent(p), sync_id(id) {} | 802 : folder(f), parent(p), sync_id(id) {} |
| 803 const BookmarkNode* folder; | 803 const BookmarkNode* folder; |
| 804 const BookmarkNode* parent; | 804 const BookmarkNode* parent; |
| 805 int64 sync_id; | 805 int64_t sync_id; |
| 806 }; | 806 }; |
| 807 typedef std::vector<FolderInfo> FolderInfoList; | 807 typedef std::vector<FolderInfo> FolderInfoList; |
| 808 | 808 |
| 809 void BookmarkModelAssociator::ApplyDeletesFromSyncJournal( | 809 void BookmarkModelAssociator::ApplyDeletesFromSyncJournal( |
| 810 syncer::BaseTransaction* trans, | 810 syncer::BaseTransaction* trans, |
| 811 Context* context) { | 811 Context* context) { |
| 812 syncer::BookmarkDeleteJournalList bk_delete_journals; | 812 syncer::BookmarkDeleteJournalList bk_delete_journals; |
| 813 syncer::DeleteJournal::GetBookmarkDeleteJournals(trans, &bk_delete_journals); | 813 syncer::DeleteJournal::GetBookmarkDeleteJournals(trans, &bk_delete_journals); |
| 814 if (bk_delete_journals.empty()) | 814 if (bk_delete_journals.empty()) |
| 815 return; | 815 return; |
| 816 | 816 |
| 817 size_t num_journals_unmatched = bk_delete_journals.size(); | 817 size_t num_journals_unmatched = bk_delete_journals.size(); |
| 818 | 818 |
| 819 // Make a set of all external IDs in the delete journal, | 819 // Make a set of all external IDs in the delete journal, |
| 820 // ignore entries with unset external IDs. | 820 // ignore entries with unset external IDs. |
| 821 std::set<int64> journaled_external_ids; | 821 std::set<int64_t> journaled_external_ids; |
| 822 for (size_t i = 0; i < num_journals_unmatched; i++) { | 822 for (size_t i = 0; i < num_journals_unmatched; i++) { |
| 823 if (bk_delete_journals[i].external_id != 0) | 823 if (bk_delete_journals[i].external_id != 0) |
| 824 journaled_external_ids.insert(bk_delete_journals[i].external_id); | 824 journaled_external_ids.insert(bk_delete_journals[i].external_id); |
| 825 } | 825 } |
| 826 | 826 |
| 827 // Check bookmark model from top to bottom. | 827 // Check bookmark model from top to bottom. |
| 828 BookmarkStack dfs_stack; | 828 BookmarkStack dfs_stack; |
| 829 for (BookmarkList::const_iterator it = context->bookmark_roots().begin(); | 829 for (BookmarkList::const_iterator it = context->bookmark_roots().begin(); |
| 830 it != context->bookmark_roots().end(); ++it) { | 830 it != context->bookmark_roots().end(); ++it) { |
| 831 dfs_stack.push(*it); | 831 dfs_stack.push(*it); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 bk_delete_journals[journal_index] = | 881 bk_delete_journals[journal_index] = |
| 882 bk_delete_journals[--num_journals_unmatched]; | 882 bk_delete_journals[--num_journals_unmatched]; |
| 883 break; | 883 break; |
| 884 } | 884 } |
| 885 } | 885 } |
| 886 } | 886 } |
| 887 } | 887 } |
| 888 | 888 |
| 889 // Ids of sync nodes not found in bookmark model, meaning the deletions are | 889 // Ids of sync nodes not found in bookmark model, meaning the deletions are |
| 890 // persisted and correponding delete journals can be dropped. | 890 // persisted and correponding delete journals can be dropped. |
| 891 std::set<int64> journals_to_purge; | 891 std::set<int64_t> journals_to_purge; |
| 892 | 892 |
| 893 // Remove empty folders from bottom to top. | 893 // Remove empty folders from bottom to top. |
| 894 for (FolderInfoList::reverse_iterator it = folders_matched.rbegin(); | 894 for (FolderInfoList::reverse_iterator it = folders_matched.rbegin(); |
| 895 it != folders_matched.rend(); ++it) { | 895 it != folders_matched.rend(); ++it) { |
| 896 if (it->folder->child_count() == 0) { | 896 if (it->folder->child_count() == 0) { |
| 897 bookmark_model_->Remove(it->folder); | 897 bookmark_model_->Remove(it->folder); |
| 898 context->IncrementLocalItemsDeleted(); | 898 context->IncrementLocalItemsDeleted(); |
| 899 } else { | 899 } else { |
| 900 // Keep non-empty folder and remove its journal so that it won't match | 900 // Keep non-empty folder and remove its journal so that it won't match |
| 901 // again in the future. | 901 // again in the future. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 921 void BookmarkModelAssociator::PersistAssociations() { | 921 void BookmarkModelAssociator::PersistAssociations() { |
| 922 // If there are no dirty associations we have nothing to do. We handle this | 922 // If there are no dirty associations we have nothing to do. We handle this |
| 923 // explicity instead of letting the for loop do it to avoid creating a write | 923 // explicity instead of letting the for loop do it to avoid creating a write |
| 924 // transaction in this case. | 924 // transaction in this case. |
| 925 if (dirty_associations_sync_ids_.empty()) { | 925 if (dirty_associations_sync_ids_.empty()) { |
| 926 DCHECK(id_map_.empty()); | 926 DCHECK(id_map_.empty()); |
| 927 DCHECK(id_map_inverse_.empty()); | 927 DCHECK(id_map_inverse_.empty()); |
| 928 return; | 928 return; |
| 929 } | 929 } |
| 930 | 930 |
| 931 int64 new_version = syncer::syncable::kInvalidTransactionVersion; | 931 int64_t new_version = syncer::syncable::kInvalidTransactionVersion; |
| 932 std::vector<const BookmarkNode*> bnodes; | 932 std::vector<const BookmarkNode*> bnodes; |
| 933 { | 933 { |
| 934 syncer::WriteTransaction trans(FROM_HERE, user_share_, &new_version); | 934 syncer::WriteTransaction trans(FROM_HERE, user_share_, &new_version); |
| 935 DirtyAssociationsSyncIds::iterator iter; | 935 DirtyAssociationsSyncIds::iterator iter; |
| 936 for (iter = dirty_associations_sync_ids_.begin(); | 936 for (iter = dirty_associations_sync_ids_.begin(); |
| 937 iter != dirty_associations_sync_ids_.end(); | 937 iter != dirty_associations_sync_ids_.end(); |
| 938 ++iter) { | 938 ++iter) { |
| 939 int64 sync_id = *iter; | 939 int64_t sync_id = *iter; |
| 940 syncer::WriteNode sync_node(&trans); | 940 syncer::WriteNode sync_node(&trans); |
| 941 if (sync_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) { | 941 if (sync_node.InitByIdLookup(sync_id) != syncer::BaseNode::INIT_OK) { |
| 942 syncer::SyncError error( | 942 syncer::SyncError error( |
| 943 FROM_HERE, | 943 FROM_HERE, |
| 944 syncer::SyncError::DATATYPE_ERROR, | 944 syncer::SyncError::DATATYPE_ERROR, |
| 945 "Could not lookup bookmark node for ID persistence.", | 945 "Could not lookup bookmark node for ID persistence.", |
| 946 syncer::BOOKMARKS); | 946 syncer::BOOKMARKS); |
| 947 unrecoverable_error_handler_->OnSingleDataTypeUnrecoverableError(error); | 947 unrecoverable_error_handler_->OnSingleDataTypeUnrecoverableError(error); |
| 948 return; | 948 return; |
| 949 } | 949 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 965 // We only access the cryptographer while holding a transaction. | 965 // We only access the cryptographer while holding a transaction. |
| 966 syncer::ReadTransaction trans(FROM_HERE, user_share_); | 966 syncer::ReadTransaction trans(FROM_HERE, user_share_); |
| 967 const syncer::ModelTypeSet encrypted_types = trans.GetEncryptedTypes(); | 967 const syncer::ModelTypeSet encrypted_types = trans.GetEncryptedTypes(); |
| 968 return !encrypted_types.Has(syncer::BOOKMARKS) || | 968 return !encrypted_types.Has(syncer::BOOKMARKS) || |
| 969 trans.GetCryptographer()->is_ready(); | 969 trans.GetCryptographer()->is_ready(); |
| 970 } | 970 } |
| 971 | 971 |
| 972 syncer::SyncError BookmarkModelAssociator::CheckModelSyncState( | 972 syncer::SyncError BookmarkModelAssociator::CheckModelSyncState( |
| 973 Context* context) const { | 973 Context* context) const { |
| 974 DCHECK_EQ(context->native_model_sync_state(), UNSET); | 974 DCHECK_EQ(context->native_model_sync_state(), UNSET); |
| 975 int64 native_version = | 975 int64_t native_version = |
| 976 bookmark_model_->root_node()->sync_transaction_version(); | 976 bookmark_model_->root_node()->sync_transaction_version(); |
| 977 | 977 |
| 978 syncer::ReadTransaction trans(FROM_HERE, user_share_); | 978 syncer::ReadTransaction trans(FROM_HERE, user_share_); |
| 979 int64 sync_version = trans.GetModelVersion(syncer::BOOKMARKS); | 979 int64_t sync_version = trans.GetModelVersion(syncer::BOOKMARKS); |
| 980 context->SetPreAssociationVersions(native_version, sync_version); | 980 context->SetPreAssociationVersions(native_version, sync_version); |
| 981 | 981 |
| 982 if (native_version != syncer::syncable::kInvalidTransactionVersion) { | 982 if (native_version != syncer::syncable::kInvalidTransactionVersion) { |
| 983 if (native_version == sync_version) { | 983 if (native_version == sync_version) { |
| 984 context->set_native_model_sync_state(IN_SYNC); | 984 context->set_native_model_sync_state(IN_SYNC); |
| 985 } else { | 985 } else { |
| 986 UMA_HISTOGRAM_ENUMERATION("Sync.LocalModelOutOfSync", | 986 UMA_HISTOGRAM_ENUMERATION("Sync.LocalModelOutOfSync", |
| 987 ModelTypeToHistogramInt(syncer::BOOKMARKS), | 987 ModelTypeToHistogramInt(syncer::BOOKMARKS), |
| 988 syncer::MODEL_TYPE_COUNT); | 988 syncer::MODEL_TYPE_COUNT); |
| 989 | 989 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1007 syncer::BOOKMARKS); | 1007 syncer::BOOKMARKS); |
| 1008 } else { | 1008 } else { |
| 1009 context->set_native_model_sync_state(BEHIND); | 1009 context->set_native_model_sync_state(BEHIND); |
| 1010 } | 1010 } |
| 1011 } | 1011 } |
| 1012 } | 1012 } |
| 1013 return syncer::SyncError(); | 1013 return syncer::SyncError(); |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 } // namespace browser_sync | 1016 } // namespace browser_sync |
| OLD | NEW |