1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/history/top_sites_cache.h"
6
7 #include "base/logging.h"
8 #include "base/memory/ref_counted_memory.h"
9
10 namespace history {
11
TopSitesCache()12 TopSitesCache::TopSitesCache() {
13 }
14
~TopSitesCache()15 TopSitesCache::~TopSitesCache() {
16 }
17
SetTopSites(const MostVisitedURLList & top_sites)18 void TopSitesCache::SetTopSites(const MostVisitedURLList& top_sites) {
19 top_sites_ = top_sites;
20 GenerateCanonicalURLs();
21 }
22
SetThumbnails(const URLToImagesMap & images)23 void TopSitesCache::SetThumbnails(const URLToImagesMap& images) {
24 images_ = images;
25 }
26
SetPageThumbnail(const GURL & url,RefCountedBytes * thumbnail,const ThumbnailScore & score)27 void TopSitesCache::SetPageThumbnail(const GURL& url,
28 RefCountedBytes* thumbnail,
29 const ThumbnailScore& score) {
30 Images& img = images_[GetCanonicalURL(url)];
31 img.thumbnail = thumbnail;
32 img.thumbnail_score = score;
33 }
34
GetImage(const GURL & url)35 Images* TopSitesCache::GetImage(const GURL& url) {
36 return &images_[GetCanonicalURL(url)];
37 }
38
GetPageThumbnail(const GURL & url,scoped_refptr<RefCountedBytes> * bytes)39 bool TopSitesCache::GetPageThumbnail(const GURL& url,
40 scoped_refptr<RefCountedBytes>* bytes) {
41 std::map<GURL, Images>::const_iterator found =
42 images_.find(GetCanonicalURL(url));
43 if (found != images_.end()) {
44 *bytes = found->second.thumbnail.get();
45 return true;
46 }
47 return false;
48 }
49
GetPageThumbnailScore(const GURL & url,ThumbnailScore * score)50 bool TopSitesCache::GetPageThumbnailScore(const GURL& url,
51 ThumbnailScore* score) {
52 std::map<GURL, Images>::const_iterator found =
53 images_.find(GetCanonicalURL(url));
54 if (found != images_.end()) {
55 *score = found->second.thumbnail_score;
56 return true;
57 }
58 return false;
59 }
60
GetCanonicalURL(const GURL & url)61 GURL TopSitesCache::GetCanonicalURL(const GURL& url) {
62 CanonicalURLs::iterator i = TopSitesCache::GetCanonicalURLsIterator(url);
63 return i == canonical_urls_.end() ? url : i->first.first->url;
64 }
65
IsKnownURL(const GURL & url)66 bool TopSitesCache::IsKnownURL(const GURL& url) {
67 return GetCanonicalURLsIterator(url) != canonical_urls_.end();
68 }
69
GetURLIndex(const GURL & url)70 size_t TopSitesCache::GetURLIndex(const GURL& url) {
71 DCHECK(IsKnownURL(url));
72 return GetCanonicalURLsIterator(url)->second;
73 }
74
RemoveUnreferencedThumbnails()75 void TopSitesCache::RemoveUnreferencedThumbnails() {
76 for (URLToImagesMap::iterator i = images_.begin(); i != images_.end(); ) {
77 if (IsKnownURL(i->first)) {
78 ++i;
79 } else {
80 URLToImagesMap::iterator next_i = i;
81 ++next_i;
82 images_.erase(i);
83 i = next_i;
84 }
85 }
86 }
87
GenerateCanonicalURLs()88 void TopSitesCache::GenerateCanonicalURLs() {
89 canonical_urls_.clear();
90 for (size_t i = 0; i < top_sites_.size(); i++)
91 StoreRedirectChain(top_sites_[i].redirects, i);
92 }
93
StoreRedirectChain(const RedirectList & redirects,size_t destination)94 void TopSitesCache::StoreRedirectChain(const RedirectList& redirects,
95 size_t destination) {
96 // redirects is empty if the user pinned a site and there are not enough top
97 // sites before the pinned site.
98
99 // Map all the redirected URLs to the destination.
100 for (size_t i = 0; i < redirects.size(); i++) {
101 // If this redirect is already known, don't replace it with a new one.
102 if (!IsKnownURL(redirects[i])) {
103 CanonicalURLEntry entry;
104 entry.first = &(top_sites_[destination]);
105 entry.second = i;
106 canonical_urls_[entry] = destination;
107 }
108 }
109 }
110
GetCanonicalURLsIterator(const GURL & url)111 TopSitesCache::CanonicalURLs::iterator TopSitesCache::GetCanonicalURLsIterator(
112 const GURL& url) {
113 MostVisitedURL most_visited_url;
114 most_visited_url.redirects.push_back(url);
115 CanonicalURLEntry entry;
116 entry.first = &most_visited_url;
117 entry.second = 0u;
118 return canonical_urls_.find(entry);
119 }
120
121 } // namespace history
122