OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |