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

Side by Side Diff: webkit/appcache/appcache_storage_impl.cc

Issue 7031065: AppCache + Quota integration (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "webkit/appcache/appcache_storage_impl.h" 5 #include "webkit/appcache/appcache_storage_impl.h"
6 6
7 #include <set>
8
7 #include "app/sql/connection.h" 9 #include "app/sql/connection.h"
8 #include "app/sql/transaction.h" 10 #include "app/sql/transaction.h"
9 #include "base/file_util.h" 11 #include "base/file_util.h"
10 #include "base/logging.h" 12 #include "base/logging.h"
11 #include "base/message_loop.h" 13 #include "base/message_loop.h"
12 #include "base/stl_util-inl.h" 14 #include "base/stl_util-inl.h"
13 #include "base/string_util.h" 15 #include "base/string_util.h"
14 #include "net/base/cache_type.h" 16 #include "net/base/cache_type.h"
15 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
16 #include "webkit/appcache/appcache.h" 18 #include "webkit/appcache/appcache.h"
17 #include "webkit/appcache/appcache_database.h" 19 #include "webkit/appcache/appcache_database.h"
18 #include "webkit/appcache/appcache_entry.h" 20 #include "webkit/appcache/appcache_entry.h"
19 #include "webkit/appcache/appcache_group.h" 21 #include "webkit/appcache/appcache_group.h"
20 #include "webkit/appcache/appcache_histograms.h" 22 #include "webkit/appcache/appcache_histograms.h"
21 #include "webkit/appcache/appcache_policy.h" 23 #include "webkit/appcache/appcache_policy.h"
24 #include "webkit/appcache/appcache_quota_client.h"
22 #include "webkit/appcache/appcache_response.h" 25 #include "webkit/appcache/appcache_response.h"
23 #include "webkit/appcache/appcache_service.h" 26 #include "webkit/appcache/appcache_service.h"
24 #include "webkit/appcache/appcache_thread.h" 27 #include "webkit/appcache/appcache_thread.h"
28 #include "webkit/quota/quota_client.h"
29 #include "webkit/quota/quota_manager.h"
25 #include "webkit/quota/special_storage_policy.h" 30 #include "webkit/quota/special_storage_policy.h"
26 31
27 namespace { 32 namespace {
28 // Helper with no return value for use with NewRunnableFunction. 33 // Helper with no return value for use with NewRunnableFunction.
29 void DeleteDirectory(const FilePath& path) { 34 void DeleteDirectory(const FilePath& path) {
30 file_util::Delete(path, true); 35 file_util::Delete(path, true);
31 } 36 }
32 } 37 }
33 38
34 namespace appcache { 39 namespace appcache {
35 40
41 // Hard coded default when not using quota management.
42 static const int kDefaultQuota = 5 * 1024 * 1024;
43
36 static const int kMaxDiskCacheSize = 250 * 1024 * 1024; 44 static const int kMaxDiskCacheSize = 250 * 1024 * 1024;
37 static const int kMaxMemDiskCacheSize = 10 * 1024 * 1024; 45 static const int kMaxMemDiskCacheSize = 10 * 1024 * 1024;
38 static const FilePath::CharType kDiskCacheDirectoryName[] = 46 static const FilePath::CharType kDiskCacheDirectoryName[] =
39 FILE_PATH_LITERAL("Cache"); 47 FILE_PATH_LITERAL("Cache");
40 48
41 // DatabaseTask ----------------------------------------- 49 // DatabaseTask -----------------------------------------
42 50
43 class AppCacheStorageImpl::DatabaseTask 51 class AppCacheStorageImpl::DatabaseTask
44 : public base::RefCountedThreadSafe<DatabaseTask> { 52 : public base::RefCountedThreadSafe<DatabaseTask> {
45 public: 53 public:
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 last_cache_id_(0), last_response_id_(0), 147 last_cache_id_(0), last_response_id_(0),
140 last_deletable_response_rowid_(0) {} 148 last_deletable_response_rowid_(0) {}
141 149
142 virtual void Run(); 150 virtual void Run();
143 virtual void RunCompleted(); 151 virtual void RunCompleted();
144 152
145 int64 last_group_id_; 153 int64 last_group_id_;
146 int64 last_cache_id_; 154 int64 last_cache_id_;
147 int64 last_response_id_; 155 int64 last_response_id_;
148 int64 last_deletable_response_rowid_; 156 int64 last_deletable_response_rowid_;
149 std::set<GURL> origins_with_groups_; 157 std::map<GURL, int64> usage_map_;
150 }; 158 };
151 159
152 void AppCacheStorageImpl::InitTask::Run() { 160 void AppCacheStorageImpl::InitTask::Run() {
153 database_->FindLastStorageIds( 161 database_->FindLastStorageIds(
154 &last_group_id_, &last_cache_id_, &last_response_id_, 162 &last_group_id_, &last_cache_id_, &last_response_id_,
155 &last_deletable_response_rowid_); 163 &last_deletable_response_rowid_);
156 database_->FindOriginsWithGroups(&origins_with_groups_); 164 database_->GetAllOriginUsage(&usage_map_);
157 } 165 }
158 166
159 void AppCacheStorageImpl::InitTask::RunCompleted() { 167 void AppCacheStorageImpl::InitTask::RunCompleted() {
160 storage_->last_group_id_ = last_group_id_; 168 storage_->last_group_id_ = last_group_id_;
161 storage_->last_cache_id_ = last_cache_id_; 169 storage_->last_cache_id_ = last_cache_id_;
162 storage_->last_response_id_ = last_response_id_; 170 storage_->last_response_id_ = last_response_id_;
163 storage_->last_deletable_response_rowid_ = last_deletable_response_rowid_; 171 storage_->last_deletable_response_rowid_ = last_deletable_response_rowid_;
164 172
165 if (!storage_->is_disabled()) { 173 if (!storage_->is_disabled()) {
166 storage_->origins_with_groups_.swap(origins_with_groups_); 174 storage_->usage_map_.swap(usage_map_);
167
168 const int kDelayMillis = 5 * 60 * 1000; // Five minutes. 175 const int kDelayMillis = 5 * 60 * 1000; // Five minutes.
169 MessageLoop::current()->PostDelayedTask(FROM_HERE, 176 MessageLoop::current()->PostDelayedTask(FROM_HERE,
170 storage_->method_factory_.NewRunnableMethod( 177 storage_->method_factory_.NewRunnableMethod(
171 &AppCacheStorageImpl::DelayedStartDeletingUnusedResponses), 178 &AppCacheStorageImpl::DelayedStartDeletingUnusedResponses),
172 kDelayMillis); 179 kDelayMillis);
173 } 180 }
181
182 if (storage_->service()->quota_client())
183 storage_->service()->quota_client()->NotifyAppCacheReady();
174 } 184 }
175 185
176 // CloseConnectionTask ------- 186 // CloseConnectionTask -------
177 187
178 class AppCacheStorageImpl::CloseConnectionTask : public DatabaseTask { 188 class AppCacheStorageImpl::CloseConnectionTask : public DatabaseTask {
179 public: 189 public:
180 explicit CloseConnectionTask(AppCacheStorageImpl* storage) 190 explicit CloseConnectionTask(AppCacheStorageImpl* storage)
181 : DatabaseTask(storage) {} 191 : DatabaseTask(storage) {}
182 192
183 virtual void Run() { database_->CloseConnection(); } 193 virtual void Run() { database_->CloseConnection(); }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 // We have to update foriegn entries if MarkEntryAsForeignTasks 305 // We have to update foriegn entries if MarkEntryAsForeignTasks
296 // are in flight. 306 // are in flight.
297 std::vector<GURL> urls; 307 std::vector<GURL> urls;
298 storage_->GetPendingForeignMarkingsForCache(cache->get()->cache_id(), &urls); 308 storage_->GetPendingForeignMarkingsForCache(cache->get()->cache_id(), &urls);
299 for (std::vector<GURL>::iterator iter = urls.begin(); 309 for (std::vector<GURL>::iterator iter = urls.begin();
300 iter != urls.end(); ++iter) { 310 iter != urls.end(); ++iter) {
301 DCHECK(cache->get()->GetEntry(*iter)); 311 DCHECK(cache->get()->GetEntry(*iter));
302 cache->get()->GetEntry(*iter)->add_types(AppCacheEntry::FOREIGN); 312 cache->get()->GetEntry(*iter)->add_types(AppCacheEntry::FOREIGN);
303 } 313 }
304 314
315 storage_->NotifyStorageAccessed(group_record_.origin);
316
305 // TODO(michaeln): Maybe verify that the responses we expect to exist 317 // TODO(michaeln): Maybe verify that the responses we expect to exist
306 // do actually exist in the disk_cache (and if not then what?) 318 // do actually exist in the disk_cache (and if not then what?)
307 } 319 }
308 320
309 // CacheLoadTask ------- 321 // CacheLoadTask -------
310 322
311 class AppCacheStorageImpl::CacheLoadTask : public StoreOrLoadTask { 323 class AppCacheStorageImpl::CacheLoadTask : public StoreOrLoadTask {
312 public: 324 public:
313 CacheLoadTask(int64 cache_id, AppCacheStorageImpl* storage) 325 CacheLoadTask(int64 cache_id, AppCacheStorageImpl* storage)
314 : StoreOrLoadTask(storage), cache_id_(cache_id), 326 : StoreOrLoadTask(storage), cache_id_(cache_id),
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 FOR_EACH_DELEGATE(delegates_, OnGroupLoaded(group, manifest_url_)); 400 FOR_EACH_DELEGATE(delegates_, OnGroupLoaded(group, manifest_url_));
389 } 401 }
390 402
391 // StoreGroupAndCacheTask ------- 403 // StoreGroupAndCacheTask -------
392 404
393 class AppCacheStorageImpl::StoreGroupAndCacheTask : public StoreOrLoadTask { 405 class AppCacheStorageImpl::StoreGroupAndCacheTask : public StoreOrLoadTask {
394 public: 406 public:
395 StoreGroupAndCacheTask(AppCacheStorageImpl* storage, AppCacheGroup* group, 407 StoreGroupAndCacheTask(AppCacheStorageImpl* storage, AppCacheGroup* group,
396 AppCache* newest_cache); 408 AppCache* newest_cache);
397 409
410 void GetQuotaThenSchedule();
411 void OnQuotaCallback(
412 quota::QuotaStatusCode status, int64 usage, int64 quota);
413
398 virtual void Run(); 414 virtual void Run();
399 virtual void RunCompleted(); 415 virtual void RunCompleted();
400 virtual void CancelCompletion(); 416 virtual void CancelCompletion();
401 417
402 scoped_refptr<AppCacheGroup> group_; 418 scoped_refptr<AppCacheGroup> group_;
403 scoped_refptr<AppCache> cache_; 419 scoped_refptr<AppCache> cache_;
404 bool success_; 420 bool success_;
405 bool would_exceed_quota_; 421 bool would_exceed_quota_;
406 int64 quota_override_; 422 int64 space_available_;
423 int64 new_origin_usage_;
407 std::vector<int64> newly_deletable_response_ids_; 424 std::vector<int64> newly_deletable_response_ids_;
408 }; 425 };
409 426
410 AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask( 427 AppCacheStorageImpl::StoreGroupAndCacheTask::StoreGroupAndCacheTask(
411 AppCacheStorageImpl* storage, AppCacheGroup* group, AppCache* newest_cache) 428 AppCacheStorageImpl* storage, AppCacheGroup* group, AppCache* newest_cache)
412 : StoreOrLoadTask(storage), group_(group), cache_(newest_cache), 429 : StoreOrLoadTask(storage), group_(group), cache_(newest_cache),
413 success_(false), would_exceed_quota_(false), 430 success_(false), would_exceed_quota_(false),
414 quota_override_(-1) { 431 space_available_(-1), new_origin_usage_(-1) {
415 group_record_.group_id = group->group_id(); 432 group_record_.group_id = group->group_id();
416 group_record_.manifest_url = group->manifest_url(); 433 group_record_.manifest_url = group->manifest_url();
417 group_record_.origin = group_record_.manifest_url.GetOrigin(); 434 group_record_.origin = group_record_.manifest_url.GetOrigin();
418 newest_cache->ToDatabaseRecords( 435 newest_cache->ToDatabaseRecords(
419 group, 436 group,
420 &cache_record_, &entry_records_, &fallback_namespace_records_, 437 &cache_record_, &entry_records_, &fallback_namespace_records_,
421 &online_whitelist_records_); 438 &online_whitelist_records_);
439 }
422 440
423 if (storage->service()->special_storage_policy() && 441 void AppCacheStorageImpl::StoreGroupAndCacheTask::GetQuotaThenSchedule() {
424 storage->service()->special_storage_policy()->IsStorageUnlimited( 442 quota::QuotaManager* quota_manager = NULL;
425 group_record_.origin)) { 443 if (storage_->service()->quota_manager_proxy()) {
426 quota_override_ = kint64max; 444 quota_manager =
445 storage_->service()->quota_manager_proxy()->quota_manager();
427 } 446 }
447
448 if (!quota_manager) {
449 if (storage_->service()->special_storage_policy() &&
450 storage_->service()->special_storage_policy()->IsStorageUnlimited(
451 group_record_.origin))
452 space_available_ = kint64max;
453 Schedule();
454 return;
455 }
456
457 // We have to ask the quota manager for the value.
458 AddRef(); // balanced in the OnQuotaCallback
459 storage_->pending_quota_queries_.insert(this);
460 quota_manager->GetUsageAndQuota(
461 group_record_.origin, quota::kStorageTypeTemporary,
462 NewCallback(this, &StoreGroupAndCacheTask::OnQuotaCallback));
463 }
464
465 void AppCacheStorageImpl::StoreGroupAndCacheTask::OnQuotaCallback(
466 quota::QuotaStatusCode status, int64 usage, int64 quota) {
467 if (storage_) {
468 if (status == quota::kQuotaStatusOk)
469 space_available_ = std::max(static_cast<int64>(0), quota - usage);
470 else
471 space_available_ = 0;
472 storage_->pending_quota_queries_.erase(this);
473 Schedule();
474 }
475 Release(); // balanced in GetQuotaThenSchedule
428 } 476 }
429 477
430 void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() { 478 void AppCacheStorageImpl::StoreGroupAndCacheTask::Run() {
431 DCHECK(!success_); 479 DCHECK(!success_);
432 sql::Connection* connection = database_->db_connection(); 480 sql::Connection* connection = database_->db_connection();
433 if (!connection) 481 if (!connection)
434 return; 482 return;
435 483
436 sql::Transaction transaction(connection); 484 sql::Transaction transaction(connection);
437 if (!transaction.Begin()) 485 if (!transaction.Begin())
438 return; 486 return;
439 487
488 int64 old_origin_usage = database_->GetOriginUsage(group_record_.origin);
489
440 AppCacheDatabase::GroupRecord existing_group; 490 AppCacheDatabase::GroupRecord existing_group;
441 success_ = database_->FindGroup(group_record_.group_id, &existing_group); 491 success_ = database_->FindGroup(group_record_.group_id, &existing_group);
442 if (!success_) { 492 if (!success_) {
443 group_record_.creation_time = base::Time::Now(); 493 group_record_.creation_time = base::Time::Now();
444 group_record_.last_access_time = base::Time::Now(); 494 group_record_.last_access_time = base::Time::Now();
445 success_ = database_->InsertGroup(&group_record_); 495 success_ = database_->InsertGroup(&group_record_);
446 } else { 496 } else {
447 DCHECK(group_record_.group_id == existing_group.group_id); 497 DCHECK(group_record_.group_id == existing_group.group_id);
448 DCHECK(group_record_.manifest_url == existing_group.manifest_url); 498 DCHECK(group_record_.manifest_url == existing_group.manifest_url);
449 DCHECK(group_record_.origin == existing_group.origin); 499 DCHECK(group_record_.origin == existing_group.origin);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 success_ = 537 success_ =
488 success_ && 538 success_ &&
489 database_->InsertCache(&cache_record_) && 539 database_->InsertCache(&cache_record_) &&
490 database_->InsertEntryRecords(entry_records_) && 540 database_->InsertEntryRecords(entry_records_) &&
491 database_->InsertFallbackNameSpaceRecords(fallback_namespace_records_)&& 541 database_->InsertFallbackNameSpaceRecords(fallback_namespace_records_)&&
492 database_->InsertOnlineWhiteListRecords(online_whitelist_records_); 542 database_->InsertOnlineWhiteListRecords(online_whitelist_records_);
493 543
494 if (!success_) 544 if (!success_)
495 return; 545 return;
496 546
497 int64 quota = (quota_override_ >= 0) ? 547 new_origin_usage_ = database_->GetOriginUsage(group_record_.origin);
498 quota_override_ :
499 database_->GetOriginQuota(group_record_.origin);
500 548
501 if (database_->GetOriginUsage(group_record_.origin) > quota) { 549 // Only check quota when the new usage exceeds the old usage.
550 if (new_origin_usage_ <= old_origin_usage) {
551 success_ = transaction.Commit();
552 return;
553 }
554
555 // Use a simple hard-coded value when not using quota management.
556 if (space_available_ == -1) {
557 if (new_origin_usage_ > kDefaultQuota) {
558 would_exceed_quota_ = true;
559 success_ = false;
560 return;
561 }
562 success_ = transaction.Commit();
563 return;
564 }
565
566 // Check limits based on the space availbable given to us via the
567 // quota system.
568 int64 delta = new_origin_usage_ - old_origin_usage;
569 if (delta > space_available_) {
502 would_exceed_quota_ = true; 570 would_exceed_quota_ = true;
503 success_ = false; 571 success_ = false;
504 return; 572 return;
505 } 573 }
506 574
507 success_ = transaction.Commit(); 575 success_ = transaction.Commit();
508 } 576 }
509 577
510 void AppCacheStorageImpl::StoreGroupAndCacheTask::RunCompleted() { 578 void AppCacheStorageImpl::StoreGroupAndCacheTask::RunCompleted() {
511 if (success_) { 579 if (success_) {
512 storage_->origins_with_groups_.insert(group_->manifest_url().GetOrigin()); 580 storage_->UpdateUsageMapAndNotify(
581 group_->manifest_url().GetOrigin(), new_origin_usage_);
513 if (cache_ != group_->newest_complete_cache()) { 582 if (cache_ != group_->newest_complete_cache()) {
514 cache_->set_complete(true); 583 cache_->set_complete(true);
515 group_->AddCache(cache_); 584 group_->AddCache(cache_);
516 } 585 }
517 if (group_->creation_time().is_null()) 586 if (group_->creation_time().is_null())
518 group_->set_creation_time(group_record_.creation_time); 587 group_->set_creation_time(group_record_.creation_time);
519 group_->AddNewlyDeletableResponseIds(&newly_deletable_response_ids_); 588 group_->AddNewlyDeletableResponseIds(&newly_deletable_response_ids_);
520 } 589 }
521 FOR_EACH_DELEGATE(delegates_, 590 FOR_EACH_DELEGATE(delegates_,
522 OnGroupAndNewestCacheStored(group_, cache_, success_, 591 OnGroupAndNewestCacheStored(group_, cache_, success_,
523 would_exceed_quota_)); 592 would_exceed_quota_));
524 group_ = NULL; 593 group_ = NULL;
525 cache_ = NULL; 594 cache_ = NULL;
595
596 // TODO(michaeln): if (would_exceed_quota_) what if the current usage
597 // also exceeds the quota? http://crbug.com/83968
526 } 598 }
527 599
528 void AppCacheStorageImpl::StoreGroupAndCacheTask::CancelCompletion() { 600 void AppCacheStorageImpl::StoreGroupAndCacheTask::CancelCompletion() {
529 // Overriden to safely drop our reference to the group and cache 601 // Overriden to safely drop our reference to the group and cache
530 // which are not thread safe refcounted. 602 // which are not thread safe refcounted.
531 DatabaseTask::CancelCompletion(); 603 DatabaseTask::CancelCompletion();
532 group_ = NULL; 604 group_ = NULL;
533 cache_ = NULL; 605 cache_ = NULL;
534 } 606 }
535 607
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 class AppCacheStorageImpl::MakeGroupObsoleteTask : public DatabaseTask { 902 class AppCacheStorageImpl::MakeGroupObsoleteTask : public DatabaseTask {
831 public: 903 public:
832 MakeGroupObsoleteTask(AppCacheStorageImpl* storage, AppCacheGroup* group); 904 MakeGroupObsoleteTask(AppCacheStorageImpl* storage, AppCacheGroup* group);
833 905
834 virtual void Run(); 906 virtual void Run();
835 virtual void RunCompleted(); 907 virtual void RunCompleted();
836 virtual void CancelCompletion(); 908 virtual void CancelCompletion();
837 909
838 scoped_refptr<AppCacheGroup> group_; 910 scoped_refptr<AppCacheGroup> group_;
839 int64 group_id_; 911 int64 group_id_;
912 GURL origin_;
840 bool success_; 913 bool success_;
841 std::set<GURL> origins_with_groups_; 914 int64 new_origin_usage_;
842 std::vector<int64> newly_deletable_response_ids_; 915 std::vector<int64> newly_deletable_response_ids_;
843 }; 916 };
844 917
845 AppCacheStorageImpl::MakeGroupObsoleteTask::MakeGroupObsoleteTask( 918 AppCacheStorageImpl::MakeGroupObsoleteTask::MakeGroupObsoleteTask(
846 AppCacheStorageImpl* storage, AppCacheGroup* group) 919 AppCacheStorageImpl* storage, AppCacheGroup* group)
847 : DatabaseTask(storage), group_(group), group_id_(group->group_id()), 920 : DatabaseTask(storage), group_(group), group_id_(group->group_id()),
848 success_(false) { 921 origin_(group->manifest_url().GetOrigin()),
922 success_(false), new_origin_usage_(-1) {
849 } 923 }
850 924
851 void AppCacheStorageImpl::MakeGroupObsoleteTask::Run() { 925 void AppCacheStorageImpl::MakeGroupObsoleteTask::Run() {
852 DCHECK(!success_); 926 DCHECK(!success_);
853 sql::Connection* connection = database_->db_connection(); 927 sql::Connection* connection = database_->db_connection();
854 if (!connection) 928 if (!connection)
855 return; 929 return;
856 930
857 sql::Transaction transaction(connection); 931 sql::Transaction transaction(connection);
858 if (!transaction.Begin()) 932 if (!transaction.Begin())
859 return; 933 return;
860 934
861 AppCacheDatabase::GroupRecord group_record; 935 AppCacheDatabase::GroupRecord group_record;
862 if (!database_->FindGroup(group_id_, &group_record)) { 936 if (!database_->FindGroup(group_id_, &group_record)) {
863 // This group doesn't exists in the database, nothing todo here. 937 // This group doesn't exists in the database, nothing todo here.
938 new_origin_usage_ = database_->GetOriginUsage(origin_);
864 success_ = true; 939 success_ = true;
865 return; 940 return;
866 } 941 }
867 942
943 DCHECK_EQ(group_record.origin, origin_);
944
868 AppCacheDatabase::CacheRecord cache_record; 945 AppCacheDatabase::CacheRecord cache_record;
869 if (database_->FindCacheForGroup(group_id_, &cache_record)) { 946 if (database_->FindCacheForGroup(group_id_, &cache_record)) {
870 database_->FindResponseIdsForCacheAsVector(cache_record.cache_id, 947 database_->FindResponseIdsForCacheAsVector(cache_record.cache_id,
871 &newly_deletable_response_ids_); 948 &newly_deletable_response_ids_);
872 success_ = 949 success_ =
873 database_->DeleteGroup(group_id_) && 950 database_->DeleteGroup(group_id_) &&
874 database_->DeleteCache(cache_record.cache_id) && 951 database_->DeleteCache(cache_record.cache_id) &&
875 database_->DeleteEntriesForCache(cache_record.cache_id) && 952 database_->DeleteEntriesForCache(cache_record.cache_id) &&
876 database_->DeleteFallbackNameSpacesForCache(cache_record.cache_id) && 953 database_->DeleteFallbackNameSpacesForCache(cache_record.cache_id) &&
877 database_->DeleteOnlineWhiteListForCache(cache_record.cache_id) && 954 database_->DeleteOnlineWhiteListForCache(cache_record.cache_id) &&
878 database_->InsertDeletableResponseIds(newly_deletable_response_ids_); 955 database_->InsertDeletableResponseIds(newly_deletable_response_ids_);
879 } else { 956 } else {
880 NOTREACHED() << "A existing group without a cache is unexpected"; 957 NOTREACHED() << "A existing group without a cache is unexpected";
881 success_ = database_->DeleteGroup(group_id_); 958 success_ = database_->DeleteGroup(group_id_);
882 } 959 }
883 960
884 success_ = success_ && 961 new_origin_usage_ = database_->GetOriginUsage(origin_);
885 database_->FindOriginsWithGroups(&origins_with_groups_) && 962 success_ = success_ && transaction.Commit();
886 transaction.Commit();
887 } 963 }
888 964
889 void AppCacheStorageImpl::MakeGroupObsoleteTask::RunCompleted() { 965 void AppCacheStorageImpl::MakeGroupObsoleteTask::RunCompleted() {
890 if (success_) { 966 if (success_) {
891 group_->set_obsolete(true); 967 group_->set_obsolete(true);
892 if (!storage_->is_disabled()) { 968 if (!storage_->is_disabled()) {
893 storage_->origins_with_groups_.swap(origins_with_groups_); 969 storage_->UpdateUsageMapAndNotify(origin_, new_origin_usage_);
894 group_->AddNewlyDeletableResponseIds(&newly_deletable_response_ids_); 970 group_->AddNewlyDeletableResponseIds(&newly_deletable_response_ids_);
895 971
896 // Also remove from the working set, caches for an 'obsolete' group 972 // Also remove from the working set, caches for an 'obsolete' group
897 // may linger in use, but the group itself cannot be looked up by 973 // may linger in use, but the group itself cannot be looked up by
898 // 'manifest_url' in the working set any longer. 974 // 'manifest_url' in the working set any longer.
899 storage_->working_set()->RemoveGroup(group_); 975 storage_->working_set()->RemoveGroup(group_);
900 } 976 }
901 } 977 }
902 FOR_EACH_DELEGATE(delegates_, OnGroupMadeObsolete(group_, success_)); 978 FOR_EACH_DELEGATE(delegates_, OnGroupMadeObsolete(group_, success_));
903 group_ = NULL; 979 group_ = NULL;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 void AppCacheStorageImpl::DeleteDeletableResponseIdsTask::Run() { 1039 void AppCacheStorageImpl::DeleteDeletableResponseIdsTask::Run() {
964 database_->DeleteDeletableResponseIds(response_ids_); 1040 database_->DeleteDeletableResponseIds(response_ids_);
965 } 1041 }
966 1042
967 // UpdateGroupLastAccessTimeTask ------- 1043 // UpdateGroupLastAccessTimeTask -------
968 1044
969 class AppCacheStorageImpl::UpdateGroupLastAccessTimeTask 1045 class AppCacheStorageImpl::UpdateGroupLastAccessTimeTask
970 : public DatabaseTask { 1046 : public DatabaseTask {
971 public: 1047 public:
972 UpdateGroupLastAccessTimeTask( 1048 UpdateGroupLastAccessTimeTask(
973 AppCacheStorageImpl* storage, int64 group_id, base::Time time) 1049 AppCacheStorageImpl* storage, AppCacheGroup* group, base::Time time)
974 : DatabaseTask(storage), group_id_(group_id), last_access_time_(time) {} 1050 : DatabaseTask(storage), group_id_(group->group_id()),
1051 last_access_time_(time) {
1052 storage->NotifyStorageAccessed(group->manifest_url().GetOrigin());
1053 }
975 1054
976 virtual void Run(); 1055 virtual void Run();
977 1056
978 int64 group_id_; 1057 int64 group_id_;
979 base::Time last_access_time_; 1058 base::Time last_access_time_;
980 }; 1059 };
981 1060
982 void AppCacheStorageImpl::UpdateGroupLastAccessTimeTask::Run() { 1061 void AppCacheStorageImpl::UpdateGroupLastAccessTimeTask::Run() {
983 database_->UpdateGroupLastAccessTime(group_id_, last_access_time_); 1062 database_->UpdateGroupLastAccessTime(group_id_, last_access_time_);
984 } 1063 }
(...skipping 10 matching lines...) Expand all
995 this, &AppCacheStorageImpl::OnDeletedOneResponse)), 1074 this, &AppCacheStorageImpl::OnDeletedOneResponse)),
996 ALLOW_THIS_IN_INITIALIZER_LIST(init_callback_( 1075 ALLOW_THIS_IN_INITIALIZER_LIST(init_callback_(
997 this, &AppCacheStorageImpl::OnDiskCacheInitialized)), 1076 this, &AppCacheStorageImpl::OnDiskCacheInitialized)),
998 database_(NULL), is_disabled_(false), 1077 database_(NULL), is_disabled_(false),
999 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 1078 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
1000 } 1079 }
1001 1080
1002 AppCacheStorageImpl::~AppCacheStorageImpl() { 1081 AppCacheStorageImpl::~AppCacheStorageImpl() {
1003 STLDeleteElements(&pending_simple_tasks_); 1082 STLDeleteElements(&pending_simple_tasks_);
1004 1083
1084 std::for_each(pending_quota_queries_.begin(),
1085 pending_quota_queries_.end(),
1086 std::mem_fun(&DatabaseTask::CancelCompletion));
1005 std::for_each(scheduled_database_tasks_.begin(), 1087 std::for_each(scheduled_database_tasks_.begin(),
1006 scheduled_database_tasks_.end(), 1088 scheduled_database_tasks_.end(),
1007 std::mem_fun(&DatabaseTask::CancelCompletion)); 1089 std::mem_fun(&DatabaseTask::CancelCompletion));
1008 1090
1009 if (database_) 1091 if (database_)
1010 AppCacheThread::DeleteSoon(AppCacheThread::db(), FROM_HERE, database_); 1092 AppCacheThread::DeleteSoon(AppCacheThread::db(), FROM_HERE, database_);
1011 } 1093 }
1012 1094
1013 void AppCacheStorageImpl::Initialize(const FilePath& cache_directory, 1095 void AppCacheStorageImpl::Initialize(const FilePath& cache_directory,
1014 base::MessageLoopProxy* cache_thread) { 1096 base::MessageLoopProxy* cache_thread) {
1015 cache_directory_ = cache_directory; 1097 cache_directory_ = cache_directory;
1016 cache_thread_ = cache_thread; 1098 cache_thread_ = cache_thread;
1017 is_incognito_ = cache_directory_.empty(); 1099 is_incognito_ = cache_directory_.empty();
1018 1100
1019 FilePath db_file_path; 1101 FilePath db_file_path;
1020 if (!is_incognito_) 1102 if (!is_incognito_)
1021 db_file_path = cache_directory_.Append(kAppCacheDatabaseName); 1103 db_file_path = cache_directory_.Append(kAppCacheDatabaseName);
1022 database_ = new AppCacheDatabase(db_file_path); 1104 database_ = new AppCacheDatabase(db_file_path);
1023 1105
1024 scoped_refptr<InitTask> task(new InitTask(this)); 1106 scoped_refptr<InitTask> task(new InitTask(this));
1025 task->Schedule(); 1107 task->Schedule();
1026 } 1108 }
1027 1109
1028 void AppCacheStorageImpl::Disable() { 1110 void AppCacheStorageImpl::Disable() {
1029 if (is_disabled_) 1111 if (is_disabled_)
1030 return; 1112 return;
1031 VLOG(1) << "Disabling appcache storage."; 1113 VLOG(1) << "Disabling appcache storage.";
1032 is_disabled_ = true; 1114 is_disabled_ = true;
1033 origins_with_groups_.clear(); 1115 ClearUsageMapAndNotify();
1034 working_set()->Disable(); 1116 working_set()->Disable();
1035 if (disk_cache_.get()) 1117 if (disk_cache_.get())
1036 disk_cache_->Disable(); 1118 disk_cache_->Disable();
1037 scoped_refptr<DisableDatabaseTask> task(new DisableDatabaseTask(this)); 1119 scoped_refptr<DisableDatabaseTask> task(new DisableDatabaseTask(this));
1038 task->Schedule(); 1120 task->Schedule();
1039 } 1121 }
1040 1122
1041 void AppCacheStorageImpl::GetAllInfo(Delegate* delegate) { 1123 void AppCacheStorageImpl::GetAllInfo(Delegate* delegate) {
1042 DCHECK(delegate); 1124 DCHECK(delegate);
1043 scoped_refptr<GetAllInfoTask> task(new GetAllInfoTask(this)); 1125 scoped_refptr<GetAllInfoTask> task(new GetAllInfoTask(this));
1044 task->AddDelegate(GetOrCreateDelegateReference(delegate)); 1126 task->AddDelegate(GetOrCreateDelegateReference(delegate));
1045 task->Schedule(); 1127 task->Schedule();
1046 } 1128 }
1047 1129
1048 void AppCacheStorageImpl::LoadCache(int64 id, Delegate* delegate) { 1130 void AppCacheStorageImpl::LoadCache(int64 id, Delegate* delegate) {
1049 DCHECK(delegate); 1131 DCHECK(delegate);
1050 if (is_disabled_) { 1132 if (is_disabled_) {
1051 delegate->OnCacheLoaded(NULL, id); 1133 delegate->OnCacheLoaded(NULL, id);
1052 return; 1134 return;
1053 } 1135 }
1054 1136
1055 AppCache* cache = working_set_.GetCache(id); 1137 AppCache* cache = working_set_.GetCache(id);
1056 if (cache) { 1138 if (cache) {
1057 delegate->OnCacheLoaded(cache, id); 1139 delegate->OnCacheLoaded(cache, id);
1058 if (cache->owning_group()) { 1140 if (cache->owning_group()) {
1059 scoped_refptr<DatabaseTask> update_task( 1141 scoped_refptr<DatabaseTask> update_task(
1060 new UpdateGroupLastAccessTimeTask( 1142 new UpdateGroupLastAccessTimeTask(
1061 this, cache->owning_group()->group_id(), base::Time::Now())); 1143 this, cache->owning_group(), base::Time::Now()));
1062 update_task->Schedule(); 1144 update_task->Schedule();
1063 } 1145 }
1064 return; 1146 return;
1065 } 1147 }
1066 scoped_refptr<CacheLoadTask> task(GetPendingCacheLoadTask(id)); 1148 scoped_refptr<CacheLoadTask> task(GetPendingCacheLoadTask(id));
1067 if (task) { 1149 if (task) {
1068 task->AddDelegate(GetOrCreateDelegateReference(delegate)); 1150 task->AddDelegate(GetOrCreateDelegateReference(delegate));
1069 return; 1151 return;
1070 } 1152 }
1071 task = new CacheLoadTask(id, this); 1153 task = new CacheLoadTask(id, this);
1072 task->AddDelegate(GetOrCreateDelegateReference(delegate)); 1154 task->AddDelegate(GetOrCreateDelegateReference(delegate));
1073 task->Schedule(); 1155 task->Schedule();
1074 pending_cache_loads_[id] = task; 1156 pending_cache_loads_[id] = task;
1075 } 1157 }
1076 1158
1077 void AppCacheStorageImpl::LoadOrCreateGroup( 1159 void AppCacheStorageImpl::LoadOrCreateGroup(
1078 const GURL& manifest_url, Delegate* delegate) { 1160 const GURL& manifest_url, Delegate* delegate) {
1079 DCHECK(delegate); 1161 DCHECK(delegate);
1080 if (is_disabled_) { 1162 if (is_disabled_) {
1081 delegate->OnGroupLoaded(NULL, manifest_url); 1163 delegate->OnGroupLoaded(NULL, manifest_url);
1082 return; 1164 return;
1083 } 1165 }
1084 1166
1085 AppCacheGroup* group = working_set_.GetGroup(manifest_url); 1167 AppCacheGroup* group = working_set_.GetGroup(manifest_url);
1086 if (group) { 1168 if (group) {
1087 delegate->OnGroupLoaded(group, manifest_url); 1169 delegate->OnGroupLoaded(group, manifest_url);
1088 scoped_refptr<DatabaseTask> update_task( 1170 scoped_refptr<DatabaseTask> update_task(
1089 new UpdateGroupLastAccessTimeTask( 1171 new UpdateGroupLastAccessTimeTask(
1090 this, group->group_id(), base::Time::Now())); 1172 this, group, base::Time::Now()));
1091 update_task->Schedule(); 1173 update_task->Schedule();
1092 return; 1174 return;
1093 } 1175 }
1094 1176
1095 scoped_refptr<GroupLoadTask> task(GetPendingGroupLoadTask(manifest_url)); 1177 scoped_refptr<GroupLoadTask> task(GetPendingGroupLoadTask(manifest_url));
1096 if (task) { 1178 if (task) {
1097 task->AddDelegate(GetOrCreateDelegateReference(delegate)); 1179 task->AddDelegate(GetOrCreateDelegateReference(delegate));
1098 return; 1180 return;
1099 } 1181 }
1100 1182
1101 if (origins_with_groups_.find(manifest_url.GetOrigin()) == 1183 if (usage_map_.find(manifest_url.GetOrigin()) == usage_map_.end()) {
1102 origins_with_groups_.end()) {
1103 // No need to query the database, return a new group immediately. 1184 // No need to query the database, return a new group immediately.
1104 scoped_refptr<AppCacheGroup> group(new AppCacheGroup( 1185 scoped_refptr<AppCacheGroup> group(new AppCacheGroup(
1105 service_, manifest_url, NewGroupId())); 1186 service_, manifest_url, NewGroupId()));
1106 delegate->OnGroupLoaded(group, manifest_url); 1187 delegate->OnGroupLoaded(group, manifest_url);
1107 return; 1188 return;
1108 } 1189 }
1109 1190
1110 task = new GroupLoadTask(manifest_url, this); 1191 task = new GroupLoadTask(manifest_url, this);
1111 task->AddDelegate(GetOrCreateDelegateReference(delegate)); 1192 task->AddDelegate(GetOrCreateDelegateReference(delegate));
1112 task->Schedule(); 1193 task->Schedule();
1113 pending_group_loads_[manifest_url] = task.get(); 1194 pending_group_loads_[manifest_url] = task.get();
1114 } 1195 }
1115 1196
1116 void AppCacheStorageImpl::StoreGroupAndNewestCache( 1197 void AppCacheStorageImpl::StoreGroupAndNewestCache(
1117 AppCacheGroup* group, AppCache* newest_cache, Delegate* delegate) { 1198 AppCacheGroup* group, AppCache* newest_cache, Delegate* delegate) {
1118 // TODO(michaeln): distinguish between a simple update of an existing 1199 // TODO(michaeln): distinguish between a simple update of an existing
1119 // cache that just adds new master entry(s), and the insertion of a 1200 // cache that just adds new master entry(s), and the insertion of a
1120 // whole new cache. The StoreGroupAndCacheTask as written will handle 1201 // whole new cache. The StoreGroupAndCacheTask as written will handle
1121 // the simple update case in a very heavy weight way (delete all and 1202 // the simple update case in a very heavy weight way (delete all and
1122 // the reinsert all over again). 1203 // the reinsert all over again).
1123 DCHECK(group && delegate && newest_cache); 1204 DCHECK(group && delegate && newest_cache);
1124 scoped_refptr<StoreGroupAndCacheTask> task( 1205 scoped_refptr<StoreGroupAndCacheTask> task(
1125 new StoreGroupAndCacheTask(this, group, newest_cache)); 1206 new StoreGroupAndCacheTask(this, group, newest_cache));
1126 task->AddDelegate(GetOrCreateDelegateReference(delegate)); 1207 task->AddDelegate(GetOrCreateDelegateReference(delegate));
1127 task->Schedule(); 1208 task->GetQuotaThenSchedule();
1128 } 1209 }
1129 1210
1130 void AppCacheStorageImpl::FindResponseForMainRequest( 1211 void AppCacheStorageImpl::FindResponseForMainRequest(
1131 const GURL& url, const GURL& preferred_manifest_url, 1212 const GURL& url, const GURL& preferred_manifest_url,
1132 Delegate* delegate) { 1213 Delegate* delegate) {
1133 DCHECK(delegate); 1214 DCHECK(delegate);
1134 1215
1135 const GURL* url_ptr = &url; 1216 const GURL* url_ptr = &url;
1136 GURL url_no_ref; 1217 GURL url_no_ref;
1137 if (url.has_ref()) { 1218 if (url.has_ref()) {
(...skipping 23 matching lines...) Expand all
1161 groups_in_use->begin(); 1242 groups_in_use->begin();
1162 it != groups_in_use->end(); ++it) { 1243 it != groups_in_use->end(); ++it) {
1163 if (FindResponseForMainRequestInGroup( 1244 if (FindResponseForMainRequestInGroup(
1164 it->second, *url_ptr, delegate)) { 1245 it->second, *url_ptr, delegate)) {
1165 return; 1246 return;
1166 } 1247 }
1167 } 1248 }
1168 } 1249 }
1169 } 1250 }
1170 1251
1171 if (IsInitTaskComplete() && 1252 if (IsInitTaskComplete() && usage_map_.find(origin) == usage_map_.end()) {
1172 origins_with_groups_.find(origin) == origins_with_groups_.end()) {
1173 // No need to query the database, return async'ly but without going thru 1253 // No need to query the database, return async'ly but without going thru
1174 // the DB thread. 1254 // the DB thread.
1175 scoped_refptr<AppCacheGroup> no_group; 1255 scoped_refptr<AppCacheGroup> no_group;
1176 scoped_refptr<AppCache> no_cache; 1256 scoped_refptr<AppCache> no_cache;
1177 ScheduleSimpleTask(method_factory_.NewRunnableMethod( 1257 ScheduleSimpleTask(method_factory_.NewRunnableMethod(
1178 &AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse, 1258 &AppCacheStorageImpl::DeliverShortCircuitedFindMainResponse,
1179 url, AppCacheEntry(), no_group, no_cache, 1259 url, AppCacheEntry(), no_group, no_cache,
1180 make_scoped_refptr(GetOrCreateDelegateReference(delegate)))); 1260 make_scoped_refptr(GetOrCreateDelegateReference(delegate))));
1181 return; 1261 return;
1182 } 1262 }
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 Disable(); 1569 Disable();
1490 if (!is_incognito_) { 1570 if (!is_incognito_) {
1491 VLOG(1) << "Deleting existing appcache data and starting over."; 1571 VLOG(1) << "Deleting existing appcache data and starting over.";
1492 AppCacheThread::PostTask(AppCacheThread::db(), FROM_HERE, 1572 AppCacheThread::PostTask(AppCacheThread::db(), FROM_HERE,
1493 NewRunnableFunction(DeleteDirectory, cache_directory_)); 1573 NewRunnableFunction(DeleteDirectory, cache_directory_));
1494 } 1574 }
1495 } 1575 }
1496 } 1576 }
1497 1577
1498 } // namespace appcache 1578 } // namespace appcache
OLDNEW
« no previous file with comments | « webkit/appcache/appcache_storage_impl.h ('k') | webkit/appcache/appcache_storage_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698