Add ICU message format support
[chromium-blink-merge.git] / content / browser / dom_storage / dom_storage_namespace.cc
blobf554ac58814260442a14cdf3bd90b140ba786511
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/dom_storage/dom_storage_namespace.h"
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #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"
16 namespace content {
18 DOMStorageNamespace::DOMStorageNamespace(
19 const base::FilePath& directory,
20 DOMStorageTaskRunner* task_runner)
21 : namespace_id_(kLocalStorageNamespaceId),
22 directory_(directory),
23 task_runner_(task_runner) {
26 DOMStorageNamespace::DOMStorageNamespace(
27 int64 namespace_id,
28 const std::string& persistent_namespace_id,
29 SessionStorageDatabase* session_storage_database,
30 DOMStorageTaskRunner* task_runner)
31 : 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);
38 DOMStorageNamespace::~DOMStorageNamespace() {
41 DOMStorageArea* DOMStorageNamespace::OpenStorageArea(const GURL& origin) {
42 if (AreaHolder* holder = GetAreaHolder(origin)) {
43 ++(holder->open_count_);
44 return holder->area_.get();
46 DOMStorageArea* area;
47 if (namespace_id_ == kLocalStorageNamespaceId) {
48 area = new DOMStorageArea(origin, directory_, task_runner_.get());
49 } else {
50 area = new DOMStorageArea(
51 namespace_id_, persistent_namespace_id_, origin,
52 session_storage_database_.get(), task_runner_.get());
54 areas_[origin] = AreaHolder(area, 1);
55 return area;
58 void DOMStorageNamespace::CloseStorageArea(DOMStorageArea* area) {
59 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.
67 DOMStorageArea* DOMStorageNamespace::GetOpenStorageArea(const GURL& origin) {
68 AreaHolder* holder = GetAreaHolder(origin);
69 if (holder && holder->open_count_)
70 return holder->area_.get();
71 return NULL;
74 DOMStorageNamespace* DOMStorageNamespace::Clone(
75 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);
79 DOMStorageNamespace* clone = new DOMStorageNamespace(
80 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) {
85 DOMStorageArea* area = it->second.area_->ShallowCopy(
86 clone_namespace_id, clone_persistent_namespace_id);
87 clone->areas_[it->first] = AreaHolder(area, 0);
89 // And clone the on-disk structures, too.
90 if (session_storage_database_.get()) {
91 task_runner_->PostShutdownBlockingTask(
92 FROM_HERE,
93 DOMStorageTaskRunner::COMMIT_SEQUENCE,
94 base::Bind(base::IgnoreResult(&SessionStorageDatabase::CloneNamespace),
95 session_storage_database_.get(), persistent_namespace_id_,
96 clone_persistent_namespace_id));
98 return clone;
101 void DOMStorageNamespace::DeleteLocalStorageOrigin(const GURL& origin) {
102 DCHECK(!session_storage_database_.get());
103 AreaHolder* holder = GetAreaHolder(origin);
104 if (holder) {
105 holder->area_->DeleteOrigin();
106 return;
108 if (!directory_.empty()) {
109 scoped_refptr<DOMStorageArea> area =
110 new DOMStorageArea(origin, directory_, task_runner_.get());
111 area->DeleteOrigin();
115 void DOMStorageNamespace::DeleteSessionStorageOrigin(const GURL& origin) {
116 DOMStorageArea* area = OpenStorageArea(origin);
117 area->FastClear();
118 CloseStorageArea(area);
121 void DOMStorageNamespace::PurgeMemory(PurgeOption option) {
122 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 const AreaHolder& holder = it->second;
128 // We can't purge if there are changes pending.
129 if (holder.area_->HasUncommittedChanges()) {
130 if (holder.open_count_ == 0) {
131 // Schedule an immediate commit so the next time we're asked to purge,
132 // we can drop it from memory.
133 holder.area_->ScheduleImmediateCommit();
135 ++it;
136 continue;
139 // If not in use, we can shut it down and remove
140 // it from our collection entirely.
141 if (holder.open_count_ == 0) {
142 holder.area_->Shutdown();
143 areas_.erase(it++);
144 continue;
147 if (option == PURGE_AGGRESSIVE) {
148 // If aggressive is true, we clear caches and such
149 // for opened areas.
150 holder.area_->PurgeMemory();
153 ++it;
157 void DOMStorageNamespace::Shutdown() {
158 AreaMap::const_iterator it = areas_.begin();
159 for (; it != areas_.end(); ++it)
160 it->second.area_->Shutdown();
163 void DOMStorageNamespace::Flush() {
164 for (auto& entry : areas_) {
165 if (!entry.second.area_->HasUncommittedChanges())
166 continue;
167 entry.second.area_->ScheduleImmediateCommit();
171 unsigned int DOMStorageNamespace::CountInMemoryAreas() const {
172 unsigned int area_count = 0;
173 for (AreaMap::const_iterator it = areas_.begin(); it != areas_.end(); ++it) {
174 if (it->second.area_->IsLoadedInMemory())
175 ++area_count;
177 return area_count;
180 DOMStorageNamespace::AreaHolder*
181 DOMStorageNamespace::GetAreaHolder(const GURL& origin) {
182 AreaMap::iterator found = areas_.find(origin);
183 if (found == areas_.end())
184 return NULL;
185 return &(found->second);
188 // AreaHolder
190 DOMStorageNamespace::AreaHolder::AreaHolder()
191 : open_count_(0) {
194 DOMStorageNamespace::AreaHolder::AreaHolder(
195 DOMStorageArea* area, int count)
196 : area_(area), open_count_(count) {
199 DOMStorageNamespace::AreaHolder::~AreaHolder() {
202 } // namespace content