Chromium Code Reviews| Index: chrome/browser/sync/glue/bookmark_model_associator.cc |
| diff --git a/chrome/browser/sync/glue/bookmark_model_associator.cc b/chrome/browser/sync/glue/bookmark_model_associator.cc |
| index 69e4a7f091da1a3f2224c248194790d4e62cb89f..0e90ea41c97a3f7cf8a8ef97d27e67b6983a5669 100644 |
| --- a/chrome/browser/sync/glue/bookmark_model_associator.cc |
| +++ b/chrome/browser/sync/glue/bookmark_model_associator.cc |
| @@ -66,38 +66,6 @@ const char kOtherBookmarksTag[] = "other_bookmarks"; |
| // limits; see write_node.cc). |
| const int kTitleLimitBytes = 255; |
| -// Bookmark comparer for map of bookmark nodes. |
| -class BookmarkComparer { |
| - public: |
| - // Compares the two given nodes and returns whether node1 should appear |
| - // before node2 in strict weak ordering. |
| - bool operator()(const BookmarkNode* node1, |
| - const BookmarkNode* node2) const { |
| - DCHECK(node1); |
| - DCHECK(node2); |
| - |
| - // Keep folder nodes before non-folder nodes. |
| - if (node1->is_folder() != node2->is_folder()) |
| - return node1->is_folder(); |
| - |
| - // Truncate bookmark titles in the form sync does internally to avoid |
| - // mismatches due to sync munging titles. |
| - std::string title1 = base::UTF16ToUTF8(node1->GetTitle()); |
| - syncer::SyncAPINameToServerName(title1, &title1); |
| - base::TruncateUTF8ToByteSize(title1, kTitleLimitBytes, &title1); |
| - |
| - std::string title2 = base::UTF16ToUTF8(node2->GetTitle()); |
| - syncer::SyncAPINameToServerName(title2, &title2); |
| - base::TruncateUTF8ToByteSize(title2, kTitleLimitBytes, &title2); |
| - |
| - int result = title1.compare(title2); |
| - if (result != 0) |
| - return result < 0; |
| - |
| - return node1->url() < node2->url(); |
| - } |
| -}; |
| - |
| // Provides the following abstraction: given a parent bookmark node, find best |
| // matching child node for many sync nodes. |
| class BookmarkNodeFinder { |
| @@ -113,10 +81,14 @@ class BookmarkNodeFinder { |
| bool is_folder); |
| private: |
| - typedef std::multiset<const BookmarkNode*, BookmarkComparer> BookmarkNodesSet; |
| + // Maps bookmark node titles to instances, duplicates allowed |
|
Nicolas Zea
2014/09/29 18:33:56
nit: Comment that the title is stored in sync inte
stanisc
2014/09/29 22:34:22
Done.
|
| + typedef base::hash_multimap<std::string, |
| + const BookmarkNode*> BookmarkNodeMap; |
| + typedef std::pair<BookmarkNodeMap::iterator, |
| + BookmarkNodeMap::iterator> BookmarkNodeRange; |
| const BookmarkNode* parent_node_; |
| - BookmarkNodesSet child_nodes_; |
| + BookmarkNodeMap child_nodes_; |
| DISALLOW_COPY_AND_ASSIGN(BookmarkNodeFinder); |
| }; |
| @@ -141,29 +113,40 @@ class ScopedAssociationUpdater { |
| BookmarkNodeFinder::BookmarkNodeFinder(const BookmarkNode* parent_node) |
| : parent_node_(parent_node) { |
| for (int i = 0; i < parent_node_->child_count(); ++i) { |
| - child_nodes_.insert(parent_node_->GetChild(i)); |
| + const BookmarkNode* child_node = parent_node_->GetChild(i); |
| + // Convert and truncate bookmark titles in the form sync does internally |
| + // to avoid mismatches due to sync munging titles. |
| + std::string title = base::UTF16ToUTF8(child_node->GetTitle()); |
| + syncer::SyncAPINameToServerName(title, &title); |
|
Nicolas Zea
2014/09/29 18:33:56
nit: probably good to go ahead and pull this and t
stanisc
2014/09/29 22:34:22
Done.
|
| + base::TruncateUTF8ToByteSize(title, kTitleLimitBytes, &title); |
| + |
| + child_nodes_.insert(std::make_pair(title, child_node)); |
| } |
| } |
| const BookmarkNode* BookmarkNodeFinder::FindBookmarkNode( |
| const GURL& url, const std::string& title, bool is_folder) { |
| - // Create a bookmark node from the given bookmark attributes. |
| - BookmarkNode temp_node(url); |
| - temp_node.SetTitle(base::UTF8ToUTF16(title)); |
| - if (is_folder) |
| - temp_node.set_type(BookmarkNode::FOLDER); |
| - else |
| - temp_node.set_type(BookmarkNode::URL); |
| - |
| - const BookmarkNode* result = NULL; |
| - BookmarkNodesSet::iterator iter = child_nodes_.find(&temp_node); |
| - if (iter != child_nodes_.end()) { |
| - result = *iter; |
| - // Remove the matched node so we don't match with it again. |
| - child_nodes_.erase(iter); |
| + // First lookup a range of bookmarks with the same title. |
| + std::string adjusted_title; |
| + syncer::SyncAPINameToServerName(title, &adjusted_title); |
| + base::TruncateUTF8ToByteSize( |
| + adjusted_title, kTitleLimitBytes, &adjusted_title); |
| + BookmarkNodeRange range = child_nodes_.equal_range(adjusted_title); |
| + for (BookmarkNodeMap::iterator iter = range.first; |
| + iter != range.second; |
| + ++iter) { |
| + |
| + // Then within the range match the node by the folder bit |
| + // and the url. |
| + const BookmarkNode* node = iter->second; |
| + if (is_folder == node->is_folder() && url == node->url()) { |
| + // Remove the matched node so we don't match with it again. |
| + child_nodes_.erase(iter); |
| + return node; |
| + } |
| } |
| - return result; |
| + return NULL; |
| } |
| // Helper class to build an index of bookmark nodes by their IDs. |