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

Side by Side Diff: chrome/browser/thumbnail_store.cc

Issue 155186: Reverting 20097. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/thumbnail_store.h ('k') | chrome/browser/thumbnail_store_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/thumbnail_store.h" 5 #include "chrome/browser/thumbnail_store.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <algorithm> 8 #include <algorithm>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "base/pickle.h"
11 #include "base/file_util.h" 12 #include "base/file_util.h"
12 #include "base/gfx/jpeg_codec.h" 13 #include "base/gfx/jpeg_codec.h"
13 #include "base/md5.h" 14 #include "base/md5.h"
14 #include "base/string_util.h" 15 #include "base/string_util.h"
15 #include "base/thread.h" 16 #include "base/thread.h"
16 #include "base/values.h" 17 #include "base/values.h"
17 #include "chrome/browser/browser_process.h" 18 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/profile.h" 19 #include "chrome/browser/profile.h"
19 #include "chrome/common/pref_service.h" 20 #include "chrome/common/pref_service.h"
20 #include "chrome/common/sqlite_utils.h" 21 #include "chrome/common/thumbnail_score.h"
21 #include "googleurl/src/gurl.h" 22 #include "googleurl/src/gurl.h"
22 #include "third_party/skia/include/core/SkBitmap.h" 23 #include "third_party/skia/include/core/SkBitmap.h"
23 24
24 25
25 ThumbnailStore::ThumbnailStore() 26 ThumbnailStore::ThumbnailStore()
26 : cache_(NULL), 27 : cache_(NULL),
27 db_(NULL), 28 cache_initialized_(false),
28 hs_(NULL), 29 hs_(NULL),
29 url_blacklist_(NULL) { 30 url_blacklist_(NULL) {
30 } 31 }
31 32
32 ThumbnailStore::~ThumbnailStore() { 33 ThumbnailStore::~ThumbnailStore() {
33 CommitCacheToDB(NULL);
34 } 34 }
35 35
36 void ThumbnailStore::Init(const FilePath& db_name, 36 void ThumbnailStore::Init(const FilePath& file_path, Profile* profile) {
37 Profile* profile) { 37 file_path_ = file_path;
38 // Load thumbnails already in the database.
39 g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
40 NewRunnableMethod(this, &ThumbnailStore::InitializeFromDB,
41 db_name, MessageLoop::current()));
42
43 // Take ownership of a reference to the HistoryService.
44 hs_ = profile->GetHistoryService(Profile::EXPLICIT_ACCESS); 38 hs_ = profile->GetHistoryService(Profile::EXPLICIT_ACCESS);
45
46 // Store a pointer to a persistent table of blacklisted URLs.
47 url_blacklist_ = profile->GetPrefs()-> 39 url_blacklist_ = profile->GetPrefs()->
48 GetMutableDictionary(prefs::kNTPMostVisitedURLsBlacklist); 40 GetMutableDictionary(prefs::kNTPMostVisitedURLsBlacklist);
49 41
50 // Get the list of most visited URLs and redirect information from the 42 g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
51 // HistoryService. 43 NewRunnableMethod(this, &ThumbnailStore::GetAllThumbnailsFromDisk,
44 file_path_, MessageLoop::current()));
45
52 timer_.Start(base::TimeDelta::FromMinutes(30), this, 46 timer_.Start(base::TimeDelta::FromMinutes(30), this,
53 &ThumbnailStore::UpdateURLData); 47 &ThumbnailStore::UpdateURLData);
54 UpdateURLData(); 48 UpdateURLData();
55 } 49 }
56 50
57 bool ThumbnailStore::SetPageThumbnail(const GURL& url, 51 bool ThumbnailStore::SetPageThumbnail(const GURL& url,
58 const SkBitmap& thumbnail, 52 const SkBitmap& thumbnail,
59 const ThumbnailScore& score) { 53 const ThumbnailScore& score,
60 if (!cache_.get()) 54 bool write_to_disk) {
55 if (!cache_initialized_)
61 return false; 56 return false;
62 57
63 if (!ShouldStoreThumbnailForURL(url) || 58 if (!ShouldStoreThumbnailForURL(url) ||
64 (cache_->find(url) != cache_->end() && 59 (cache_->find(url) != cache_->end() &&
65 !ShouldReplaceThumbnailWith((*cache_)[url].score_, score))) 60 !ShouldReplaceThumbnailWith((*cache_)[url].second, score)))
66 return true; 61 return true;
67 62
68 base::TimeTicks encode_start = base::TimeTicks::Now(); 63 base::TimeTicks encode_start = base::TimeTicks::Now();
69 64
70 // Encode the SkBitmap to jpeg. 65 // Encode the SkBitmap to jpeg and add to cache.
71 scoped_refptr<RefCountedBytes> jpeg_data = new RefCountedBytes; 66 scoped_refptr<RefCountedBytes> jpeg_data = new RefCountedBytes;
72 SkAutoLockPixels thumbnail_lock(thumbnail); 67 SkAutoLockPixels thumbnail_lock(thumbnail);
73 bool encoded = JPEGCodec::Encode( 68 bool encoded = JPEGCodec::Encode(
74 reinterpret_cast<unsigned char*>(thumbnail.getAddr32(0, 0)), 69 reinterpret_cast<unsigned char*>(thumbnail.getAddr32(0, 0)),
75 JPEGCodec::FORMAT_BGRA, thumbnail.width(), 70 JPEGCodec::FORMAT_BGRA, thumbnail.width(),
76 thumbnail.height(), 71 thumbnail.height(),
77 static_cast<int>(thumbnail.rowBytes()), 90, 72 static_cast<int>(thumbnail.rowBytes()), 90,
78 &jpeg_data->data); 73 &jpeg_data->data);
79 74
80 base::TimeDelta delta = base::TimeTicks::Now() - encode_start; 75 base::TimeDelta delta = base::TimeTicks::Now() - encode_start;
81 HISTOGRAM_TIMES("Thumbnail.Encode", delta); 76 HISTOGRAM_TIMES("Thumbnail.Encode", delta);
82 77
83 if (!encoded) 78 if (!encoded)
84 return false; 79 return false;
85 80
86 // Update the cache_ with the new thumbnail. 81 // Update the cache_ with the new thumbnail.
87 (*cache_)[url] = CacheEntry(jpeg_data, score, true); 82 (*cache_)[url] = std::make_pair(jpeg_data, score);
88 83
84 // Write the new thumbnail data to disk in the background on file_thread.
85 if (write_to_disk) {
86 g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
87 NewRunnableMethod(this, &ThumbnailStore::WriteThumbnailToDisk, url,
88 jpeg_data, score));
89 }
89 return true; 90 return true;
90 } 91 }
91 92
92 bool ThumbnailStore::GetPageThumbnail( 93 bool ThumbnailStore::GetPageThumbnail(
93 const GURL& url, 94 const GURL& url,
94 RefCountedBytes** data) { 95 RefCountedBytes** data) {
95 if (!cache_.get() || IsURLBlacklisted(url)) 96 if (!cache_initialized_ || IsURLBlacklisted(url))
96 return false; 97 return false;
97 98
98 // Look up the |url| in the redirect list to find the final destination 99 // Look up the |url| in the redirect list to find the final destination
99 // which is the key into the |cache_|. 100 // which is the key into the |cache_|.
100 history::RedirectMap::iterator it = redirect_urls_->find(url); 101 history::RedirectMap::iterator it = redirect_urls_->find(url);
101 if (it != redirect_urls_->end()) { 102 if (it == redirect_urls_->end())
102 // Return the first available thumbnail starting at the end of the 103 return false;
103 // redirect list. 104
104 history::RedirectList::reverse_iterator rit; 105 // Return the first available thumbnail starting at the end of the
105 for (rit = it->second->data.rbegin(); 106 // redirect list.
106 rit != it->second->data.rend(); ++rit) { 107 history::RedirectList::reverse_iterator rit;
107 if (cache_->find(*rit) != cache_->end()) { 108 for (rit = it->second->data.rbegin();
108 *data = (*cache_)[*rit].data_.get(); 109 rit != it->second->data.rend(); ++rit) {
109 (*data)->AddRef(); 110 if (cache_->find(*rit) != cache_->end()) {
110 return true; 111 *data = (*cache_)[*rit].first;
111 } 112 (*data)->AddRef();
113 return true;
112 } 114 }
113 } 115 }
114 116
115 // TODO(meelapshah) bug 14643: check past redirect lists 117 // TODO(meelapshah) bug 14643: check past redirect lists
116 118
117 if (cache_->find(url) == cache_->end()) 119 if (cache_->find(url) == cache_->end())
118 return false; 120 return false;
119 121
120 *data = (*cache_)[url].data_.get(); 122 *data = (*cache_)[url].first;
121 (*data)->AddRef(); 123 (*data)->AddRef();
122 return true; 124 return true;
123 } 125 }
124 126
125 void ThumbnailStore::UpdateURLData() { 127 void ThumbnailStore::UpdateURLData() {
126 int result_count = ThumbnailStore::kMaxCacheSize + url_blacklist_->GetSize(); 128 int result_count = ThumbnailStore::kMaxCacheSize + url_blacklist_->GetSize();
127 hs_->QueryTopURLsAndRedirects(result_count, &consumer_, 129 hs_->QueryTopURLsAndRedirects(result_count, &consumer_,
128 NewCallback(this, &ThumbnailStore::OnURLDataAvailable)); 130 NewCallback(this, &ThumbnailStore::OnURLDataAvailable));
129 } 131 }
130 132
131 void ThumbnailStore::OnURLDataAvailable(std::vector<GURL>* urls, 133 void ThumbnailStore::OnURLDataAvailable(std::vector<GURL>* urls,
132 history::RedirectMap* redirects) { 134 history::RedirectMap* redirects) {
133 DCHECK(urls); 135 DCHECK(urls);
134 DCHECK(redirects); 136 DCHECK(redirects);
135 137
136 most_visited_urls_.reset(new std::vector<GURL>(*urls)); 138 most_visited_urls_.reset(new std::vector<GURL>(*urls));
137 redirect_urls_.reset(new history::RedirectMap(*redirects)); 139 redirect_urls_.reset(new history::RedirectMap(*redirects));
138 CleanCacheData(); 140 CleanCacheData();
139 } 141 }
140 142
141 void ThumbnailStore::CleanCacheData() { 143 void ThumbnailStore::CleanCacheData() {
142 if (!cache_.get()) 144 if (!cache_initialized_)
143 return; 145 return;
144 146
145 // For each URL in the cache, search the RedirectMap for the originating URL. 147 // For each URL in the cache, search the RedirectMap for the originating URL.
146 // If this URL is blacklisted or not in the most visited list, delete the 148 // If this URL is blacklisted or not in the most visited list, delete the
147 // thumbnail data for it from the cache and from disk in the background. 149 // thumbnail data for it from the cache and from disk in the background.
148 scoped_refptr<RefCountedVector<GURL> > old_urls = new RefCountedVector<GURL>; 150 scoped_refptr<RefCountedVector<GURL> > old_urls = new RefCountedVector<GURL>;
149 for (Cache::iterator cache_it = cache_->begin(); 151 for (ThumbnailStore::Cache::iterator cache_it = cache_->begin();
150 cache_it != cache_->end();) { 152 cache_it != cache_->end();) {
151 const GURL* url = NULL; 153 const GURL* url = NULL;
152 for (history::RedirectMap::iterator it = redirect_urls_->begin(); 154 for (history::RedirectMap::iterator it = redirect_urls_->begin();
153 it != redirect_urls_->end(); ++it) { 155 it != redirect_urls_->end(); ++it) {
154 if (cache_it->first == it->first || 156 if (cache_it->first == it->first ||
155 (it->second->data.size() && 157 (it->second->data.size() &&
156 cache_it->first == it->second->data.back())) { 158 cache_it->first == it->second->data.back())) {
157 url = &it->first; 159 url = &it->first;
158 break; 160 break;
159 } 161 }
160 } 162 }
161 163
162 if (url == NULL || IsURLBlacklisted(*url) || !IsPopular(*url)) { 164 if (url == NULL || IsURLBlacklisted(*url) || !IsPopular(*url)) {
163 old_urls->data.push_back(cache_it->first); 165 old_urls->data.push_back(cache_it->first);
164 cache_->erase(cache_it++); 166 cache_->erase(cache_it++);
165 } else { 167 } else {
166 cache_it++; 168 cache_it++;
167 } 169 }
168 } 170 }
169 171
170 if (old_urls->data.size()) { 172 if (old_urls->data.size()) {
171 g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE, 173 g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
172 NewRunnableMethod(this, &ThumbnailStore::CommitCacheToDB, old_urls)); 174 NewRunnableMethod(this, &ThumbnailStore::DeleteThumbnails, old_urls));
173 } 175 }
174 } 176 }
175 177
176 void ThumbnailStore::CommitCacheToDB( 178 void ThumbnailStore::DeleteThumbnails(
177 scoped_refptr<RefCountedVector<GURL> > stale_urls) const { 179 scoped_refptr<RefCountedVector<GURL> > thumbnail_urls) const {
178 if (!db_) 180 for (std::vector<GURL>::iterator it = thumbnail_urls->data.begin();
179 return; 181 it != thumbnail_urls->data.end(); ++it)
182 file_util::Delete(file_path_.AppendASCII(MD5String(it->spec())), false);
183 }
180 184
181 // Delete old thumbnails. 185 void ThumbnailStore::GetAllThumbnailsFromDisk(FilePath filepath,
182 if (stale_urls.get()) { 186 MessageLoop* cb_loop) {
183 for (std::vector<GURL>::iterator it = stale_urls->data.begin(); 187 ThumbnailStore::Cache* cache = new ThumbnailStore::Cache;
184 it != stale_urls->data.end(); ++it) { 188
185 SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_, 189 // Create the specified directory if it does not exist.
186 "DELETE FROM thumbnails WHERE url=?"); 190 if (!file_util::DirectoryExists(filepath)) {
187 statement->bind_string(0, it->spec()); 191 file_util::CreateDirectory(filepath);
188 if (statement->step() != SQLITE_DONE) 192 } else {
189 NOTREACHED(); 193 // Walk the directory and read the thumbnail data from disk.
194 FilePath path;
195 GURL url;
196 RefCountedBytes* data;
197 ThumbnailScore score;
198 file_util::FileEnumerator fenum(filepath, false,
199 file_util::FileEnumerator::FILES);
200
201 while (!(path = fenum.Next()).empty()) {
202 data = new RefCountedBytes;
203 if (GetPageThumbnailFromDisk(path, &url, data, &score))
204 (*cache)[url] = std::make_pair(data, score);
205 else
206 delete data;
190 } 207 }
191 } 208 }
192
193 // Update cached thumbnails.
194 for (Cache::iterator it = cache_->begin(); it != cache_->end(); ++it) {
195 if (!it->second.dirty_)
196 continue;
197
198 SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
199 "INSERT OR REPLACE INTO thumbnails "
200 "(url, boring_score, good_clipping, at_top, time_taken, data) "
201 "VALUES (?,?,?,?,?,?)");
202 statement->bind_string(0, it->first.spec());
203 statement->bind_double(1, it->second.score_.boring_score);
204 statement->bind_bool(2, it->second.score_.good_clipping);
205 statement->bind_bool(3, it->second.score_.at_top);
206 statement->bind_int64(4, it->second.score_.time_at_snapshot.
207 ToInternalValue());
208 statement->bind_blob(5, &it->second.data_->data[0],
209 static_cast<int>(it->second.data_->data.size()));
210 if (statement->step() != SQLITE_DONE)
211 DLOG(WARNING) << "Unable to insert thumbnail for URL";
212 else
213 it->second.dirty_ = false;
214 }
215 }
216
217 void ThumbnailStore::InitializeFromDB(const FilePath& db_name,
218 MessageLoop* cb_loop) {
219 if (OpenSqliteDb(db_name, &db_) != SQLITE_OK)
220 return;
221
222 // Use a large page size since the thumbnails we are storing are typically
223 // large, a small cache size since we cache in memory and don't go to disk
224 // often, and take exclusive access since nobody else uses this db.
225 sqlite3_exec(db_, "PRAGMA page_size=4096 "
226 "PRAGMA cache_size=64 "
227 "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL, NULL);
228
229 statement_cache_ = new SqliteStatementCache;
230
231 // Use local DBCloseScoper so that if we cannot create the table and
232 // need to return, the |db_| and |statement_cache_| are closed properly.
233 history::DBCloseScoper scoper(&db_, &statement_cache_);
234
235 if (!DoesSqliteTableExist(db_, "thumbnails")) {
236 if (sqlite3_exec(db_, "CREATE TABLE thumbnails ("
237 "url LONGVARCHAR PRIMARY KEY,"
238 "boring_score DOUBLE DEFAULT 1.0,"
239 "good_clipping INTEGER DEFAULT 0,"
240 "at_top INTEGER DEFAULT 0,"
241 "time_taken INTEGER DEFAULT 0,"
242 "data BLOB)", NULL, NULL, NULL) != SQLITE_OK)
243 return;
244 }
245
246 statement_cache_->set_db(db_);
247
248 // Now we can use a DBCloseScoper at the object scope.
249 scoper.Detach();
250 close_scoper_.Attach(&db_, &statement_cache_);
251
252 if (cb_loop)
253 GetAllThumbnailsFromDisk(cb_loop);
254 }
255
256 void ThumbnailStore::GetAllThumbnailsFromDisk(MessageLoop* cb_loop) {
257 ThumbnailStore::Cache* cache = new ThumbnailStore::Cache;
258
259 SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
260 "SELECT * FROM thumbnails");
261
262 while (statement->step() == SQLITE_ROW) {
263 GURL url(statement->column_string(0));
264 ThumbnailScore score(statement->column_double(1), // Boring score
265 statement->column_bool(2), // Good clipping
266 statement->column_bool(3), // At top
267 base::Time::FromInternalValue(
268 statement->column_int64(4))); // Time taken
269 scoped_refptr<RefCountedBytes> data = new RefCountedBytes;
270 if (statement->column_blob_as_vector(5, &data->data))
271 (*cache)[url] = CacheEntry(data, score, false);
272 }
273
274 cb_loop->PostTask(FROM_HERE, 209 cb_loop->PostTask(FROM_HERE,
275 NewRunnableMethod(this, &ThumbnailStore::OnDiskDataAvailable, cache)); 210 NewRunnableMethod(this, &ThumbnailStore::OnDiskDataAvailable, cache));
276 } 211 }
277 212
213 bool ThumbnailStore::GetPageThumbnailFromDisk(const FilePath& file,
214 GURL* url,
215 RefCountedBytes* data,
216 ThumbnailScore* score) const {
217 int64 file_size;
218 if (!file_util::GetFileSize(file, &file_size))
219 return false;
220
221 // Read the file into a buffer.
222 std::vector<char> file_data;
223 file_data.resize(static_cast<unsigned int>(file_size));
224 if (file_util::ReadFile(file, &file_data[0],
225 static_cast<int>(file_size)) == -1)
226 return false;
227
228 // Unpack the url, ThumbnailScore and JPEG size from the buffer.
229 std::string url_string;
230 unsigned int jpeg_len;
231 void* iter = NULL;
232 Pickle packed(&file_data[0], static_cast<int>(file_size));
233
234 if (!packed.ReadString(&iter, &url_string) ||
235 !UnpackScore(score, packed, iter) ||
236 !packed.ReadUInt32(&iter, &jpeg_len))
237 return false;
238
239 // Store the url to the out parameter.
240 GURL temp_url(url_string);
241 url->Swap(&temp_url);
242
243 // Unpack the JPEG data from the buffer.
244 const char* jpeg_data = NULL;
245 int out_len;
246
247 if (!packed.ReadData(&iter, &jpeg_data, &out_len) ||
248 out_len != static_cast<int>(jpeg_len))
249 return false;
250
251 // Copy jpeg data to the out parameter.
252 data->data.resize(jpeg_len);
253 memcpy(&data->data[0], jpeg_data, jpeg_len);
254
255 return true;
256 }
257
278 void ThumbnailStore::OnDiskDataAvailable(ThumbnailStore::Cache* cache) { 258 void ThumbnailStore::OnDiskDataAvailable(ThumbnailStore::Cache* cache) {
279 if (cache) 259 if (cache) {
280 cache_.reset(cache); 260 cache_.reset(cache);
261 cache_initialized_ = true;
262 }
263 }
264
265 bool ThumbnailStore::WriteThumbnailToDisk(const GURL& url,
266 scoped_refptr<RefCountedBytes> data,
267 const ThumbnailScore& score) const {
268 Pickle packed;
269 FilePath file = file_path_.AppendASCII(MD5String(url.spec()));
270
271 // Pack the url, ThumbnailScore, and the JPEG data.
272 packed.WriteString(url.spec());
273 PackScore(score, &packed);
274 packed.WriteUInt32(data->data.size());
275 packed.WriteData(reinterpret_cast<char*>(&data->data[0]), data->data.size());
276
277 // Write the packed data to a file.
278 file_util::Delete(file, false);
279 return file_util::WriteFile(file,
280 reinterpret_cast<const char*>(packed.data()),
281 packed.size()) != -1;
282 }
283
284 void ThumbnailStore::PackScore(const ThumbnailScore& score,
285 Pickle* packed) const {
286 // Pack the contents of the given ThumbnailScore into the given Pickle.
287 packed->WriteData(reinterpret_cast<const char*>(&score.boring_score),
288 sizeof(score.boring_score));
289 packed->WriteBool(score.at_top);
290 packed->WriteBool(score.good_clipping);
291 packed->WriteInt64(score.time_at_snapshot.ToInternalValue());
292 }
293
294 bool ThumbnailStore::UnpackScore(ThumbnailScore* score, const Pickle& packed,
295 void*& iter) const {
296 // Unpack a ThumbnailScore from the given Pickle and iterator.
297 const char* boring = NULL;
298 int out_len;
299 int64 us;
300
301 if (!packed.ReadData(&iter, &boring, &out_len) ||
302 !packed.ReadBool(&iter, &score->at_top) ||
303 !packed.ReadBool(&iter, &score->good_clipping) ||
304 !packed.ReadInt64(&iter, &us))
305 return false;
306
307 if (out_len != sizeof(score->boring_score))
308 return false;
309
310 memcpy(&score->boring_score, boring, sizeof(score->boring_score));
311 score->time_at_snapshot = base::Time::FromInternalValue(us);
312 return true;
281 } 313 }
282 314
283 bool ThumbnailStore::ShouldStoreThumbnailForURL(const GURL& url) const { 315 bool ThumbnailStore::ShouldStoreThumbnailForURL(const GURL& url) const {
284 if (IsURLBlacklisted(url) || cache_->size() >= ThumbnailStore::kMaxCacheSize) 316 if (IsURLBlacklisted(url) || cache_->size() >= ThumbnailStore::kMaxCacheSize)
285 return false; 317 return false;
286 318
287 return most_visited_urls_->size() < ThumbnailStore::kMaxCacheSize || 319 return most_visited_urls_->size() < ThumbnailStore::kMaxCacheSize ||
288 IsPopular(url); 320 IsPopular(url);
289 } 321 }
290 322
291 bool ThumbnailStore::IsURLBlacklisted(const GURL& url) const { 323 bool ThumbnailStore::IsURLBlacklisted(const GURL& url) const {
292 if (url_blacklist_) 324 if (url_blacklist_)
293 return url_blacklist_->HasKey(GetDictionaryKeyForURL(url.spec())); 325 return url_blacklist_->HasKey(GetDictionaryKeyForURL(url.spec()));
294 return false; 326 return false;
295 } 327 }
296 328
297 std::wstring ThumbnailStore::GetDictionaryKeyForURL( 329 std::wstring ThumbnailStore::GetDictionaryKeyForURL(
298 const std::string& url) const { 330 const std::string& url) const {
299 return ASCIIToWide(MD5String(url)); 331 return ASCIIToWide(MD5String(url));
300 } 332 }
301 333
302 bool ThumbnailStore::IsPopular(const GURL& url) const { 334 bool ThumbnailStore::IsPopular(const GURL& url) const {
303 return most_visited_urls_->end() != find(most_visited_urls_->begin(), 335 return most_visited_urls_->end() != find(most_visited_urls_->begin(),
304 most_visited_urls_->end(), 336 most_visited_urls_->end(),
305 url); 337 url);
306 } 338 }
OLDNEW
« no previous file with comments | « chrome/browser/thumbnail_store.h ('k') | chrome/browser/thumbnail_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698