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

Unified Diff: chrome/browser/history/top_sites_cache.cc

Issue 23477033: Implementing URL prefix match for history thumbnail cache. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/history/top_sites_cache.cc
diff --git a/chrome/browser/history/top_sites_cache.cc b/chrome/browser/history/top_sites_cache.cc
index f94013f0773be2ee3408d859a9fa827ff60cff89..bc31260a3ab4d4acf7a8620a224730fa1d7280d8 100644
--- a/chrome/browser/history/top_sites_cache.cc
+++ b/chrome/browser/history/top_sites_cache.cc
@@ -4,11 +4,43 @@
#include "chrome/browser/history/top_sites_cache.h"
+#include <algorithm>
+
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
namespace history {
+bool CanonicalURLComparator::operator()(const CanonicalURLEntry& e1,
+ const CanonicalURLEntry& e2) const {
+ return CanonicalURLComparator::CompareString(
+ e1.first->redirects[e1.second].spec(),
+ e2.first->redirects[e2.second].spec());
+}
+
+// static
+bool CanonicalURLComparator::CompareString(const std::string& s1,
+ const std::string& s2) {
+ const std::string::value_type* ch1 = s1.c_str();
+ const std::string::value_type* ch2 = s2.c_str();
+ // Find first difference.
+ while (*ch1 && *ch2 && *ch1 == *ch2) {
+ ++ch1;
+ ++ch2;
+ }
+ if (!*ch1 || !*ch2) // Identical strings, or one is strict prefix of other.
+ return *ch2 != '\0'; // true iff |e1| is strict prefix of |e2|.
+
+ // Now |*ch1| != |*ch2|. Compare using order '?' < '/' < other.
+ // Table : |*ch2| = '?' : |*ch2| = "/" : |*ch2| = other
+ // |*ch1| = '?' : (excluded) : true : true
+ // |*ch1| = '/' : false : (excluded) : true
+ // |*ch1| = 'other' : false : false : |*ch1| < |*ch2|
+ return (*ch1 == '?') || (*ch1 == '/' && *ch2 != '?') ||
+ (*ch2 != '?' && *ch2 != '/' && *ch1 < *ch2);
+}
+
+
TopSitesCache::TopSitesCache() {
}
@@ -43,6 +75,21 @@ bool TopSitesCache::GetPageThumbnail(
return false;
}
+bool TopSitesCache::GetPageThumbnailForPrefix(
+ const GURL& prefix_url,
+ scoped_refptr<base::RefCountedMemory>* bytes) {
+ std::map<GURL, Images>::const_iterator found =
+ images_.find(GetCanonicalURLForPrefix(prefix_url));
+ if (found != images_.end()) {
+ base::RefCountedMemory* data = found->second.thumbnail.get();
+ if (data) {
+ *bytes = data;
+ return true;
+ }
+ }
+ return false;
+}
+
bool TopSitesCache::GetPageThumbnailScore(const GURL& url,
ThumbnailScore* score) {
std::map<GURL, Images>::const_iterator found =
@@ -55,17 +102,51 @@ bool TopSitesCache::GetPageThumbnailScore(const GURL& url,
}
const GURL& TopSitesCache::GetCanonicalURL(const GURL& url) {
- CanonicalURLs::iterator i = TopSitesCache::GetCanonicalURLsIterator(url);
+ CanonicalURLs::iterator i = GetCanonicalURLsIterator(url, false);
+ return i == canonical_urls_.end() ? url : i->first.first->url;
+}
+
+const GURL& TopSitesCache::GetCanonicalURLForPrefix(const GURL& url) {
+ CanonicalURLs::iterator i = GetCanonicalURLsIterator(url, true);
return i == canonical_urls_.end() ? url : i->first.first->url;
}
bool TopSitesCache::IsKnownURL(const GURL& url) {
- return GetCanonicalURLsIterator(url) != canonical_urls_.end();
+ return GetCanonicalURLsIterator(url, false) != canonical_urls_.end();
}
size_t TopSitesCache::GetURLIndex(const GURL& url) {
DCHECK(IsKnownURL(url));
- return GetCanonicalURLsIterator(url)->second;
+ return GetCanonicalURLsIterator(url, false)->second;
+}
+
+// static
+bool TopSitesCache::UrlIsPrefix(const GURL& url1, const GURL& url2) {
+ if (url1.scheme() != url2.scheme() || url1.host() != url2.host() ||
+ url1.port() != url2.port()) {
+ return false;
+ }
+ // Only need to compare path now. Note that queries are ignored.
+ std::string p1(url1.path());
+ std::string p2(url2.path());
+ if (p1.length() > p2.length())
+ return false;
+ std::pair<std::string::iterator, std::string::iterator> first_diff =
+ std::mismatch(p1.begin(), p1.end(), p2.begin());
+ // Necessary condition: |p1| is a string prefix of |p2|.
+ if (first_diff.first != p1.end())
+ return false; // E.g.: (|p1| = "/test", |p2| = "/exam") => false.
+
+ // |p1| is string prefix.
+ if (first_diff.second == p2.end()) // Is exact match?
+ return true; // E.g.: ("/test", "/test") => true.
+ // |p1| is strict string prefix, check full match of last path component.
+ if (!p1.empty() && *p1.rbegin() == '/') // Ends in '/'?
+ return true; // E.g.: ("/test/", "/test/stuff") => true.
+
+ // Finally, |p1| does not end in "/": check first extra character in |p2|.
+ // E.g.: ("/test", "/test/stuff") => true; ("/test", "/testing") => false.
+ return *(first_diff.second) == '/';
}
void TopSitesCache::GenerateCanonicalURLs() {
@@ -76,7 +157,7 @@ void TopSitesCache::GenerateCanonicalURLs() {
void TopSitesCache::StoreRedirectChain(const RedirectList& redirects,
size_t destination) {
- // redirects is empty if the user pinned a site and there are not enough top
+ // |redirects| is empty if the user pinned a site and there are not enough top
// sites before the pinned site.
// Map all the redirected URLs to the destination.
@@ -92,13 +173,22 @@ void TopSitesCache::StoreRedirectChain(const RedirectList& redirects,
}
TopSitesCache::CanonicalURLs::iterator TopSitesCache::GetCanonicalURLsIterator(
- const GURL& url) {
+ const GURL& url, bool match_prefix) {
MostVisitedURL most_visited_url;
most_visited_url.redirects.push_back(url);
CanonicalURLEntry entry;
entry.first = &most_visited_url;
entry.second = 0u;
- return canonical_urls_.find(entry);
+ if (!match_prefix)
+ return canonical_urls_.find(entry);
+
+ TopSitesCache::CanonicalURLs::iterator best_it =
+ canonical_urls_.lower_bound(entry);
+ if (best_it == canonical_urls_.end())
+ return best_it;
+
+ const GURL& comp_url = best_it->first.first->redirects[best_it->first.second];
+ return UrlIsPrefix(url, comp_url) ? best_it : canonical_urls_.end();
}
} // namespace history

Powered by Google App Engine
This is Rietveld 408576698