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

Side by Side Diff: chrome/browser/sync/glue/bookmark_model_associator.cc

Issue 906403003: Revert of Use external ID to match native model nodes during bookmark association. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 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
OLDNEW
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 "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/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 const int kTitleLimitBytes = 255; 69 const int kTitleLimitBytes = 255;
70 70
71 // Provides the following abstraction: given a parent bookmark node, find best 71 // Provides the following abstraction: given a parent bookmark node, find best
72 // matching child node for many sync nodes. 72 // matching child node for many sync nodes.
73 class BookmarkNodeFinder { 73 class BookmarkNodeFinder {
74 public: 74 public:
75 // Creates an instance with the given parent bookmark node. 75 // Creates an instance with the given parent bookmark node.
76 explicit BookmarkNodeFinder(const BookmarkNode* parent_node); 76 explicit BookmarkNodeFinder(const BookmarkNode* parent_node);
77 77
78 // Finds the bookmark node that matches the given url, title and folder 78 // Finds the bookmark node that matches the given url, title and folder
79 // attribute. Returns the matching node if one exists; NULL otherwise. 79 // attribute. Returns the matching node if one exists; NULL otherwise. If a
80 // If there are multiple matches then a node with ID matching |preferred_id| 80 // matching node is found, it's removed for further matches.
81 // is returned; otherwise the first matching node is returned.
82 // If a matching node is found, it's removed for further matches.
83 const BookmarkNode* FindBookmarkNode(const GURL& url, 81 const BookmarkNode* FindBookmarkNode(const GURL& url,
84 const std::string& title, 82 const std::string& title,
85 bool is_folder, 83 bool is_folder);
86 int64 preferred_id);
87
88 // Returns true if |bookmark_node| matches the specified |url|,
89 // |title|, and |is_folder| flags.
90 static bool NodeMatches(const BookmarkNode* bookmark_node,
91 const GURL& url,
92 const std::string& title,
93 bool is_folder);
94 84
95 private: 85 private:
96 // Maps bookmark node titles to instances, duplicates allowed. 86 // Maps bookmark node titles to instances, duplicates allowed.
97 // Titles are converted to the sync internal format before 87 // Titles are converted to the sync internal format before
98 // being used as keys for the map. 88 // being used as keys for the map.
99 typedef base::hash_multimap<std::string, 89 typedef base::hash_multimap<std::string,
100 const BookmarkNode*> BookmarkNodeMap; 90 const BookmarkNode*> BookmarkNodeMap;
101 typedef std::pair<BookmarkNodeMap::iterator, 91 typedef std::pair<BookmarkNodeMap::iterator,
102 BookmarkNodeMap::iterator> BookmarkNodeRange; 92 BookmarkNodeMap::iterator> BookmarkNodeRange;
103 93
104 // Converts and truncates bookmark titles in the form sync does internally 94 // Converts and truncates bookmark titles in the form sync does internally
105 // to avoid mismatches due to sync munging titles. 95 // to avoid mismatches due to sync munging titles.
106 static void ConvertTitleToSyncInternalFormat(const std::string& input, 96 void ConvertTitleToSyncInternalFormat(
107 std::string* output); 97 const std::string& input, std::string* output);
108 98
109 const BookmarkNode* parent_node_; 99 const BookmarkNode* parent_node_;
110 BookmarkNodeMap child_nodes_; 100 BookmarkNodeMap child_nodes_;
111 101
112 DISALLOW_COPY_AND_ASSIGN(BookmarkNodeFinder); 102 DISALLOW_COPY_AND_ASSIGN(BookmarkNodeFinder);
113 }; 103 };
114 104
115 class ScopedAssociationUpdater { 105 class ScopedAssociationUpdater {
116 public: 106 public:
117 explicit ScopedAssociationUpdater(BookmarkModel* model) { 107 explicit ScopedAssociationUpdater(BookmarkModel* model) {
(...skipping 17 matching lines...) Expand all
135 const BookmarkNode* child_node = parent_node_->GetChild(i); 125 const BookmarkNode* child_node = parent_node_->GetChild(i);
136 126
137 std::string title = base::UTF16ToUTF8(child_node->GetTitle()); 127 std::string title = base::UTF16ToUTF8(child_node->GetTitle());
138 ConvertTitleToSyncInternalFormat(title, &title); 128 ConvertTitleToSyncInternalFormat(title, &title);
139 129
140 child_nodes_.insert(std::make_pair(title, child_node)); 130 child_nodes_.insert(std::make_pair(title, child_node));
141 } 131 }
142 } 132 }
143 133
144 const BookmarkNode* BookmarkNodeFinder::FindBookmarkNode( 134 const BookmarkNode* BookmarkNodeFinder::FindBookmarkNode(
145 const GURL& url, 135 const GURL& url, const std::string& title, bool is_folder) {
146 const std::string& title,
147 bool is_folder,
148 int64 preferred_id) {
149 const BookmarkNode* match = nullptr;
150
151 // First lookup a range of bookmarks with the same title. 136 // First lookup a range of bookmarks with the same title.
152 std::string adjusted_title; 137 std::string adjusted_title;
153 ConvertTitleToSyncInternalFormat(title, &adjusted_title); 138 ConvertTitleToSyncInternalFormat(title, &adjusted_title);
154 BookmarkNodeRange range = child_nodes_.equal_range(adjusted_title); 139 BookmarkNodeRange range = child_nodes_.equal_range(adjusted_title);
155 BookmarkNodeMap::iterator match_iter = range.second;
156 for (BookmarkNodeMap::iterator iter = range.first; 140 for (BookmarkNodeMap::iterator iter = range.first;
157 iter != range.second; 141 iter != range.second;
158 ++iter) { 142 ++iter) {
143
159 // Then within the range match the node by the folder bit 144 // Then within the range match the node by the folder bit
160 // and the url. 145 // and the url.
161 const BookmarkNode* node = iter->second; 146 const BookmarkNode* node = iter->second;
162 if (is_folder == node->is_folder() && url == node->url()) { 147 if (is_folder == node->is_folder() && url == node->url()) {
163 if (node->id() == preferred_id || preferred_id == 0) { 148 // Remove the matched node so we don't match with it again.
164 // Preferred match - use this node. 149 child_nodes_.erase(iter);
165 match = node; 150 return node;
166 match_iter = iter;
167 break;
168 } else if (match == nullptr) {
169 // First match - continue iterating.
170 match = node;
171 match_iter = iter;
172 }
173 } 151 }
174 } 152 }
175 153
176 if (match_iter != range.second) { 154 return NULL;
177 // Remove the matched node so we don't match with it again.
178 child_nodes_.erase(match_iter);
179 }
180
181 return match;
182 } 155 }
183 156
184 /* static */
185 bool BookmarkNodeFinder::NodeMatches(const BookmarkNode* bookmark_node,
186 const GURL& url,
187 const std::string& title,
188 bool is_folder) {
189 if (url != bookmark_node->url() || is_folder != bookmark_node->is_folder()) {
190 return false;
191 }
192
193 // The title passed to this method comes from a sync directory entry.
194 // The following two lines are needed to make the native bookmark title
195 // comparable. The same conversion is used in BookmarkNodeFinder constructor.
196 std::string bookmark_title = base::UTF16ToUTF8(bookmark_node->GetTitle());
197 ConvertTitleToSyncInternalFormat(bookmark_title, &bookmark_title);
198 return title == bookmark_title;
199 }
200
201 /* static */
202 void BookmarkNodeFinder::ConvertTitleToSyncInternalFormat( 157 void BookmarkNodeFinder::ConvertTitleToSyncInternalFormat(
203 const std::string& input, std::string* output) { 158 const std::string& input, std::string* output) {
204 syncer::SyncAPINameToServerName(input, output); 159 syncer::SyncAPINameToServerName(input, output);
205 base::TruncateUTF8ToByteSize(*output, kTitleLimitBytes, output); 160 base::TruncateUTF8ToByteSize(*output, kTitleLimitBytes, output);
206 } 161 }
207 162
208 // Helper class to build an index of bookmark nodes by their IDs. 163 // Helper class to build an index of bookmark nodes by their IDs.
209 class BookmarkNodeIdIndex { 164 class BookmarkNodeIdIndex {
210 public: 165 public:
211 BookmarkNodeIdIndex() { } 166 BookmarkNodeIdIndex() { }
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 } 339 }
385 340
386 // Sync model has user created nodes if any of the permanent nodes has 341 // Sync model has user created nodes if any of the permanent nodes has
387 // children. 342 // children.
388 *has_nodes = bookmark_bar_node.HasChildren() || 343 *has_nodes = bookmark_bar_node.HasChildren() ||
389 other_bookmarks_node.HasChildren() || 344 other_bookmarks_node.HasChildren() ||
390 (has_mobile_folder && mobile_bookmarks_node.HasChildren()); 345 (has_mobile_folder && mobile_bookmarks_node.HasChildren());
391 return true; 346 return true;
392 } 347 }
393 348
349 bool BookmarkModelAssociator::NodesMatch(
350 const BookmarkNode* bookmark,
351 const syncer::BaseNode* sync_node) const {
352 std::string truncated_title = base::UTF16ToUTF8(bookmark->GetTitle());
353 base::TruncateUTF8ToByteSize(truncated_title,
354 kTitleLimitBytes,
355 &truncated_title);
356 if (truncated_title != sync_node->GetTitle())
357 return false;
358 if (bookmark->is_folder() != sync_node->GetIsFolder())
359 return false;
360 if (bookmark->is_url()) {
361 if (bookmark->url() != GURL(sync_node->GetBookmarkSpecifics().url()))
362 return false;
363 }
364 // Don't compare favicons here, because they are not really
365 // user-updated and we don't have versioning information -- a site changing
366 // its favicon shouldn't result in a bookmark mismatch.
367 return true;
368 }
369
394 bool BookmarkModelAssociator::AssociateTaggedPermanentNode( 370 bool BookmarkModelAssociator::AssociateTaggedPermanentNode(
395 const BookmarkNode* permanent_node, const std::string&tag) { 371 const BookmarkNode* permanent_node, const std::string&tag) {
396 // Do nothing if |permanent_node| is already initialized and associated. 372 // Do nothing if |permanent_node| is already initialized and associated.
397 int64 sync_id = GetSyncIdFromChromeId(permanent_node->id()); 373 int64 sync_id = GetSyncIdFromChromeId(permanent_node->id());
398 if (sync_id != syncer::kInvalidId) 374 if (sync_id != syncer::kInvalidId)
399 return true; 375 return true;
400 if (!GetSyncIdForTaggedNode(tag, &sync_id)) 376 if (!GetSyncIdForTaggedNode(tag, &sync_id))
401 return false; 377 return false;
402 378
403 Associate(permanent_node, sync_id); 379 Associate(permanent_node, sync_id);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 // Match up the roots and recursively do the following: 417 // Match up the roots and recursively do the following:
442 // * For each sync node for the current sync parent node, find the best 418 // * For each sync node for the current sync parent node, find the best
443 // matching bookmark node under the corresponding bookmark parent node. 419 // matching bookmark node under the corresponding bookmark parent node.
444 // If no matching node is found, create a new bookmark node in the same 420 // If no matching node is found, create a new bookmark node in the same
445 // position as the corresponding sync node. 421 // position as the corresponding sync node.
446 // If a matching node is found, update the properties of it from the 422 // If a matching node is found, update the properties of it from the
447 // corresponding sync node. 423 // corresponding sync node.
448 // * When all children sync nodes are done, add the extra children bookmark 424 // * When all children sync nodes are done, add the extra children bookmark
449 // nodes to the sync parent node. 425 // nodes to the sync parent node.
450 // 426 //
451 // The best match algorithm uses folder title or bookmark title/url to 427 // This algorithm will do a good job of merging when folder names are a good
452 // perform the primary match. If there are multiple match candidates it 428 // indicator of the two folders being the same. It will handle reordering and
453 // selects the preferred one based on sync node external ID match to the 429 // new node addition very well (without creating duplicates).
454 // bookmark folder ID. 430 // This algorithm will not do well if the folder name has changes but the
431 // children under them are all the same.
455 432
456 DCHECK(bookmark_model_->loaded()); 433 DCHECK(bookmark_model_->loaded());
457 434
458 // To prime our association, we associate the top-level nodes, Bookmark Bar 435 // To prime our association, we associate the top-level nodes, Bookmark Bar
459 // and Other Bookmarks. 436 // and Other Bookmarks.
460 if (!AssociateTaggedPermanentNode(bookmark_model_->bookmark_bar_node(), 437 if (!AssociateTaggedPermanentNode(bookmark_model_->bookmark_bar_node(),
461 kBookmarkBarTag)) { 438 kBookmarkBarTag)) {
462 return unrecoverable_error_handler_->CreateAndUploadError( 439 return unrecoverable_error_handler_->CreateAndUploadError(
463 FROM_HERE, 440 FROM_HERE,
464 "Bookmark bar node not found", 441 "Bookmark bar node not found",
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 syncer::WriteTransaction trans(FROM_HERE, user_share_); 485 syncer::WriteTransaction trans(FROM_HERE, user_share_);
509 syncer::ReadNode bm_root(&trans); 486 syncer::ReadNode bm_root(&trans);
510 if (bm_root.InitTypeRoot(syncer::BOOKMARKS) == syncer::BaseNode::INIT_OK) { 487 if (bm_root.InitTypeRoot(syncer::BOOKMARKS) == syncer::BaseNode::INIT_OK) {
511 syncer_merge_result->set_num_items_before_association( 488 syncer_merge_result->set_num_items_before_association(
512 bm_root.GetTotalNodeCount()); 489 bm_root.GetTotalNodeCount());
513 } 490 }
514 local_merge_result->set_num_items_before_association( 491 local_merge_result->set_num_items_before_association(
515 bookmark_model_->root_node()->GetTotalNodeCount()); 492 bookmark_model_->root_node()->GetTotalNodeCount());
516 493
517 // Remove obsolete bookmarks according to sync delete journal. 494 // Remove obsolete bookmarks according to sync delete journal.
518 // TODO (stanisc): crbug.com/456876: rewrite this to avoid a separate
519 // traversal and instead perform deletes at the end of the loop below where
520 // the unmatched bookmark nodes are created as sync nodes.
521 local_merge_result->set_num_items_deleted( 495 local_merge_result->set_num_items_deleted(
522 ApplyDeletesFromSyncJournal(&trans)); 496 ApplyDeletesFromSyncJournal(&trans));
523 497
524 while (!dfs_stack.empty()) { 498 while (!dfs_stack.empty()) {
525 int64 sync_parent_id = dfs_stack.top(); 499 int64 sync_parent_id = dfs_stack.top();
526 dfs_stack.pop(); 500 dfs_stack.pop();
527 501
528 syncer::ReadNode sync_parent(&trans); 502 syncer::ReadNode sync_parent(&trans);
529 if (sync_parent.InitByIdLookup(sync_parent_id) != 503 if (sync_parent.InitByIdLookup(sync_parent_id) !=
530 syncer::BaseNode::INIT_OK) { 504 syncer::BaseNode::INIT_OK) {
(...skipping 22 matching lines...) Expand all
553 int64 sync_child_id = *it; 527 int64 sync_child_id = *it;
554 syncer::ReadNode sync_child_node(&trans); 528 syncer::ReadNode sync_child_node(&trans);
555 if (sync_child_node.InitByIdLookup(sync_child_id) != 529 if (sync_child_node.InitByIdLookup(sync_child_id) !=
556 syncer::BaseNode::INIT_OK) { 530 syncer::BaseNode::INIT_OK) {
557 return unrecoverable_error_handler_->CreateAndUploadError( 531 return unrecoverable_error_handler_->CreateAndUploadError(
558 FROM_HERE, 532 FROM_HERE,
559 "Failed to lookup node.", 533 "Failed to lookup node.",
560 model_type()); 534 model_type());
561 } 535 }
562 536
563 const BookmarkNode* child_node = node_finder.FindBookmarkNode( 537 const BookmarkNode* child_node = NULL;
538 child_node = node_finder.FindBookmarkNode(
564 GURL(sync_child_node.GetBookmarkSpecifics().url()), 539 GURL(sync_child_node.GetBookmarkSpecifics().url()),
565 sync_child_node.GetTitle(), sync_child_node.GetIsFolder(), 540 sync_child_node.GetTitle(),
566 sync_child_node.GetExternalId()); 541 sync_child_node.GetIsFolder());
567 if (child_node) { 542 if (child_node) {
568 Associate(child_node, sync_child_id); 543 Associate(child_node, sync_child_id);
569 544
570 // All bookmarks are currently modified at association time, even if 545 // All bookmarks are currently modified at association time, even if
571 // nothing has changed. 546 // nothing has changed.
572 // TODO(sync): Only modify the bookmark model if necessary. 547 // TODO(sync): Only modify the bookmark model if necessary.
573 BookmarkChangeProcessor::UpdateBookmarkWithSyncData( 548 BookmarkChangeProcessor::UpdateBookmarkWithSyncData(
574 sync_child_node, bookmark_model_, child_node, profile_); 549 sync_child_node, bookmark_model_, child_node, profile_);
575 bookmark_model_->Move(child_node, parent_node, index); 550 bookmark_model_->Move(child_node, parent_node, index);
576 local_merge_result->set_num_items_modified( 551 local_merge_result->set_num_items_modified(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 int64 BookmarkModelAssociator::ApplyDeletesFromSyncJournal( 609 int64 BookmarkModelAssociator::ApplyDeletesFromSyncJournal(
635 syncer::BaseTransaction* trans) { 610 syncer::BaseTransaction* trans) {
636 int64 num_bookmark_deleted = 0; 611 int64 num_bookmark_deleted = 0;
637 612
638 syncer::BookmarkDeleteJournalList bk_delete_journals; 613 syncer::BookmarkDeleteJournalList bk_delete_journals;
639 syncer::DeleteJournal::GetBookmarkDeleteJournals(trans, &bk_delete_journals); 614 syncer::DeleteJournal::GetBookmarkDeleteJournals(trans, &bk_delete_journals);
640 if (bk_delete_journals.empty()) 615 if (bk_delete_journals.empty())
641 return 0; 616 return 0;
642 size_t num_journals_unmatched = bk_delete_journals.size(); 617 size_t num_journals_unmatched = bk_delete_journals.size();
643 618
644 // Make a set of all external IDs in the delete journal,
645 // ignore entries with unset external IDs.
646 std::set<int64> journaled_external_ids;
647 for (size_t i = 0; i < num_journals_unmatched; i++) {
648 if (bk_delete_journals[i].external_id != 0)
649 journaled_external_ids.insert(bk_delete_journals[i].external_id);
650 }
651
652 // Check bookmark model from top to bottom. 619 // Check bookmark model from top to bottom.
653 std::stack<const BookmarkNode*> dfs_stack; 620 std::stack<const BookmarkNode*> dfs_stack;
654 dfs_stack.push(bookmark_model_->bookmark_bar_node()); 621 dfs_stack.push(bookmark_model_->bookmark_bar_node());
655 dfs_stack.push(bookmark_model_->other_node()); 622 dfs_stack.push(bookmark_model_->other_node());
656 if (expect_mobile_bookmarks_folder_) 623 if (expect_mobile_bookmarks_folder_)
657 dfs_stack.push(bookmark_model_->mobile_node()); 624 dfs_stack.push(bookmark_model_->mobile_node());
658 // Note: the root node may have additional extra nodes. Currently none of 625 // Note: the root node may have additional extra nodes. Currently none of
659 // them are meant to sync. 626 // them are meant to sync.
660 627
661 // Remember folders that match delete journals in first pass but don't delete 628 // Remember folders that match delete journals in first pass but don't delete
662 // them in case there are bookmarks left under them. After non-folder 629 // them in case there are bookmarks left under them. After non-folder
663 // bookmarks are removed in first pass, recheck the folders in reverse order 630 // bookmarks are removed in first pass, recheck the folders in reverse order
664 // to remove empty ones. 631 // to remove empty ones.
665 FolderInfoList folders_matched; 632 FolderInfoList folders_matched;
666 while (!dfs_stack.empty() && num_journals_unmatched > 0) { 633 while (!dfs_stack.empty()) {
667 const BookmarkNode* parent = dfs_stack.top(); 634 const BookmarkNode* parent = dfs_stack.top();
668 dfs_stack.pop(); 635 dfs_stack.pop();
669 DCHECK(parent->is_folder());
670 636
671 // Enumerate folder children in reverse order to make it easier to remove 637 BookmarkNodeFinder finder(parent);
672 // bookmarks matching entries in the delete journal. 638 // Iterate through journals from back to front. Remove matched journal by
673 for (int child_index = parent->child_count() - 1; 639 // moving an unmatched journal at the tail to its position so that we can
674 child_index >= 0 && num_journals_unmatched > 0; --child_index) { 640 // read unmatched journals off the head in next loop.
675 const BookmarkNode* child = parent->GetChild(child_index); 641 for (int i = num_journals_unmatched - 1; i >= 0; --i) {
676 if (child->is_folder()) 642 const BookmarkNode* child = finder.FindBookmarkNode(
677 dfs_stack.push(child); 643 GURL(bk_delete_journals[i].specifics.bookmark().url()),
644 bk_delete_journals[i].specifics.bookmark().title(),
645 bk_delete_journals[i].is_folder);
646 if (child) {
647 if (child->is_folder()) {
648 // Remember matched folder without removing and delete only empty
649 // ones later.
650 folders_matched.push_back(FolderInfo(child, parent,
651 bk_delete_journals[i].id));
652 } else {
653 bookmark_model_->Remove(parent, parent->GetIndexOf(child));
654 ++num_bookmark_deleted;
655 }
656 // Move unmatched journal here and decrement counter.
657 bk_delete_journals[i] = bk_delete_journals[--num_journals_unmatched];
658 }
659 }
660 if (num_journals_unmatched == 0)
661 break;
678 662
679 if (journaled_external_ids.find(child->id()) == 663 for (int i = 0; i < parent->child_count(); ++i) {
680 journaled_external_ids.end()) { 664 if (parent->GetChild(i)->is_folder())
681 // Skip bookmark node which id is not in the set of external IDs. 665 dfs_stack.push(parent->GetChild(i));
682 continue;
683 }
684
685 // Iterate through the journal entries from back to front. Remove matched
686 // journal by moving an unmatched entry at the tail to the matched
687 // position so that we can read unmatched entries off the head in next
688 // loop.
689 for (int journal_index = num_journals_unmatched - 1; journal_index >= 0;
690 --journal_index) {
691 const syncer::BookmarkDeleteJournal& delete_entry =
692 bk_delete_journals[journal_index];
693 if (child->id() == delete_entry.external_id &&
694 BookmarkNodeFinder::NodeMatches(
695 child, GURL(delete_entry.specifics.bookmark().url()),
696 delete_entry.specifics.bookmark().title(),
697 delete_entry.is_folder)) {
698 if (child->is_folder()) {
699 // Remember matched folder without removing and delete only empty
700 // ones later.
701 folders_matched.push_back(
702 FolderInfo(child, parent, delete_entry.id));
703 } else {
704 bookmark_model_->Remove(parent, child_index);
705 ++num_bookmark_deleted;
706 }
707 // Move unmatched journal here and decrement counter.
708 bk_delete_journals[journal_index] =
709 bk_delete_journals[--num_journals_unmatched];
710 break;
711 }
712 }
713 } 666 }
714 } 667 }
715 668
716 // Ids of sync nodes not found in bookmark model, meaning the deletions are 669 // Ids of sync nodes not found in bookmark model, meaning the deletions are
717 // persisted and correponding delete journals can be dropped. 670 // persisted and correponding delete journals can be dropped.
718 std::set<int64> journals_to_purge; 671 std::set<int64> journals_to_purge;
719 672
720 // Remove empty folders from bottom to top. 673 // Remove empty folders from bottom to top.
721 for (FolderInfoList::reverse_iterator it = folders_matched.rbegin(); 674 for (FolderInfoList::reverse_iterator it = folders_matched.rbegin();
722 it != folders_matched.rend(); ++it) { 675 it != folders_matched.rend(); ++it) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 syncer::SyncError::PERSISTENCE_ERROR, 787 syncer::SyncError::PERSISTENCE_ERROR,
835 message, 788 message,
836 syncer::BOOKMARKS); 789 syncer::BOOKMARKS);
837 } 790 }
838 } 791 }
839 } 792 }
840 return syncer::SyncError(); 793 return syncer::SyncError();
841 } 794 }
842 795
843 } // namespace browser_sync 796 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/bookmark_model_associator.h ('k') | chrome/browser/sync/profile_sync_service_bookmark_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698