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

Unified Diff: content/browser/in_process_webkit/indexed_db_context.cc

Issue 7470008: Improve IndexedDB's quota support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: improve names and comments, better map cleanup Created 9 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/in_process_webkit/indexed_db_context.cc
diff --git a/content/browser/in_process_webkit/indexed_db_context.cc b/content/browser/in_process_webkit/indexed_db_context.cc
index 8e091c1678572dca7c3192b74addfff3e3a338cf..cac2ee20f385115c347f4fcbefba901be0e98f98 100644
--- a/content/browser/in_process_webkit/indexed_db_context.cc
+++ b/content/browser/in_process_webkit/indexed_db_context.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/message_loop_proxy.h"
#include "base/string_util.h"
+#include "base/task.h"
#include "base/utf_string_conversions.h"
#include "content/browser/browser_thread.h"
#include "content/browser/in_process_webkit/indexed_db_quota_client.h"
@@ -18,10 +19,12 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebIDBFactory.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
+#include "webkit/database/database_util.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/quota/quota_manager.h"
#include "webkit/quota/special_storage_policy.h"
+using webkit_database::DatabaseUtil;
using WebKit::WebIDBDatabase;
using WebKit::WebIDBFactory;
using WebKit::WebSecurityOrigin;
@@ -103,7 +106,7 @@ FilePath IndexedDBContext::GetIndexedDBFilePath(
void IndexedDBContext::DeleteIndexedDBFile(const FilePath& file_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
// TODO(pastarmovj): Close all database connections that use that file.
- file_util::Delete(file_path, false);
+ file_util::Delete(file_path, true /*recursive*/);
}
void IndexedDBContext::DeleteIndexedDBForOrigin(const string16& origin_id) {
@@ -115,6 +118,17 @@ void IndexedDBContext::DeleteIndexedDBForOrigin(const string16& origin_id) {
DeleteIndexedDBFile(GetIndexedDBFilePath(origin_id));
}
+// TODO(dgrogan): Once we can delete IndexedDB directories out from underneath
+// open webkit instances, merge this and DeleteIndexedDBForOrigin.
+void IndexedDBContext::EvictOriginIfNotInUse(const GURL& origin_url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ if (connection_count_.find(origin_url) == connection_count_.end()) {
+ string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
+ FilePath idb_directory = GetIndexedDBFilePath(origin_id);
+ DeleteIndexedDBFile(idb_directory);
+ }
+}
+
bool IndexedDBContext::IsUnlimitedStorageGranted(
const GURL& origin) const {
return special_storage_policy_->IsStorageUnlimited(origin);
@@ -137,6 +151,148 @@ void IndexedDBContext::GetAllOriginIdentifiers(
}
}
+int64 IndexedDBContext::InitializeDiskUsage(const GURL& origin_url) {
+ int64 disk_usage = ReadUsageFromDisk(origin_url);
+ origin_size_map_[origin_url] = disk_usage;
+ return disk_usage;
+}
+
+int64 IndexedDBContext::ReadUsageFromDisk(const GURL& origin_url) const {
+ string16 origin_id = DatabaseUtil::GetOriginIdentifier(origin_url);
+ FilePath file_path = GetIndexedDBFilePath(origin_id);
+ return file_util::ComputeDirectorySize(file_path);
+}
+
+void IndexedDBContext::ConnectionClosed(const GURL& origin_url) {
+ if (quota_manager_proxy()) {
+ quota_manager_proxy()->NotifyStorageAccessed(
+ quota::QuotaClient::kIndexedDatabase, origin_url,
+ quota::kStorageTypeTemporary);
+ }
+ connection_count_[origin_url] --;
+ if (connection_count_[origin_url] == 0) {
+ QueryDiskAndUpdateQuotaUsage(origin_url);
+ connection_count_.erase(origin_url);
+ }
+}
+
+void IndexedDBContext::NewConnection(const GURL& origin_url) {
+ if (quota_manager_proxy()) {
+ quota_manager_proxy()->NotifyStorageAccessed(
+ quota::QuotaClient::kIndexedDatabase, origin_url,
+ quota::kStorageTypeTemporary);
+ }
+ connection_count_[origin_url] ++;
+ QueryAvailableQuota(origin_url);
+}
+
+bool IndexedDBContext::WouldBeOverQuota(const GURL& origin_url,
+ int64 additional_bytes) {
+ if (origin_allocated_quota_map_.find(origin_url) ==
+ origin_allocated_quota_map_.end()) {
+ // We haven't heard back from the QuotaManager yet, just let it through.
+ return false;
+ }
+ bool over_quota = additional_bytes + origin_size_map_[origin_url] >
+ origin_allocated_quota_map_[origin_url];
+ return over_quota;
+}
+
+bool IndexedDBContext::IsOverQuota(const GURL& origin_url) {
+ return WouldBeOverQuota(origin_url, 0 /*additional_bytes*/);
+}
+
+void IndexedDBContext::TransactionComplete(const GURL& origin_url) {
+ QueryDiskAndUpdateQuotaUsage(origin_url);
+ QueryAvailableQuota(origin_url);
+}
+
+void IndexedDBContext::QueryDiskAndUpdateQuotaUsage(const GURL& origin_url) {
+ int64 former_disk_usage = origin_size_map_[origin_url];
+ int64 current_disk_usage = ReadUsageFromDisk(origin_url);
+ int64 difference = current_disk_usage - former_disk_usage;
+ if (difference) {
+ quota_manager_proxy()->NotifyStorageModified(
+ quota::QuotaClient::kIndexedDatabase,
+ origin_url,
+ quota::kStorageTypeTemporary,
+ difference);
+ origin_size_map_[origin_url] = current_disk_usage;
+ }
+}
+
+void IndexedDBContext::GotUpdatedQuota(const GURL& origin_url, int64 usage,
+ int64 quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+ origin_allocated_quota_map_[origin_url] = quota;
+}
+
+void GotUpdatedQuota(IndexedDBContext* context, const GURL& origin_url,
+ int64 usage, int64 quota) {
+ context->GotUpdatedQuota(origin_url, usage, quota);
+}
+
+class IndexedDBGetUsageAndQuotaCallback :
+ public quota::QuotaManager::GetUsageAndQuotaCallback {
+ public:
+ IndexedDBGetUsageAndQuotaCallback(IndexedDBContext* context,
+ const GURL& origin_url)
+ : context_(context),
+ origin_url_(origin_url) {
+ }
+
+ void Run(quota::QuotaStatusCode status, int64 usage, int64 quota) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(status == quota::kQuotaStatusOk || status == quota::kQuotaErrorAbort)
+ << "status was " << status;
+ if (status == quota::kQuotaErrorAbort) {
+ // We seem to no longer care to wait around for the answer.
+ return;
+ }
+ BrowserThread::PostTask(BrowserThread::WEBKIT, FROM_HERE,
+ NewRunnableFunction(&GotUpdatedQuota,
+ context_,
+ origin_url_,
+ usage,
+ quota));
+ }
+
+ virtual void RunWithParams(
+ const Tuple3<quota::QuotaStatusCode, int64, int64>& params) {
+ Run(params.a, params.b, params.c);
+ }
+
+ private:
+ scoped_refptr<IndexedDBContext> context_;
+ const GURL origin_url_;
+};
+
+void RequestQuota(
+ scoped_refptr<quota::QuotaManagerProxy> proxy, const GURL& gurl,
+ IndexedDBGetUsageAndQuotaCallback* idb_quota_callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (!proxy->quota_manager()) {
+ // QuotaManager was deleted on the IO thread just before this RequestQuota
+ // task was run.
+ return;
+ }
+ proxy->quota_manager()->GetUsageAndQuota(
+ gurl,
+ quota::kStorageTypeTemporary,
+ idb_quota_callback);
+}
+
+void IndexedDBContext::QueryAvailableQuota(const GURL& origin_url) {
+ IndexedDBGetUsageAndQuotaCallback* callback =
+ new IndexedDBGetUsageAndQuotaCallback(this, origin_url);
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ NewRunnableFunction(&RequestQuota,
kinuko 2011/08/03 09:12:22 Could this be implemented using NewRunnableMethod?
dgrogan 2011/08/03 21:45:47 Either using NewRunnableMethod won't really work h
+ scoped_refptr<quota::QuotaManagerProxy>(
kinuko 2011/08/03 09:12:22 I guess you could use make_scoped_refptr() ?
dgrogan 2011/08/03 21:45:47 Ah, thanks. Didn't know about that.
+ quota_manager_proxy()),
+ origin_url,
+ callback));
+}
+
quota::QuotaManagerProxy* IndexedDBContext::quota_manager_proxy() {
return quota_manager_proxy_;
}

Powered by Google App Engine
This is Rietveld 408576698