blob: 75bfdaacb71bcee82a6a52b89f0940a58c207198 [file] [log] [blame]
Ben Murdochbb1529c2013-08-08 10:24:53 +01001// Copyright 2013 The Chromium Authors. All rights reserved.
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Murdochbb1529c2013-08-08 10:24:53 +01005#include "content/browser/dom_storage/dom_storage_namespace.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01006
7#include "base/basictypes.h"
8#include "base/bind.h"
9#include "base/location.h"
10#include "base/logging.h"
Ben Murdochbb1529c2013-08-08 10:24:53 +010011#include "content/browser/dom_storage/dom_storage_area.h"
12#include "content/browser/dom_storage/dom_storage_task_runner.h"
13#include "content/browser/dom_storage/session_storage_database.h"
14#include "content/common/dom_storage/dom_storage_types.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010015
Ben Murdochbb1529c2013-08-08 10:24:53 +010016namespace content {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010017
Ben Murdochbb1529c2013-08-08 10:24:53 +010018DOMStorageNamespace::DOMStorageNamespace(
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010019 const base::FilePath& directory,
Ben Murdochbb1529c2013-08-08 10:24:53 +010020 DOMStorageTaskRunner* task_runner)
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010021 : namespace_id_(kLocalStorageNamespaceId),
22 directory_(directory),
23 task_runner_(task_runner) {
24}
25
Ben Murdochbb1529c2013-08-08 10:24:53 +010026DOMStorageNamespace::DOMStorageNamespace(
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010027 int64 namespace_id,
28 const std::string& persistent_namespace_id,
29 SessionStorageDatabase* session_storage_database,
Ben Murdochbb1529c2013-08-08 10:24:53 +010030 DOMStorageTaskRunner* task_runner)
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010031 : namespace_id_(namespace_id),
32 persistent_namespace_id_(persistent_namespace_id),
33 task_runner_(task_runner),
34 session_storage_database_(session_storage_database) {
35 DCHECK_NE(kLocalStorageNamespaceId, namespace_id);
36}
37
Ben Murdochbb1529c2013-08-08 10:24:53 +010038DOMStorageNamespace::~DOMStorageNamespace() {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010039}
40
Ben Murdochbb1529c2013-08-08 10:24:53 +010041DOMStorageArea* DOMStorageNamespace::OpenStorageArea(const GURL& origin) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010042 if (AreaHolder* holder = GetAreaHolder(origin)) {
43 ++(holder->open_count_);
44 return holder->area_.get();
45 }
Ben Murdochbb1529c2013-08-08 10:24:53 +010046 DOMStorageArea* area;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010047 if (namespace_id_ == kLocalStorageNamespaceId) {
Ben Murdochbb1529c2013-08-08 10:24:53 +010048 area = new DOMStorageArea(origin, directory_, task_runner_.get());
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010049 } else {
Ben Murdochbb1529c2013-08-08 10:24:53 +010050 area = new DOMStorageArea(
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010051 namespace_id_, persistent_namespace_id_, origin,
52 session_storage_database_.get(), task_runner_.get());
53 }
54 areas_[origin] = AreaHolder(area, 1);
55 return area;
56}
57
Ben Murdochbb1529c2013-08-08 10:24:53 +010058void DOMStorageNamespace::CloseStorageArea(DOMStorageArea* area) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010059 AreaHolder* holder = GetAreaHolder(area->origin());
60 DCHECK(holder);
61 DCHECK_EQ(holder->area_.get(), area);
62 --(holder->open_count_);
63 // TODO(michaeln): Clean up areas that aren't needed in memory anymore.
64 // The in-process-webkit based impl didn't do this either, but would be nice.
65}
66
Ben Murdochbb1529c2013-08-08 10:24:53 +010067DOMStorageArea* DOMStorageNamespace::GetOpenStorageArea(const GURL& origin) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010068 AreaHolder* holder = GetAreaHolder(origin);
69 if (holder && holder->open_count_)
70 return holder->area_.get();
71 return NULL;
72}
73
Ben Murdochbb1529c2013-08-08 10:24:53 +010074DOMStorageNamespace* DOMStorageNamespace::Clone(
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010075 int64 clone_namespace_id,
76 const std::string& clone_persistent_namespace_id) {
77 DCHECK_NE(kLocalStorageNamespaceId, namespace_id_);
78 DCHECK_NE(kLocalStorageNamespaceId, clone_namespace_id);
Ben Murdochbb1529c2013-08-08 10:24:53 +010079 DOMStorageNamespace* clone = new DOMStorageNamespace(
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010080 clone_namespace_id, clone_persistent_namespace_id,
81 session_storage_database_.get(), task_runner_.get());
82 AreaMap::const_iterator it = areas_.begin();
83 // Clone the in-memory structures.
84 for (; it != areas_.end(); ++it) {
Ben Murdochbb1529c2013-08-08 10:24:53 +010085 DOMStorageArea* area = it->second.area_->ShallowCopy(
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010086 clone_namespace_id, clone_persistent_namespace_id);
87 clone->areas_[it->first] = AreaHolder(area, 0);
88 }
89 // And clone the on-disk structures, too.
90 if (session_storage_database_.get()) {
91 task_runner_->PostShutdownBlockingTask(
92 FROM_HERE,
Ben Murdochbb1529c2013-08-08 10:24:53 +010093 DOMStorageTaskRunner::COMMIT_SEQUENCE,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010094 base::Bind(base::IgnoreResult(&SessionStorageDatabase::CloneNamespace),
95 session_storage_database_.get(), persistent_namespace_id_,
96 clone_persistent_namespace_id));
97 }
98 return clone;
99}
100
Ben Murdochbb1529c2013-08-08 10:24:53 +0100101void DOMStorageNamespace::DeleteLocalStorageOrigin(const GURL& origin) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100102 DCHECK(!session_storage_database_.get());
103 AreaHolder* holder = GetAreaHolder(origin);
104 if (holder) {
105 holder->area_->DeleteOrigin();
106 return;
107 }
108 if (!directory_.empty()) {
Ben Murdochbb1529c2013-08-08 10:24:53 +0100109 scoped_refptr<DOMStorageArea> area =
110 new DOMStorageArea(origin, directory_, task_runner_.get());
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100111 area->DeleteOrigin();
112 }
113}
114
Ben Murdochbb1529c2013-08-08 10:24:53 +0100115void DOMStorageNamespace::DeleteSessionStorageOrigin(const GURL& origin) {
116 DOMStorageArea* area = OpenStorageArea(origin);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100117 area->FastClear();
118 CloseStorageArea(area);
119}
120
Ben Murdochbb1529c2013-08-08 10:24:53 +0100121void DOMStorageNamespace::PurgeMemory(PurgeOption option) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100122 if (directory_.empty())
123 return; // We can't purge w/o backing on disk.
124 AreaMap::iterator it = areas_.begin();
125 while (it != areas_.end()) {
126 // Leave it alone if changes are pending
127 if (it->second.area_->HasUncommittedChanges()) {
128 ++it;
129 continue;
130 }
131
132 // If not in use, we can shut it down and remove
133 // it from our collection entirely.
134 if (it->second.open_count_ == 0) {
135 it->second.area_->Shutdown();
136 areas_.erase(it++);
137 continue;
138 }
139
140 if (option == PURGE_AGGRESSIVE) {
141 // If aggressive is true, we clear caches and such
142 // for opened areas.
143 it->second.area_->PurgeMemory();
144 }
145
146 ++it;
147 }
148}
149
Ben Murdochbb1529c2013-08-08 10:24:53 +0100150void DOMStorageNamespace::Shutdown() {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100151 AreaMap::const_iterator it = areas_.begin();
152 for (; it != areas_.end(); ++it)
153 it->second.area_->Shutdown();
154}
155
Ben Murdochbb1529c2013-08-08 10:24:53 +0100156unsigned int DOMStorageNamespace::CountInMemoryAreas() const {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100157 unsigned int area_count = 0;
158 for (AreaMap::const_iterator it = areas_.begin(); it != areas_.end(); ++it) {
159 if (it->second.area_->IsLoadedInMemory())
160 ++area_count;
161 }
162 return area_count;
163}
164
Ben Murdochbb1529c2013-08-08 10:24:53 +0100165DOMStorageNamespace::AreaHolder*
166DOMStorageNamespace::GetAreaHolder(const GURL& origin) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100167 AreaMap::iterator found = areas_.find(origin);
168 if (found == areas_.end())
169 return NULL;
170 return &(found->second);
171}
172
173// AreaHolder
174
Ben Murdochbb1529c2013-08-08 10:24:53 +0100175DOMStorageNamespace::AreaHolder::AreaHolder()
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100176 : open_count_(0) {
177}
178
Ben Murdochbb1529c2013-08-08 10:24:53 +0100179DOMStorageNamespace::AreaHolder::AreaHolder(
180 DOMStorageArea* area, int count)
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100181 : area_(area), open_count_(count) {
182}
183
Ben Murdochbb1529c2013-08-08 10:24:53 +0100184DOMStorageNamespace::AreaHolder::~AreaHolder() {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100185}
186
Ben Murdochbb1529c2013-08-08 10:24:53 +0100187} // namespace content