Chromium Code Reviews| Index: webkit/dom_storage/dom_storage_area.cc |
| diff --git a/webkit/dom_storage/dom_storage_area.cc b/webkit/dom_storage/dom_storage_area.cc |
| index ed4885b7b078f8e01f368fb944db7f066ff6a9df..e172ba8c1a3cf786703337bba53db1789284c8ea 100644 |
| --- a/webkit/dom_storage/dom_storage_area.cc |
| +++ b/webkit/dom_storage/dom_storage_area.cc |
| @@ -15,6 +15,7 @@ |
| #include "webkit/dom_storage/dom_storage_namespace.h" |
| #include "webkit/dom_storage/dom_storage_task_runner.h" |
| #include "webkit/dom_storage/dom_storage_types.h" |
| +#include "webkit/dom_storage/session_storage_database.h" |
| #include "webkit/fileapi/file_system_util.h" |
| #include "webkit/glue/webkit_glue.h" |
| @@ -59,13 +60,38 @@ DomStorageArea::DomStorageArea( |
| directory_(directory), |
| task_runner_(task_runner), |
| map_(new DomStorageMap(kPerAreaQuota)), |
| + is_initial_import_done_(false), |
| + is_shutdown_(false), |
| + is_shallow_copy_(false) { |
| + DCHECK(!directory.empty()); |
| + DCHECK_EQ(kLocalStorageNamespaceId, namespace_id); |
| + FilePath path = directory.Append(DatabaseFileNameFromOrigin(origin_)); |
| + backing_.reset(new LocalStorageDatabase(path)); |
| +} |
| + |
| +DomStorageArea::DomStorageArea( |
| + int64 namespace_id, const GURL& origin, |
| + SessionStorageDatabase* session_storage_backing, |
| + DomStorageTaskRunner* task_runner) |
| + : namespace_id_(namespace_id), origin_(origin), |
| + task_runner_(task_runner), |
| + map_(new DomStorageMap(kPerAreaQuota)), |
| + session_storage_backing_(session_storage_backing), |
| + is_initial_import_done_(false), |
| + is_shutdown_(false), |
| + is_shallow_copy_(false) { |
| + DCHECK(namespace_id != kLocalStorageNamespaceId); |
| +} |
| + |
| +DomStorageArea::DomStorageArea(int64 namespace_id, |
| + const GURL& origin, |
| + DomStorageTaskRunner* task_runner) |
| + : namespace_id_(namespace_id), origin_(origin), |
| + task_runner_(task_runner), |
| + map_(new DomStorageMap(kPerAreaQuota)), |
| is_initial_import_done_(true), |
| - is_shutdown_(false) { |
| - if (namespace_id == kLocalStorageNamespaceId && !directory.empty()) { |
| - FilePath path = directory.Append(DatabaseFileNameFromOrigin(origin_)); |
| - backing_.reset(new DomStorageDatabase(path)); |
| - is_initial_import_done_ = false; |
| - } |
| + is_shutdown_(false), |
| + is_shallow_copy_(false) { |
| } |
| DomStorageArea::~DomStorageArea() { |
| @@ -98,10 +124,15 @@ bool DomStorageArea::SetItem(const string16& key, |
| if (is_shutdown_) |
| return false; |
| InitialImportIfNeeded(); |
| - if (!map_->HasOneRef()) |
| + if (is_shallow_copy_) { |
| map_ = map_->DeepCopy(); |
| + if (session_storage_backing_.get()) { |
| + session_storage_backing_->DeepCopy(namespace_id_, origin_); |
|
michaeln
2012/04/12 01:48:46
see comments below about serializing deepcopy with
marja
2012/04/19 10:20:50
Done.
|
| + } |
| + is_shallow_copy_ = false; |
| + } |
| bool success = map_->SetItem(key, value, old_value); |
| - if (success && backing_.get()) { |
| + if (success && GetBacking()) { |
| CommitBatch* commit_batch = CreateCommitBatchIfNeeded(); |
| commit_batch->changed_values[key] = NullableString16(value, false); |
| } |
| @@ -112,10 +143,15 @@ bool DomStorageArea::RemoveItem(const string16& key, string16* old_value) { |
| if (is_shutdown_) |
| return false; |
| InitialImportIfNeeded(); |
| - if (!map_->HasOneRef()) |
| + if (is_shallow_copy_) { |
| map_ = map_->DeepCopy(); |
| + if (session_storage_backing_.get()) { |
| + session_storage_backing_->DeepCopy(namespace_id_, origin_); |
|
michaeln
2012/04/12 01:48:46
The changes to the backing store made by DeepCopy
marja
2012/04/19 10:20:50
Done. deep_copy_first doens't work, since the same
|
| + } |
| + is_shallow_copy_ = false; |
| + } |
| bool success = map_->RemoveItem(key, old_value); |
| - if (success && backing_.get()) { |
| + if (success && GetBacking()) { |
| CommitBatch* commit_batch = CreateCommitBatchIfNeeded(); |
| commit_batch->changed_values[key] = NullableString16(true); |
| } |
| @@ -131,7 +167,7 @@ bool DomStorageArea::Clear() { |
| map_ = new DomStorageMap(kPerAreaQuota); |
|
michaeln
2012/04/12 01:48:46
if this area is a 'shallow copy', we'll need to co
marja
2012/04/19 10:20:50
Done.
|
| - if (backing_.get()) { |
| + if (GetBacking()) { |
| CommitBatch* commit_batch = CreateCommitBatchIfNeeded(); |
| commit_batch->clear_all_first = true; |
| commit_batch->changed_values.clear(); |
| @@ -143,10 +179,15 @@ bool DomStorageArea::Clear() { |
| DomStorageArea* DomStorageArea::ShallowCopy(int64 destination_namespace_id) { |
| DCHECK_NE(kLocalStorageNamespaceId, namespace_id_); |
| DCHECK_NE(kLocalStorageNamespaceId, destination_namespace_id); |
| - DCHECK(!backing_.get()); // SessionNamespaces aren't stored on disk. |
| + DCHECK(session_storage_backing_.get()); |
| + |
| + session_storage_backing_->ShallowCopy(namespace_id_, origin_, |
|
michaeln
2012/04/12 01:48:46
see earlier comments about serializing changes in
marja
2012/04/19 10:20:50
Done.
|
| + destination_namespace_id); |
| - DomStorageArea* copy = new DomStorageArea(destination_namespace_id, origin_, |
| - FilePath(), task_runner_); |
| + DomStorageArea* copy = new DomStorageArea( |
| + destination_namespace_id, origin_, session_storage_backing_, |
| + task_runner_); |
| + copy->is_shallow_copy_ = true; |
| copy->map_ = map_; |
| copy->is_shutdown_ = is_shutdown_; |
| return copy; |
| @@ -171,10 +212,12 @@ void DomStorageArea::DeleteOrigin() { |
| map_ = new DomStorageMap(kPerAreaQuota); |
| if (backing_.get()) { |
| is_initial_import_done_ = false; |
| - backing_.reset(new DomStorageDatabase(backing_->file_path())); |
| + backing_.reset(new LocalStorageDatabase(backing_->file_path())); |
| file_util::Delete(backing_->file_path(), false); |
| file_util::Delete( |
| - DomStorageDatabase::GetJournalFilePath(backing_->file_path()), false); |
| + LocalStorageDatabase::GetJournalFilePath(backing_->file_path()), false); |
| + } else if (session_storage_backing_.get()) { |
| + session_storage_backing_->DeleteOrigin(namespace_id_, origin_); |
|
michaeln
2012/04/12 01:48:46
probably needs to be serialized on the COMMIT_SEQU
marja
2012/04/19 10:20:50
Done.
|
| } |
| } |
| @@ -191,14 +234,14 @@ void DomStorageArea::PurgeMemory() { |
| // Recreate the database object, this frees up the open sqlite connection |
| // and its page cache. |
| - backing_.reset(new DomStorageDatabase(backing_->file_path())); |
| + backing_.reset(new LocalStorageDatabase(backing_->file_path())); |
| } |
| void DomStorageArea::Shutdown() { |
| DCHECK(!is_shutdown_); |
| is_shutdown_ = true; |
| map_ = NULL; |
| - if (!backing_.get()) |
| + if (!GetBacking()) |
| return; |
| bool success = task_runner_->PostShutdownBlockingTask( |
| @@ -212,11 +255,10 @@ void DomStorageArea::InitialImportIfNeeded() { |
| if (is_initial_import_done_) |
| return; |
| - DCHECK_EQ(kLocalStorageNamespaceId, namespace_id_); |
| - DCHECK(backing_.get()); |
| + DCHECK(GetBacking()); |
| ValuesMap initial_values; |
| - backing_->ReadAllValues(&initial_values); |
| + GetBacking()->ReadAllValues(namespace_id_, origin_, &initial_values); |
| map_->SwapValues(&initial_values); |
| is_initial_import_done_ = true; |
| } |
| @@ -240,11 +282,10 @@ DomStorageArea::CommitBatch* DomStorageArea::CreateCommitBatchIfNeeded() { |
| } |
| void DomStorageArea::OnCommitTimer() { |
| - DCHECK_EQ(kLocalStorageNamespaceId, namespace_id_); |
| if (is_shutdown_) |
| return; |
| - DCHECK(backing_.get()); |
| + DCHECK(GetBacking()); |
| DCHECK(commit_batch_.get()); |
| DCHECK(!in_flight_commit_batch_.get()); |
| @@ -263,7 +304,8 @@ void DomStorageArea::CommitChanges() { |
| // This method executes on the commit sequence. |
| DCHECK(task_runner_->IsRunningOnCommitSequence()); |
| DCHECK(in_flight_commit_batch_.get()); |
| - bool success = backing_->CommitChanges( |
| + bool success = GetBacking()->CommitChanges( |
| + namespace_id_, origin_, |
| in_flight_commit_batch_->clear_all_first, |
| in_flight_commit_batch_->changed_values); |
| DCHECK(success); // TODO(michaeln): what if it fails? |
| @@ -290,10 +332,11 @@ void DomStorageArea::OnCommitComplete() { |
| void DomStorageArea::ShutdownInCommitSequence() { |
| // This method executes on the commit sequence. |
| DCHECK(task_runner_->IsRunningOnCommitSequence()); |
| - DCHECK(backing_.get()); |
| + DCHECK(GetBacking()); |
| if (commit_batch_.get()) { |
| // Commit any changes that accrued prior to the timer firing. |
| - bool success = backing_->CommitChanges( |
| + bool success = GetBacking()->CommitChanges( |
| + namespace_id_, origin_, |
| commit_batch_->clear_all_first, |
| commit_batch_->changed_values); |
| DCHECK(success); |
| @@ -301,6 +344,14 @@ void DomStorageArea::ShutdownInCommitSequence() { |
| commit_batch_.reset(); |
| in_flight_commit_batch_.reset(); |
| backing_.reset(); |
| + session_storage_backing_ = NULL; |
| +} |
| + |
| +DomStorageDatabase* DomStorageArea::GetBacking() const { |
| + DCHECK(!backing_.get() || !session_storage_backing_.get()); |
| + if (backing_.get()) |
| + return backing_.get(); |
| + return session_storage_backing_.get(); |
| } |
| } // namespace dom_storage |