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

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: Peter's comments Created 3 years, 6 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 bitmaps of type ON_DEMAND, for clearing old
73 // should be retained on cleanup. 74 // entries. (On-demand bitmaps cannot get cleared along with
75 // expired visits in history DB.) On-demand bitmaps are
76 // defined by last_requested>0 and thus this field should
77 // never get updated for bitmaps of type ON_VISIT.
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 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 } 496 }
491 497
492 if (pixel_size) { 498 if (pixel_size) {
493 *pixel_size = gfx::Size(statement.ColumnInt(2), 499 *pixel_size = gfx::Size(statement.ColumnInt(2),
494 statement.ColumnInt(3)); 500 statement.ColumnInt(3));
495 } 501 }
496 502
497 if (last_requested) 503 if (last_requested)
498 *last_requested = base::Time::FromInternalValue(statement.ColumnInt64(4)); 504 *last_requested = base::Time::FromInternalValue(statement.ColumnInt64(4));
499 505
506 // Checking timestamps: last_requested is set only for bitmaps of type
507 // ON_DEMAND, last_updated timestamp is set only for bitmaps of type ON_VISIT.
508 DCHECK(!last_requested || !last_updated || *last_requested == base::Time() ||
509 *last_updated == base::Time())
510 << "the favicon " << bitmap_id << " does not have consistent timestamps";
pkotwicz 2017/06/07 17:40:53 I am not a big fan of DCHECKs in general. The main
jkrcal 2017/06/09 16:38:38 Okay, removed (as this is not tested by unit-test,
511
500 return true; 512 return true;
501 } 513 }
502 514
503 FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap( 515 FaviconBitmapID ThumbnailDatabase::AddFaviconBitmap(
504 favicon_base::FaviconID icon_id, 516 favicon_base::FaviconID icon_id,
505 const scoped_refptr<base::RefCountedMemory>& icon_data, 517 const scoped_refptr<base::RefCountedMemory>& icon_data,
518 FaviconBitmapType type,
506 base::Time time, 519 base::Time time,
507 const gfx::Size& pixel_size) { 520 const gfx::Size& pixel_size) {
508 DCHECK(icon_id); 521 DCHECK(icon_id);
509 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 522
510 "INSERT INTO favicon_bitmaps (icon_id, image_data, last_updated, width, " 523 sql::Statement statement(db_.GetCachedStatement(
511 "height) VALUES (?, ?, ?, ?, ?)")); 524 SQL_FROM_HERE,
525 type == ON_VISIT
526 // On-visit bitmaps:
527 // - keep track of last_updated: last write time is used for
528 // expiration;
529 // - always have last_requested==0: no need to keep track
530 // of last read time.
531 ? "INSERT INTO favicon_bitmaps (icon_id, image_data, last_updated, "
532 "width, height) VALUES (?, ?, ?, ?, ?)"
533 // On-demand bitmaps:
534 // - always have last_updated==0: last write time is not stored as
535 // they are always expired and thus ready to be replaced by
536 // ON_VISIT icons;
537 // - keep track of last_requested: last read time is used for cache
538 // eviction.
539 : "INSERT INTO favicon_bitmaps (icon_id, image_data, last_requested, "
540 "width, height) VALUES (?, ?, ?, ?, ?)"));
541
pkotwicz 2017/06/07 17:40:53 Can you do this instead: INSERT INTO favicon_bitm
jkrcal 2017/06/09 16:38:38 Ah, sure, much better.
512 statement.BindInt64(0, icon_id); 542 statement.BindInt64(0, icon_id);
513 if (icon_data.get() && icon_data->size()) { 543 if (icon_data.get() && icon_data->size()) {
514 statement.BindBlob(1, icon_data->front(), 544 statement.BindBlob(1, icon_data->front(),
515 static_cast<int>(icon_data->size())); 545 static_cast<int>(icon_data->size()));
516 } else { 546 } else {
517 statement.BindNull(1); 547 statement.BindNull(1);
518 } 548 }
549 // Both versions of the statement have a timestamp at index 2.
519 statement.BindInt64(2, time.ToInternalValue()); 550 statement.BindInt64(2, time.ToInternalValue());
520 statement.BindInt(3, pixel_size.width()); 551 statement.BindInt(3, pixel_size.width());
521 statement.BindInt(4, pixel_size.height()); 552 statement.BindInt(4, pixel_size.height());
522 553
523 if (!statement.Run()) 554 if (!statement.Run())
524 return 0; 555 return 0;
525 return db_.GetLastInsertRowId(); 556 return db_.GetLastInsertRowId();
526 } 557 }
527 558
528 bool ThumbnailDatabase::SetFaviconBitmap( 559 bool ThumbnailDatabase::SetFaviconBitmap(
529 FaviconBitmapID bitmap_id, 560 FaviconBitmapID bitmap_id,
530 scoped_refptr<base::RefCountedMemory> bitmap_data, 561 scoped_refptr<base::RefCountedMemory> bitmap_data,
531 base::Time time) { 562 base::Time time) {
532 DCHECK(bitmap_id); 563 DCHECK(bitmap_id);
533 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 564 // By updating last_updated timestamp, we assume the icon is of type ON_VISIT.
534 "UPDATE favicon_bitmaps SET image_data=?, last_updated=? WHERE id=?")); 565 // If it is ON_DEMAND, reset last_requested to 0 and thus silently change the
566 // type to ON_VISIT.
567 sql::Statement statement(
568 db_.GetCachedStatement(SQL_FROM_HERE,
569 "UPDATE favicon_bitmaps SET image_data=?, "
570 "last_updated=?, last_requested=? WHERE id=?"));
535 if (bitmap_data.get() && bitmap_data->size()) { 571 if (bitmap_data.get() && bitmap_data->size()) {
536 statement.BindBlob(0, bitmap_data->front(), 572 statement.BindBlob(0, bitmap_data->front(),
537 static_cast<int>(bitmap_data->size())); 573 static_cast<int>(bitmap_data->size()));
538 } else { 574 } else {
539 statement.BindNull(0); 575 statement.BindNull(0);
540 } 576 }
541 statement.BindInt64(1, time.ToInternalValue()); 577 statement.BindInt64(1, time.ToInternalValue());
542 statement.BindInt64(2, bitmap_id); 578 statement.BindInt64(2, 0);
579 statement.BindInt64(3, bitmap_id);
543 580
544 return statement.Run(); 581 return statement.Run();
545 } 582 }
546 583
547 bool ThumbnailDatabase::SetFaviconBitmapLastUpdateTime( 584 bool ThumbnailDatabase::SetFaviconBitmapLastUpdateTime(
548 FaviconBitmapID bitmap_id, 585 FaviconBitmapID bitmap_id,
549 base::Time time) { 586 base::Time time) {
550 DCHECK(bitmap_id); 587 DCHECK(bitmap_id);
551 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 588 // By updating last_updated timestamp, we assume the icon is of type ON_VISIT.
552 "UPDATE favicon_bitmaps SET last_updated=? WHERE id=?")); 589 // If it is ON_DEMAND, reset last_requested to 0 and thus silently change the
590 // type to ON_VISIT.
591 sql::Statement statement(
592 db_.GetCachedStatement(SQL_FROM_HERE,
593 "UPDATE favicon_bitmaps SET last_updated=?, "
594 "last_requested=? WHERE id=?"));
553 statement.BindInt64(0, time.ToInternalValue()); 595 statement.BindInt64(0, time.ToInternalValue());
554 statement.BindInt64(1, bitmap_id); 596 statement.BindInt64(1, 0);
597 statement.BindInt64(2, 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=?"));
pkotwicz 2017/06/07 17:40:53 Isn't it theoretically possible to have multiple e
jkrcal 2017/06/09 16:38:38 Done.
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
611 // Update the time only for ON_DEMAND bitmaps (i.e. with last_requested > 0).
612 sql::Statement statement(db_.GetCachedStatement(
613 SQL_FROM_HERE,
614 "UPDATE favicon_bitmaps SET last_requested=? WHERE icon_id=? AND "
615 "last_requested>0 AND last_requested<=?"));
564 statement.BindInt64(0, time.ToInternalValue()); 616 statement.BindInt64(0, time.ToInternalValue());
565 statement.BindInt64(1, bitmap_id); 617 statement.BindInt64(1, icon_id);
618 // For performance reasons update the time only if the currently stored time
619 // is old enough (UPDATEs where the WHERE condition does not match any entries
620 // are way faster than UPDATEs that really change some data).
pkotwicz 2017/06/07 17:40:53 Nit: Merge this comment with the comment on line 6
jkrcal 2017/06/09 16:38:38 Done.
621 base::Time max_time =
622 time - base::TimeDelta::FromDays(kFaviconUpdateLastRequestedAfterDays);
623 statement.BindInt64(2, max_time.ToInternalValue());
566 return statement.Run(); 624 return statement.Run();
567 } 625 }
568 626
569 bool ThumbnailDatabase::DeleteFaviconBitmap(FaviconBitmapID bitmap_id) { 627 bool ThumbnailDatabase::DeleteFaviconBitmap(FaviconBitmapID bitmap_id) {
570 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE, 628 sql::Statement statement(db_.GetCachedStatement(SQL_FROM_HERE,
571 "DELETE FROM favicon_bitmaps WHERE id=?")); 629 "DELETE FROM favicon_bitmaps WHERE id=?"));
572 statement.BindInt64(0, bitmap_id); 630 statement.BindInt64(0, bitmap_id);
573 return statement.Run(); 631 return statement.Run();
574 } 632 }
575 633
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 return db_.GetLastInsertRowId(); 688 return db_.GetLastInsertRowId();
631 } 689 }
632 690
633 favicon_base::FaviconID ThumbnailDatabase::AddFavicon( 691 favicon_base::FaviconID ThumbnailDatabase::AddFavicon(
634 const GURL& icon_url, 692 const GURL& icon_url,
635 favicon_base::IconType icon_type, 693 favicon_base::IconType icon_type,
636 const scoped_refptr<base::RefCountedMemory>& icon_data, 694 const scoped_refptr<base::RefCountedMemory>& icon_data,
637 base::Time time, 695 base::Time time,
638 const gfx::Size& pixel_size) { 696 const gfx::Size& pixel_size) {
639 favicon_base::FaviconID icon_id = AddFavicon(icon_url, icon_type); 697 favicon_base::FaviconID icon_id = AddFavicon(icon_url, icon_type);
640 if (!icon_id || !AddFaviconBitmap(icon_id, icon_data, time, pixel_size)) 698 if (!icon_id ||
699 !AddFaviconBitmap(icon_id, icon_data, FaviconBitmapType::ON_VISIT, time,
700 pixel_size))
641 return 0; 701 return 0;
642 702
643 return icon_id; 703 return icon_id;
644 } 704 }
645 705
646 bool ThumbnailDatabase::DeleteFavicon(favicon_base::FaviconID id) { 706 bool ThumbnailDatabase::DeleteFavicon(favicon_base::FaviconID id) {
647 sql::Statement statement; 707 sql::Statement statement;
648 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE, 708 statement.Assign(db_.GetCachedStatement(SQL_FROM_HERE,
649 "DELETE FROM favicons WHERE id = ?")); 709 "DELETE FROM favicons WHERE id = ?"));
650 statement.BindInt64(0, id); 710 statement.BindInt64(0, id);
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 meta_table_.SetVersionNumber(8); 1118 meta_table_.SetVersionNumber(8);
1059 meta_table_.SetCompatibleVersionNumber(std::min(8, kCompatibleVersionNumber)); 1119 meta_table_.SetCompatibleVersionNumber(std::min(8, kCompatibleVersionNumber));
1060 return true; 1120 return true;
1061 } 1121 }
1062 1122
1063 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() { 1123 bool ThumbnailDatabase::IsFaviconDBStructureIncorrect() {
1064 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons"); 1124 return !db_.IsSQLValid("SELECT id, url, icon_type FROM favicons");
1065 } 1125 }
1066 1126
1067 } // namespace history 1127 } // namespace history
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698