15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#ifndef COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_INDEX_H_
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_INDEX_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <string>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/query_parser/query_parser.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkNode;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace bookmarks {
2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass BookmarkClient;
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)struct BookmarkMatch;
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// BookmarkIndex maintains an index of the titles and URLs of bookmarks for
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// quick look up. BookmarkIndex is owned and maintained by BookmarkModel, you
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shouldn't need to interact directly with BookmarkIndex.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BookmarkIndex maintains the index (index_) as a map of sets. The map (type
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Index) maps from a lower case string to the set (type NodeSet) of
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// BookmarkNodes that contain that string in their title or URL.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkIndex {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |languages| is used to help parse IDNs in URLs for the bookmark index.
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  BookmarkIndex(BookmarkClient* client,
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                const std::string& languages);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~BookmarkIndex();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked when a bookmark has been added to the model.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Add(const BookmarkNode* node);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invoked when a bookmark has been removed from the model.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Remove(const BookmarkNode* node);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Returns up to |max_count| of bookmarks containing each term from
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // the text |query| in either the title or the URL.
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void GetBookmarksMatching(
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& query,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t max_count,
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      std::vector<BookmarkMatch>* results);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  typedef std::vector<const BookmarkNode*> Nodes;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::set<const BookmarkNode*> NodeSet;
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef std::map<base::string16, NodeSet> Index;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct Match;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<Match> Matches;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Extracts |matches.nodes| into Nodes, sorts the pairs in decreasing order of
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // typed count (if supported by the client), and then de-dupes the matches.
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void SortMatches(const Matches& matches, Nodes* sorted_nodes) const;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add |node| to |results| if the node matches the query.
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void AddMatchToResults(
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      const BookmarkNode* node,
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      query_parser::QueryParser* parser,
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      const query_parser::QueryNodeStarVector& query_nodes,
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      std::vector<BookmarkMatch>* results);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Populates |matches| for the specified term. If |first_term| is true, this
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is the first term in the query. Returns true if there is at least one node
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // matching the term.
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool GetBookmarksMatchingTerm(const base::string16& term,
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                bool first_term,
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                Matches* matches);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Iterates over |matches| updating each Match's nodes to contain the
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // intersection of the Match's current nodes and the nodes at |index_i|.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the intersection is empty, the Match is removed.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // This is invoked from GetBookmarksMatchingTerm.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CombineMatchesInPlace(const Index::const_iterator& index_i,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Matches* matches);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Iterates over |current_matches| calculating the intersection between the
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Match's nodes and the nodes at |index_i|. If the intersection between the
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // two is non-empty, a new match is added to |result|.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This differs from CombineMatchesInPlace in that if the intersection is
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-empty the result is added to result, not combined in place. This
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // variant is used for prefix matching.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // This is invoked from GetBookmarksMatchingTerm.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CombineMatches(const Index::const_iterator& index_i,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const Matches& current_matches,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      Matches* result);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the set of query words from |query|.
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<base::string16> ExtractQueryWords(const base::string16& query);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds |node| to |index_|.
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void RegisterNode(const base::string16& term, const BookmarkNode* node);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Removes |node| from |index_|.
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void UnregisterNode(const base::string16& term, const BookmarkNode* node);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Index index_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  BookmarkClient* const client_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Languages used to help parse IDNs in URLs for the bookmark index.
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const std::string languages_;
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BookmarkIndex);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace bookmarks
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_INDEX_H_
120