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

Side by Side Diff: components/history/core/browser/thumbnail_database.cc

Issue 2856873002: [Thumbnails DB] Allow setting last_requested time when accessing favicons. (Closed)
Patch Set: Splitting off clearing Created 3 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "components/history/core/browser/thumbnail_database.h" 5 #include "components/history/core/browser/thumbnail_database.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // favicons. There is a separate row for every size in a 57 // favicons. There is a separate row for every size in a
58 // multi resolution bitmap. The bitmap data is associated 58 // multi resolution bitmap. The bitmap data is associated
59 // to the favicon via the |icon_id| field which matches 59 // to the favicon via the |icon_id| field which matches
60 // the |id| field in the appropriate row in the |favicons| 60 // the |id| field in the appropriate row in the |favicons|
61 // table. 61 // table.
62 // 62 //
63 // id Unique ID. 63 // id Unique ID.
64 // icon_id The ID of the favicon that the bitmap is associated to. 64 // icon_id The ID of the favicon that the bitmap is associated to.
65 // last_updated The time at which this favicon was inserted into the 65 // last_updated The time at which this favicon was inserted into the
66 // table. This is used to determine if it needs to be 66 // table. This is used to determine if it needs to be
67 // redownloaded from the web. 67 // redownloaded from the web. Value 0 denotes that the bitmap
68 // has been explicitly expired.
68 // image_data PNG encoded data of the favicon. 69 // image_data PNG encoded data of the favicon.
69 // width Pixel width of |image_data|. 70 // width Pixel width of |image_data|.
70 // height Pixel height of |image_data|. 71 // height Pixel height of |image_data|.
71 // last_requested The time at which this bitmap was last requested. This is 72 // last_requested The time at which this bitmap was last requested. This is
72 // used to determine the priority with which the bitmap 73 // only used for on-demand bitmaps, for clearing old entries.
73 // should be retained on cleanup. 74 // (On-demand bitmaps cannot get cleared along with expired
75 // visits in history DB.) On-demand bitmaps are defined by
76 // last_requested>0 and thus this field should never get
77 // updated for standard (not on-demand) bitmaps.
74 78
75 namespace { 79 namespace {
76 80
81 const int kFaviconUpdateLastRequestedAfterDays = 14;
82
77 // For this database, schema migrations are deprecated after two 83 // For this database, schema migrations are deprecated after two
78 // years. This means that the oldest non-deprecated version should be 84 // years. This means that the oldest non-deprecated version should be
79 // two years old or greater (thus the migrations to get there are 85 // two years old or greater (thus the migrations to get there are
80 // older). Databases containing deprecated versions will be cleared 86 // older). Databases containing deprecated versions will be cleared
81 // at startup. Since this database is a cache, losing old data is not 87 // at startup. Since this database is a cache, losing old data is not
82 // fatal (in fact, very old data may be expired immediately at startup 88 // fatal (in fact, very old data may be expired immediately at startup
83 // anyhow). 89 // anyhow).
84 90
85 // Version 8: 982ef2c1/r323176 by rogerm@chromium.org on 2015-03-31 91 // Version 8: 982ef2c1/r323176 by rogerm@chromium.org on 2015-03-31
86 // Version 7: 911a634d/r209424 by qsr@chromium.org on 2013-07-01 92 // Version 7: 911a634d/r209424 by qsr@chromium.org on 2013-07-01
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 // test-expectation framework that the error was handled. 266 // test-expectation framework that the error was handled.
261 ignore_result(sql::Connection::IsExpectedSqliteError(extended_error)); 267 ignore_result(sql::Connection::IsExpectedSqliteError(extended_error));
262 return; 268 return;
263 } 269 }
264 270
265 // The default handling is to assert on debug and to ignore on release. 271 // The default handling is to assert on debug and to ignore on release.
266 if (!sql::Connection::IsExpectedSqliteError(extended_error)) 272 if (!sql::Connection::IsExpectedSqliteError(extended_error))
267 DLOG(FATAL) << db->GetErrorMessage(); 273 DLOG(FATAL) << db->GetErrorMessage();
268 } 274 }
269 275
276 void FillStatementForAddFaviconBitmap(
277 favicon_base::FaviconID icon_id,
278 const scoped_refptr<base::RefCountedMemory>& icon_data,
279 base::Time time,
280 const gfx::Size& pixel_size,
281 sql::Statement* statement) {
282 DCHECK(statement);
283 DCHECK(icon_id);
284 statement->BindInt64(0, icon_id);
285 if (icon_data.get() && icon_data->size()) {
286 statement->BindBlob(1, icon_data->front(),
287 static_cast<int>(icon_data->size()));
288 } else {
289 statement->BindNull(1);
290 }
291 statement->BindInt64(2, time.ToInternalValue());
292 statement->BindInt(3, pixel_size.width());
293 statement->BindInt(4, pixel_size.height());
294 }
295
270 } // namespace 296 } // namespace
271 297
272 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() { 298 ThumbnailDatabase::IconMappingEnumerator::IconMappingEnumerator() {
273 } 299 }
274 300
275 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() { 301 ThumbnailDatabase::IconMappingEnumerator::~IconMappingEnumerator() {
276 } 302 }
277 303
278 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping( 304 bool ThumbnailDatabase::IconMappingEnumerator::GetNextIconMapping(
279 IconMapping* icon_mapping) { 305 IconMapping* icon_mapping) {
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 if (last_requested) 523 if (last_requested)
498 *last_requested = base::Time::FromInternalValue(statement.ColumnInt64(4)); 524 *last_requested = base::Time::FromInternalValue(statement.ColumnInt64(4));
499 525
500 return true; 526 return true;
501 } 527 }
502 528
503 FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap( 529 FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap(
504 favicon_base::FaviconID icon_id, 530 favicon_base::FaviconID icon_id,
505 const scoped_refptr<base::RefCountedMemory>& icon_data, 531 const scoped_refptr<base::RefCountedMemory>& icon_data,
506 base::Time time, 532 base::Time time,
507 const gfx::Size& pixel_size) { 533 const gfx::Size& pixel_size) {
pkotwicz 2017/05/24 15:43:31 Can you either: - add an enum parameter with wheth
sky 2017/05/24 18:20:15 +1 to what Peter says.
jkrcal 2017/06/06 15:41:55 Done.
508 DCHECK(icon_id); 534 DCHECK(icon_id);
509 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 535 // Standard bitmaps (in contrast to on-demand bitmaps below):
510 "INSERT INTO favicon_bitmaps (icon_id, image_data, last_updated, width, " 536 // - keep track of last_updated: last write time is used for expiration;
511 "height) VALUES (?, ?, ?, ?, ?)")); 537 // - always have last_requested==0: no need to keep track of last read time.
512 statement.BindInt64(0, icon_id); 538 sql::Statement statement(db_.GetCachedStatement(
513 if (icon_data.get() && icon_data->size()) { 539 SQL_FROM_HERE,
514 statement.BindBlob(1, icon_data->front(), 540 "INSERT INTO favicon_bitmaps (icon_id, image_data, last_updated, "
515 static_cast<int>(icon_data->size())); 541 "width, height) VALUES (?, ?, ?, ?, ?)"));
516 } else { 542 FillStatementForAddFaviconBitmap(icon_id, icon_data, time, pixel_size,
517 statement.BindNull(1); 543 &statement);
518 }
519 statement.BindInt64(2, time.ToInternalValue());
520 statement.BindInt(3, pixel_size.width());
521 statement.BindInt(4, pixel_size.height());
522 544
523 if (!statement.Run()) 545 if (!statement.Run())
524 return 0; 546 return 0;
547 return db_.GetLastInsertRowId();
548 }
549
550 FaviconBitmapID ThumbnailDatabase::AddOnDemandFaviconBitmap(
551 favicon_base::FaviconID icon_id,
552 const scoped_refptr<base::RefCountedMemory>& icon_data,
553 base::Time time,
554 const gfx::Size& pixel_size) {
555 // On-demand bitmaps (in contrast to standard bitmaps above):
556 // - always have last_updated==0: last write time is not stored as they are
557 // always expired and thus ready to be replaced by standard icons;
558 // - keep track of last_requested: last read time is used for cache eviction.
pkotwicz 2017/05/24 15:43:31 If a row has both non-zero |last_updated| and non-
jkrcal 2017/06/06 15:41:55 Oh, very good point. I changed other functions tha
559 sql::Statement statement(db_.GetCachedStatement(
560 SQL_FROM_HERE,
561 "INSERT INTO favicon_bitmaps (icon_id, image_data, last_requested, "
562 "width, height) VALUES (?, ?, ?, ?, ?)"));
563 FillStatementForAddFaviconBitmap(icon_id, icon_data, time, pixel_size,
564 &statement);
565
566 if (!statement.Run())
567 return 0;
525 return db_.GetLastInsertRowId(); 568 return db_.GetLastInsertRowId();
526 } 569 }
527 570
528 bool ThumbnailDatabase::SetFaviconBitmap( 571 bool ThumbnailDatabase::SetFaviconBitmap(
529 FaviconBitmapID bitmap_id, 572 FaviconBitmapID bitmap_id,
530 scoped_refptr<base::RefCountedMemory> bitmap_data, 573 scoped_refptr<base::RefCountedMemory> bitmap_data,
531 base::Time time) { 574 base::Time time) {
532 DCHECK(bitmap_id); 575 DCHECK(bitmap_id);
533 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 576 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
534 "UPDATE favicon_bitmaps SET image_data=?, last_updated=? WHERE id=?")); 577 "UPDATE favicon_bitmaps SET image_data=?, last_updated=? WHERE id=?"));
(...skipping 13 matching lines...) Expand all
548 FaviconBitmapID bitmap_id, 591 FaviconBitmapID bitmap_id,
549 base::Time time) { 592 base::Time time) {
550 DCHECK(bitmap_id); 593 DCHECK(bitmap_id);
551 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 594 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
552 "UPDATE favicon_bitmaps SET last_updated=? WHERE id=?")); 595 "UPDATE favicon_bitmaps SET last_updated=? WHERE id=?"));
553 statement.BindInt64(0, time.ToInternalValue()); 596 statement.BindInt64(0, time.ToInternalValue());
554 statement.BindInt64(1, bitmap_id); 597 statement.BindInt64(1, bitmap_id);
555 return statement.Run(); 598 return statement.Run();
556 } 599 }
557 600
558 bool ThumbnailDatabase::SetFaviconBitmapLastRequestedTime( 601 bool ThumbnailDatabase::TouchOnDemandFavicon(const GURL& icon_url,
559 FaviconBitmapID bitmap_id, 602 base::Time time) {
560 base::Time time) { 603 // Look up the id of the icon.
561 DCHECK(bitmap_id); 604 sql::Statement id_statement(db_.GetCachedStatement(
562 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 605 SQL_FROM_HERE, "SELECT id FROM favicons WHERE url=?"));
563 "UPDATE favicon_bitmaps SET last_requested=? WHERE id=?")); 606 id_statement.BindString(0, URLDatabase::GURLToDatabaseURL(icon_url));
607 if (!id_statement.Step())
608 return false; // not cached
609 favicon_base::FaviconID icon_id = id_statement.ColumnInt64(0);
610
pkotwicz 2017/05/24 15:43:31 Can you skip the SELECT and go straight to the UPD
jkrcal 2017/06/06 15:41:55 Not really because "url" is in the favicons table
pkotwicz 2017/06/07 17:40:52 I see now.
611 sql::Statement statement(db_.GetCachedStatement(
612 SQL_FROM_HERE,
613 "UPDATE favicon_bitmaps SET last_requested=? WHERE icon_id=? AND "
614 "last_requested>0 AND last_requested<=?"));
564 statement.BindInt64(0, time.ToInternalValue()); 615 statement.BindInt64(0, time.ToInternalValue());
565 statement.BindInt64(1, bitmap_id); 616 statement.BindInt64(1, icon_id);
617 base::Time max_time =
618 time - base::TimeDelta::FromDays(kFaviconUpdateLastRequestedAfterDays);
pkotwicz 2017/05/24 15:43:31 Why the upper bound on |last_requested|? Is this t
jkrcal 2017/06/06 15:41:55 Yes, it is because of performance. I did a small
pkotwicz 2017/06/07 17:40:52 Thank you for adding the explanation
619 statement.BindInt64(2, max_time.ToInternalValue());
566 return statement.Run(); 620 return statement.Run();
567 } 621 }
568 622
569 bool ThumbnailDatabase::DeleteFaviconBitmap(FaviconBitmapID bitmap_id) { 623 bool ThumbnailDatabase::DeleteFaviconBitmap(FaviconBitmapID bitmap_id) {
570 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 624 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
571 "DELETE FROM favicon_bitmaps WHERE id=?")); 625 "DELETE FROM favicon_bitmaps WHERE id=?"));
572 statement.BindInt64(0, bitmap_id); 626 statement.BindInt64(0, bitmap_id);
573 return statement.Run(); 627 return statement.Run();
574 } 628 }
575 629
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 meta_table_.SetVersionNumber(8); 1112 meta_table_.SetVersionNumber(8);
1059 meta_table_.SetCompatibleVersionNumber(std::min(8, kCompatibleVersionNumber)); 1113 meta_table_.SetCompatibleVersionNumber(std::min(8, kCompatibleVersionNumber));
1060 return true; 1114 return true;
1061 } 1115 }
1062 1116
1063 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() { 1117 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() {
1064 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons"); 1118 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons");
1065 } 1119 }
1066 1120
1067 } // namespace history 1121 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698