diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-04 06:48:46 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-04 06:48:46 +0000 |
commit | a623aae4e88566e21092dfe6671dcd92fc9d3f26 (patch) | |
tree | acbef921ffe550ba785832b5722b12382c3068db /webkit | |
parent | d33f9e88470477c4d86b0302773171e3151d7f64 (diff) | |
download | chromium_src-a623aae4e88566e21092dfe6671dcd92fc9d3f26.zip chromium_src-a623aae4e88566e21092dfe6671dcd92fc9d3f26.tar.gz chromium_src-a623aae4e88566e21092dfe6671dcd92fc9d3f26.tar.bz2 |
Prepopulate directory database for isolated origins
This reduces end-to-end OpenFileSystem + CreateFile cost
by ~100ms (measured in JS layer) for packaged apps.
BUG=242272
R=tzik@chromium.org
Review URL: https://codereview.chromium.org/15724009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203877 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
6 files changed, 72 insertions, 13 deletions
diff --git a/webkit/browser/fileapi/obfuscated_file_util.cc b/webkit/browser/fileapi/obfuscated_file_util.cc index f976985..00662f7 100644 --- a/webkit/browser/fileapi/obfuscated_file_util.cc +++ b/webkit/browser/fileapi/obfuscated_file_util.cc @@ -991,6 +991,36 @@ int64 ObfuscatedFileUtil::ComputeFilePathCost(const base::FilePath& path) { return UsageForPath(VirtualPath::BaseName(path).value().size()); } +void ObfuscatedFileUtil::MaybePrepopulateDatabase() { + base::FilePath isolated_origin_dir = file_system_directory_.Append( + SandboxIsolatedOriginDatabase::kOriginDirectory); + if (!file_util::DirectoryExists(isolated_origin_dir)) + return; + + const FileSystemType kPrepopulateTypes[] = { + kFileSystemTypePersistent, kFileSystemTypeTemporary + }; + + // Prepulate the directory database(s) if and only if this instance is + // initialized for isolated storage dedicated for a single origin. + for (size_t i = 0; i < arraysize(kPrepopulateTypes); ++i) { + const FileSystemType type = kPrepopulateTypes[i]; + base::FilePath::StringType type_string = GetDirectoryNameForType(type); + DCHECK(!type_string.empty()); + base::FilePath path = isolated_origin_dir.Append(type_string); + if (!file_util::DirectoryExists(path)) + continue; + scoped_ptr<SandboxDirectoryDatabase> db(new SandboxDirectoryDatabase(path)); + if (db->Init(SandboxDirectoryDatabase::FAIL_ON_CORRUPTION)) { + directories_[GetFileSystemTypeString(type)] = db.release(); + MarkUsed(); + // Don't populate more than one database, as it may rather hurt + // performance. + break; + } + } +} + PlatformFileError ObfuscatedFileUtil::GetFileInfoInternal( SandboxDirectoryDatabase* db, FileSystemOperationContext* context, @@ -1132,20 +1162,32 @@ base::FilePath ObfuscatedFileUtil::DataPathToLocalPath( return root.Append(data_path); } +std::string ObfuscatedFileUtil::GetDirectoryDatabaseKey( + const GURL& origin, FileSystemType type) { + std::string type_string = GetFileSystemTypeString(type); + if (type_string.empty()) { + LOG(WARNING) << "Unknown filesystem type requested:" << type; + return std::string(); + } + // For isolated origin we just use a type string as a key. + if (special_storage_policy_ && + special_storage_policy_->HasIsolatedStorage(origin)) { + return type_string; + } + return UTF16ToUTF8(webkit_base::GetOriginIdentifierFromURL(origin)) + + type_string; +} + // TODO(ericu): How to do the whole validation-without-creation thing? // We may not have quota even to create the database. // Ah, in that case don't even get here? // Still doesn't answer the quota issue, though. SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( const GURL& origin, FileSystemType type, bool create) { - std::string type_string = GetFileSystemTypeString(type); - if (type_string.empty()) { - LOG(WARNING) << "Unknown filesystem type requested:" << type; + std::string key = GetDirectoryDatabaseKey(origin, type); + if (key.empty()) return NULL; - } - std::string key = - UTF16ToUTF8(webkit_base::GetOriginIdentifierFromURL(origin)) + - type_string; + DirectoryMap::iterator iter = directories_.find(key); if (iter != directories_.end()) { MarkUsed(); @@ -1169,10 +1211,10 @@ base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( const GURL& origin, bool create, base::PlatformFileError* error_code) { if (special_storage_policy_.get() && special_storage_policy_->HasIsolatedStorage(origin)) { - CHECK(isolated_origin_.is_empty() || isolated_origin_ == origin) - << "multiple origins for an isolated site: " - << isolated_origin_.spec() << " vs " << origin.spec(); - isolated_origin_ = origin; + if (isolated_origin_.is_empty()) + isolated_origin_ = origin; + CHECK_EQ(isolated_origin_.spec(), origin.spec()) + << "multiple origins for an isolated site"; } if (!InitOriginDatabase(create)) { diff --git a/webkit/browser/fileapi/obfuscated_file_util.h b/webkit/browser/fileapi/obfuscated_file_util.h index 651bc21..7cd5c59 100644 --- a/webkit/browser/fileapi/obfuscated_file_util.h +++ b/webkit/browser/fileapi/obfuscated_file_util.h @@ -176,6 +176,8 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE ObfuscatedFileUtil // on each path segment and add the results. static int64 ComputeFilePathCost(const base::FilePath& path); + void MaybePrepopulateDatabase(); + private: typedef SandboxDirectoryDatabase::FileId FileId; typedef SandboxDirectoryDatabase::FileInfo FileInfo; @@ -220,6 +222,8 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE ObfuscatedFileUtil FileSystemType type, const base::FilePath& data_file_path); + std::string GetDirectoryDatabaseKey(const GURL& origin, FileSystemType type); + // This returns NULL if |create| flag is false and a filesystem does not // exist for the given |origin_url| and |type|. // For read operations |create| should be false. @@ -261,7 +265,7 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE ObfuscatedFileUtil base::FilePath file_system_directory_; base::OneShotTimer<ObfuscatedFileUtil> timer_; - // If this instance is initialized for an isolated origin, this should + // If this instance is initialized for an isolated partition, this should // only see a single origin. GURL isolated_origin_; diff --git a/webkit/browser/fileapi/sandbox_directory_database.h b/webkit/browser/fileapi/sandbox_directory_database.h index c16c90d..a15ec17 100644 --- a/webkit/browser/fileapi/sandbox_directory_database.h +++ b/webkit/browser/fileapi/sandbox_directory_database.h @@ -99,6 +99,7 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE SandboxDirectoryDatabase { FAIL_ON_CORRUPTION, }; + friend class ObfuscatedFileUtil; friend class SandboxDirectoryDatabaseTest; bool Init(RecoveryOption recovery_option); diff --git a/webkit/browser/fileapi/sandbox_isolated_origin_database.cc b/webkit/browser/fileapi/sandbox_isolated_origin_database.cc index 17b365d..f382cf4 100644 --- a/webkit/browser/fileapi/sandbox_isolated_origin_database.cc +++ b/webkit/browser/fileapi/sandbox_isolated_origin_database.cc @@ -11,7 +11,8 @@ namespace fileapi { // Special directory name for isolated origin. -const base::FilePath::CharType kOriginDirectory[] = FILE_PATH_LITERAL("iso"); +const base::FilePath::CharType +SandboxIsolatedOriginDatabase::kOriginDirectory[] = FILE_PATH_LITERAL("iso"); SandboxIsolatedOriginDatabase::SandboxIsolatedOriginDatabase( const std::string& origin, diff --git a/webkit/browser/fileapi/sandbox_isolated_origin_database.h b/webkit/browser/fileapi/sandbox_isolated_origin_database.h index c3d54d5..72bff72 100644 --- a/webkit/browser/fileapi/sandbox_isolated_origin_database.h +++ b/webkit/browser/fileapi/sandbox_isolated_origin_database.h @@ -12,6 +12,8 @@ namespace fileapi { class WEBKIT_STORAGE_EXPORT_PRIVATE SandboxIsolatedOriginDatabase : public SandboxOriginDatabaseInterface { public: + static const base::FilePath::CharType kOriginDirectory[]; + explicit SandboxIsolatedOriginDatabase( const std::string& origin, const base::FilePath& file_system_directory); diff --git a/webkit/browser/fileapi/sandbox_mount_point_provider.cc b/webkit/browser/fileapi/sandbox_mount_point_provider.cc index 5beefc6..3f3afaa 100644 --- a/webkit/browser/fileapi/sandbox_mount_point_provider.cc +++ b/webkit/browser/fileapi/sandbox_mount_point_provider.cc @@ -179,6 +179,15 @@ SandboxMountPointProvider::SandboxMountPointProvider( update_observers_ = UpdateObserverList(update_observers_src); access_observers_ = AccessObserverList(access_observers_src); syncable_update_observers_ = UpdateObserverList(update_observers_src); + + if (!file_task_runner_->RunsTasksOnCurrentThread()) { + // Post prepopulate task only if it's not already running on + // file_task_runner (which implies running in tests). + file_task_runner_->PostTask( + FROM_HERE, + base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase, + base::Unretained(sandbox_sync_file_util()))); + } } SandboxMountPointProvider::~SandboxMountPointProvider() { |