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

Side by Side Diff: components/offline_pages/offline_page_model_impl.cc

Issue 2415473003: Query API: Introduces an OfflinePageModelQuery object. (Closed)
Patch Set: Add tests and address comments. Created 4 years, 1 month 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/offline_pages/offline_page_model_impl.h" 5 #include "components/offline_pages/offline_page_model_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_util.h" 11 #include "base/files/file_util.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/rand_util.h" 15 #include "base/rand_util.h"
16 #include "base/sequenced_task_runner.h" 16 #include "base/sequenced_task_runner.h"
17 #include "base/strings/string16.h" 17 #include "base/strings/string16.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/threading/thread_task_runner_handle.h" 19 #include "base/threading/thread_task_runner_handle.h"
20 #include "base/time/clock.h" 20 #include "base/time/clock.h"
21 #include "base/time/time.h" 21 #include "base/time/time.h"
22 #include "components/offline_pages/archive_manager.h" 22 #include "components/offline_pages/archive_manager.h"
23 #include "components/offline_pages/client_namespace_constants.h" 23 #include "components/offline_pages/client_namespace_constants.h"
24 #include "components/offline_pages/client_policy_controller.h" 24 #include "components/offline_pages/client_policy_controller.h"
25 #include "components/offline_pages/offline_page_item.h" 25 #include "components/offline_pages/offline_page_item.h"
26 #include "components/offline_pages/offline_page_model_query.h"
26 #include "components/offline_pages/offline_page_storage_manager.h" 27 #include "components/offline_pages/offline_page_storage_manager.h"
27 #include "url/gurl.h" 28 #include "url/gurl.h"
28 29
29 using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult; 30 using ArchiverResult = offline_pages::OfflinePageArchiver::ArchiverResult;
30 using ClearStorageCallback = 31 using ClearStorageCallback =
31 offline_pages::OfflinePageStorageManager::ClearStorageCallback; 32 offline_pages::OfflinePageStorageManager::ClearStorageCallback;
32 using ClearStorageResult = 33 using ClearStorageResult =
33 offline_pages::OfflinePageStorageManager::ClearStorageResult; 34 offline_pages::OfflinePageStorageManager::ClearStorageResult;
34 35
35 namespace offline_pages { 36 namespace offline_pages {
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 425
425 archive_manager_->DeleteMultipleArchives( 426 archive_manager_->DeleteMultipleArchives(
426 paths_to_delete, 427 paths_to_delete,
427 base::Bind(&OfflinePageModelImpl::OnDeleteArchiveFilesDone, 428 base::Bind(&OfflinePageModelImpl::OnDeleteArchiveFilesDone,
428 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback)); 429 weak_ptr_factory_.GetWeakPtr(), offline_ids, callback));
429 } 430 }
430 431
431 void OfflinePageModelImpl::DeletePagesByClientIds( 432 void OfflinePageModelImpl::DeletePagesByClientIds(
432 const std::vector<ClientId>& client_ids, 433 const std::vector<ClientId>& client_ids,
433 const DeletePageCallback& callback) { 434 const DeletePageCallback& callback) {
434 RunWhenLoaded(base::Bind(&OfflinePageModelImpl::DoDeletePagesByClientIds, 435 OfflinePageModelQueryBuilder builder;
435 weak_ptr_factory_.GetWeakPtr(), client_ids, 436 builder.SetClientIds(client_ids).AllowExpiredPages(true);
436 callback)); 437 auto delete_pages = base::Bind(&OfflinePageModelImpl::DeletePages,
438 weak_ptr_factory_.GetWeakPtr(), callback);
439 RunWhenLoaded(base::Bind(
440 &OfflinePageModelImpl::ExecuteQuery, weak_ptr_factory_.GetWeakPtr(),
441 base::Passed(builder.Build(GetPolicyController())), delete_pages));
437 } 442 }
438 443
439 void OfflinePageModelImpl::DoDeletePagesByClientIds( 444 void OfflinePageModelImpl::DeletePages(
440 const std::vector<ClientId>& client_ids, 445 const DeletePageCallback& callback,
441 const DeletePageCallback& callback) { 446 const MultipleOfflinePageItemResult& pages) {
442 std::set<ClientId> client_id_set(client_ids.begin(), client_ids.end()); 447 DCHECK(is_loaded_);
443 448
444 std::vector<int64_t> offline_ids; 449 std::vector<int64_t> offline_ids;
445 for (const auto& page_pair : offline_pages_) { 450 for (auto& page : pages)
446 if (client_id_set.count(page_pair.second.client_id) > 0) 451 offline_ids.emplace_back(page.offline_id);
447 offline_ids.emplace_back(page_pair.first);
448 }
449 452
450 DoDeletePagesByOfflineId(offline_ids, callback); 453 DoDeletePagesByOfflineId(offline_ids, callback);
451 } 454 }
452 455
453 void OfflinePageModelImpl::GetPagesByClientIds( 456 void OfflinePageModelImpl::GetPagesByClientIds(
454 const std::vector<ClientId>& client_ids, 457 const std::vector<ClientId>& client_ids,
455 const MultipleOfflinePageItemCallback& callback) { 458 const MultipleOfflinePageItemCallback& callback) {
456 RunWhenLoaded(base::Bind(&OfflinePageModelImpl::DoGetPagesByClientIds, 459 OfflinePageModelQueryBuilder builder;
457 weak_ptr_factory_.GetWeakPtr(), client_ids, 460 builder.SetClientIds(client_ids);
458 callback)); 461 RunWhenLoaded(base::Bind(
459 } 462 &OfflinePageModelImpl::ExecuteQuery, weak_ptr_factory_.GetWeakPtr(),
460 463 base::Passed(builder.Build(GetPolicyController())), callback));
461 void OfflinePageModelImpl::DoGetPagesByClientIds(
462 const std::vector<ClientId>& client_ids,
463 const MultipleOfflinePageItemCallback& callback) {
464 std::set<ClientId> client_id_set(client_ids.begin(), client_ids.end());
465
466 std::vector<OfflinePageItem> result;
467 for (const auto& page_pair : offline_pages_) {
468 if (!page_pair.second.IsExpired() &&
469 client_id_set.count(page_pair.second.client_id) > 0) {
470 result.emplace_back(page_pair.second);
471 }
472 }
473 callback.Run(result);
474 } 464 }
475 465
476 void OfflinePageModelImpl::DeleteCachedPagesByURLPredicate( 466 void OfflinePageModelImpl::DeleteCachedPagesByURLPredicate(
477 const UrlPredicate& predicate, 467 const UrlPredicate& predicate,
478 const DeletePageCallback& callback) { 468 const DeletePageCallback& callback) {
479 RunWhenLoaded( 469 RunWhenLoaded(
480 base::Bind(&OfflinePageModelImpl::DoDeleteCachedPagesByURLPredicate, 470 base::Bind(&OfflinePageModelImpl::DoDeleteCachedPagesByURLPredicate,
481 weak_ptr_factory_.GetWeakPtr(), predicate, callback)); 471 weak_ptr_factory_.GetWeakPtr(), predicate, callback));
482 } 472 }
483 473
484 void OfflinePageModelImpl::DoDeleteCachedPagesByURLPredicate( 474 void OfflinePageModelImpl::DoDeleteCachedPagesByURLPredicate(
485 const UrlPredicate& predicate, 475 const UrlPredicate& predicate,
486 const DeletePageCallback& callback) { 476 const DeletePageCallback& callback) {
487 DCHECK(is_loaded_); 477 DCHECK(is_loaded_);
488 478
489 std::vector<int64_t> offline_ids; 479 std::vector<int64_t> offline_ids;
490 for (const auto& id_page_pair : offline_pages_) { 480 for (const auto& id_page_pair : offline_pages_) {
491 if (IsRemovedOnCacheReset(id_page_pair.second) && 481 if (IsRemovedOnCacheReset(id_page_pair.second) &&
492 predicate.Run(id_page_pair.second.url)) { 482 predicate.Run(id_page_pair.second.url)) {
493 offline_ids.push_back(id_page_pair.first); 483 offline_ids.push_back(id_page_pair.first);
494 } 484 }
495 } 485 }
496 DoDeletePagesByOfflineId(offline_ids, callback); 486 DoDeletePagesByOfflineId(offline_ids, callback);
497 } 487 }
498 488
499 void OfflinePageModelImpl::CheckPagesExistOffline( 489 void OfflinePageModelImpl::CheckPagesExistOffline(
500 const std::set<GURL>& urls, 490 const std::set<GURL>& urls,
501 const CheckPagesExistOfflineCallback& callback) { 491 const CheckPagesExistOfflineCallback& callback) {
502 RunWhenLoaded( 492 OfflinePageModelQueryBuilder builder;
503 base::Bind(&OfflinePageModelImpl::CheckPagesExistOfflineAfterLoadDone, 493 builder.SetUrls(std::vector<GURL>(urls.begin(), urls.end()))
504 weak_ptr_factory_.GetWeakPtr(), urls, callback)); 494 .RequireRestrictedToOriginalTab(
495 OfflinePageModelQueryBuilder::Requirement::OnlyNotMatching);
496 auto pages_to_urls = base::Bind(
497 [](const CheckPagesExistOfflineCallback& callback,
498 const MultipleOfflinePageItemResult& pages) {
499 CheckPagesExistOfflineResult result;
500 for (auto& page : pages)
501 result.insert(page.url);
502 callback.Run(result);
503 },
504 callback);
505 RunWhenLoaded(base::Bind(
506 &OfflinePageModelImpl::ExecuteQuery, weak_ptr_factory_.GetWeakPtr(),
507 base::Passed(builder.Build(GetPolicyController())), pages_to_urls));
505 } 508 }
506 509
507 void OfflinePageModelImpl::CheckPagesExistOfflineAfterLoadDone( 510 void OfflinePageModelImpl::ExecuteQuery(
508 const std::set<GURL>& urls, 511 std::unique_ptr<OfflinePageModelQuery> query,
509 const CheckPagesExistOfflineCallback& callback) { 512 const MultipleOfflinePageItemCallback& callback) {
510 DCHECK(is_loaded_); 513 // TODO(dewittj): some sort of signalling here?
511 CheckPagesExistOfflineResult result; 514 if (!query)
512 for (const auto& id_page_pair : offline_pages_) { 515 return;
513 // TODO(dewittj): Remove the "Last N" restriction in favor of a better query 516
514 // interface. See https://crbug.com/622763 for information. 517 MultipleOfflinePageItemResult offline_pages_result;
515 if (id_page_pair.second.IsExpired() || 518
516 id_page_pair.second.client_id.name_space == kLastNNamespace) 519 std::set<int64_t> offline_ids;
517 continue; 520 // Optimization: since we store as a map of offline IDs, we will look them up
518 auto iter = urls.find(id_page_pair.second.url); 521 // directly if we have an explicit ID list.
519 if (iter != urls.end()) 522 if (query->GetRestrictedToOfflineIds(&offline_ids)) {
520 result.insert(*iter); 523 for (int64_t id : offline_ids) {
524 if (offline_pages_.count(id) > 0 && query->Matches(offline_pages_[id]))
525 offline_pages_result.emplace_back(offline_pages_[id]);
526 }
527 } else {
528 for (const auto& id_page_pair : offline_pages_) {
529 if (query->Matches(id_page_pair.second))
530 offline_pages_result.emplace_back(id_page_pair.second);
531 }
521 } 532 }
522 callback.Run(result); 533
534 callback.Run(offline_pages_result);
523 } 535 }
524 536
525 void OfflinePageModelImpl::GetAllPages( 537 void OfflinePageModelImpl::GetAllPages(
526 const MultipleOfflinePageItemCallback& callback) { 538 const MultipleOfflinePageItemCallback& callback) {
527 RunWhenLoaded(base::Bind(&OfflinePageModelImpl::GetAllPagesAfterLoadDone, 539 OfflinePageModelQueryBuilder builder;
528 weak_ptr_factory_.GetWeakPtr(), GetAllPageMode::ALL, 540 RunWhenLoaded(base::Bind(
529 callback)); 541 &OfflinePageModelImpl::ExecuteQuery, weak_ptr_factory_.GetWeakPtr(),
542 base::Passed(builder.Build(GetPolicyController())), callback));
530 } 543 }
531 544
532 void OfflinePageModelImpl::GetAllPagesWithExpired( 545 void OfflinePageModelImpl::GetAllPagesWithExpired(
533 const MultipleOfflinePageItemCallback& callback) { 546 const MultipleOfflinePageItemCallback& callback) {
534 RunWhenLoaded(base::Bind(&OfflinePageModelImpl::GetAllPagesAfterLoadDone, 547 OfflinePageModelQueryBuilder builder;
535 weak_ptr_factory_.GetWeakPtr(), 548 builder.AllowExpiredPages(true);
536 GetAllPageMode::ALL_WITH_EXPIRED, callback));
537 }
538 549
539 void OfflinePageModelImpl::GetAllPagesAfterLoadDone( 550 RunWhenLoaded(base::Bind(
540 GetAllPageMode mode, 551 &OfflinePageModelImpl::ExecuteQuery, weak_ptr_factory_.GetWeakPtr(),
541 const MultipleOfflinePageItemCallback& callback) const { 552 base::Passed(builder.Build(GetPolicyController())), callback));
542 DCHECK(is_loaded_);
543
544 MultipleOfflinePageItemResult offline_pages;
545 for (const auto& id_page_pair : offline_pages_) {
546 if (mode == GetAllPageMode::ALL_WITH_EXPIRED ||
547 !id_page_pair.second.IsExpired())
548 offline_pages.push_back(id_page_pair.second);
549 }
550
551 callback.Run(offline_pages);
552 } 553 }
553 554
554 void OfflinePageModelImpl::GetOfflineIdsForClientId( 555 void OfflinePageModelImpl::GetOfflineIdsForClientId(
555 const ClientId& client_id, 556 const ClientId& client_id,
556 const MultipleOfflineIdCallback& callback) { 557 const MultipleOfflineIdCallback& callback) {
557 RunWhenLoaded( 558 RunWhenLoaded(
558 base::Bind(&OfflinePageModelImpl::GetOfflineIdsForClientIdWhenLoadDone, 559 base::Bind(&OfflinePageModelImpl::GetOfflineIdsForClientIdWhenLoadDone,
559 weak_ptr_factory_.GetWeakPtr(), client_id, callback)); 560 weak_ptr_factory_.GetWeakPtr(), client_id, callback));
560 } 561 }
561 562
(...skipping 15 matching lines...) Expand all
577 !id_page_pair.second.IsExpired()) { 578 !id_page_pair.second.IsExpired()) {
578 results.push_back(id_page_pair.second.offline_id); 579 results.push_back(id_page_pair.second.offline_id);
579 } 580 }
580 } 581 }
581 return results; 582 return results;
582 } 583 }
583 584
584 void OfflinePageModelImpl::GetPageByOfflineId( 585 void OfflinePageModelImpl::GetPageByOfflineId(
585 int64_t offline_id, 586 int64_t offline_id,
586 const SingleOfflinePageItemCallback& callback) { 587 const SingleOfflinePageItemCallback& callback) {
587 RunWhenLoaded( 588 std::vector<int64_t> query_ids;
588 base::Bind(&OfflinePageModelImpl::GetPageByOfflineIdWhenLoadDone, 589 query_ids.emplace_back(offline_id);
589 weak_ptr_factory_.GetWeakPtr(), offline_id, callback));
590 }
591 590
592 void OfflinePageModelImpl::GetPageByOfflineIdWhenLoadDone( 591 OfflinePageModelQueryBuilder builder;
593 int64_t offline_id, 592 builder.SetOfflinePageIds(query_ids);
594 const SingleOfflinePageItemCallback& callback) const {
595 callback.Run(MaybeGetPageByOfflineId(offline_id));
596 }
597 593
598 const OfflinePageItem* OfflinePageModelImpl::MaybeGetPageByOfflineId( 594 auto multiple_callback = base::Bind(
599 int64_t offline_id) const { 595 [](const SingleOfflinePageItemCallback& callback,
600 const auto iter = offline_pages_.find(offline_id); 596 const MultipleOfflinePageItemResult& result) {
601 return iter != offline_pages_.end() && !iter->second.IsExpired() 597 DCHECK_LE(result.size(), 1U);
602 ? &(iter->second) 598 if (result.empty()) {
603 : nullptr; 599 callback.Run(nullptr);
600 } else {
601 callback.Run(&result[0]);
602 }
603 },
604 callback);
605
606 RunWhenLoaded(base::Bind(
607 &OfflinePageModelImpl::ExecuteQuery, weak_ptr_factory_.GetWeakPtr(),
608 base::Passed(builder.Build(GetPolicyController())), multiple_callback));
604 } 609 }
605 610
606 void OfflinePageModelImpl::GetPagesByOnlineURL( 611 void OfflinePageModelImpl::GetPagesByOnlineURL(
607 const GURL& online_url, 612 const GURL& online_url,
608 const MultipleOfflinePageItemCallback& callback) { 613 const MultipleOfflinePageItemCallback& callback) {
609 RunWhenLoaded( 614 RunWhenLoaded(
610 base::Bind(&OfflinePageModelImpl::GetPagesByOnlineURLWhenLoadDone, 615 base::Bind(&OfflinePageModelImpl::GetPagesByOnlineURLWhenLoadDone,
611 weak_ptr_factory_.GetWeakPtr(), online_url, callback)); 616 weak_ptr_factory_.GetWeakPtr(), online_url, callback));
612 } 617 }
613 618
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 } 1085 }
1081 1086
1082 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); 1087 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
1083 } 1088 }
1084 1089
1085 base::Time OfflinePageModelImpl::GetCurrentTime() const { 1090 base::Time OfflinePageModelImpl::GetCurrentTime() const {
1086 return testing_clock_ ? testing_clock_->Now() : base::Time::Now(); 1091 return testing_clock_ ? testing_clock_->Now() : base::Time::Now();
1087 } 1092 }
1088 1093
1089 } // namespace offline_pages 1094 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698