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

Side by Side Diff: content/browser/dom_storage/dom_storage_namespace.cc

Issue 1953703004: Purge browser cache for dom storage in a smarter way (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@dom_storage
Patch Set: Fixes. Created 4 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/dom_storage/dom_storage_namespace.h" 5 #include "content/browser/dom_storage/dom_storage_namespace.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/sys_info.h"
10 #include "content/browser/dom_storage/dom_storage_area.h" 11 #include "content/browser/dom_storage/dom_storage_area.h"
11 #include "content/browser/dom_storage/dom_storage_task_runner.h" 12 #include "content/browser/dom_storage/dom_storage_task_runner.h"
12 #include "content/browser/dom_storage/session_storage_database.h" 13 #include "content/browser/dom_storage/session_storage_database.h"
13 #include "content/common/dom_storage/dom_storage_types.h" 14 #include "content/common/dom_storage/dom_storage_types.h"
14 15
15 namespace content { 16 namespace content {
17 namespace {
18 // Limits on the cache size and number of areas in memory, over which the areas
19 // are purged.
20 #if defined(OS_ANDROID)
21 const size_t kMaxStorageAreaCount = 20;
22 const uint64_t kMaxCacheSize = 2 * 1024 * 1024;
23 #else
24 const size_t kMaxStorageAreaCount = 100;
25 const uint64_t kMaxCacheSize = 20 * 1024 * 1024;
26 #endif
ssid 2016/05/10 02:04:16 Not sure if I should move these to dom_storage_typ
27 } // namespace
16 28
17 DOMStorageNamespace::DOMStorageNamespace( 29 DOMStorageNamespace::DOMStorageNamespace(
18 const base::FilePath& directory, 30 const base::FilePath& directory,
19 DOMStorageTaskRunner* task_runner) 31 DOMStorageTaskRunner* task_runner)
20 : namespace_id_(kLocalStorageNamespaceId), 32 : namespace_id_(kLocalStorageNamespaceId),
21 directory_(directory), 33 directory_(directory),
22 task_runner_(task_runner) { 34 task_runner_(task_runner) {
23 } 35 }
24 36
25 DOMStorageNamespace::DOMStorageNamespace( 37 DOMStorageNamespace::DOMStorageNamespace(
26 int64_t namespace_id, 38 int64_t namespace_id,
27 const std::string& persistent_namespace_id, 39 const std::string& persistent_namespace_id,
28 SessionStorageDatabase* session_storage_database, 40 SessionStorageDatabase* session_storage_database,
29 DOMStorageTaskRunner* task_runner) 41 DOMStorageTaskRunner* task_runner)
30 : namespace_id_(namespace_id), 42 : namespace_id_(namespace_id),
31 persistent_namespace_id_(persistent_namespace_id), 43 persistent_namespace_id_(persistent_namespace_id),
32 task_runner_(task_runner), 44 task_runner_(task_runner),
33 session_storage_database_(session_storage_database) { 45 session_storage_database_(session_storage_database),
46 is_low_end_device_(base::SysInfo::IsLowEndDevice()) {
34 DCHECK_NE(kLocalStorageNamespaceId, namespace_id); 47 DCHECK_NE(kLocalStorageNamespaceId, namespace_id);
35 } 48 }
36 49
37 DOMStorageNamespace::~DOMStorageNamespace() { 50 DOMStorageNamespace::~DOMStorageNamespace() {
38 } 51 }
39 52
40 DOMStorageArea* DOMStorageNamespace::OpenStorageArea(const GURL& origin) { 53 DOMStorageArea* DOMStorageNamespace::OpenStorageArea(const GURL& origin) {
41 if (AreaHolder* holder = GetAreaHolder(origin)) { 54 if (AreaHolder* holder = GetAreaHolder(origin)) {
42 ++(holder->open_count_); 55 ++(holder->open_count_);
43 return holder->area_.get(); 56 return holder->area_.get();
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 126
114 void DOMStorageNamespace::DeleteSessionStorageOrigin(const GURL& origin) { 127 void DOMStorageNamespace::DeleteSessionStorageOrigin(const GURL& origin) {
115 DOMStorageArea* area = OpenStorageArea(origin); 128 DOMStorageArea* area = OpenStorageArea(origin);
116 area->FastClear(); 129 area->FastClear();
117 CloseStorageArea(area); 130 CloseStorageArea(area);
118 } 131 }
119 132
120 void DOMStorageNamespace::PurgeMemory(PurgeOption option) { 133 void DOMStorageNamespace::PurgeMemory(PurgeOption option) {
121 if (directory_.empty()) 134 if (directory_.empty())
122 return; // We can't purge w/o backing on disk. 135 return; // We can't purge w/o backing on disk.
136
137 if (option == PURGE_IF_NEEDED) {
138 if (!ShouldPurgeMemory())
139 return;
140 option = PURGE_UNOPENED;
141 }
142
123 AreaMap::iterator it = areas_.begin(); 143 AreaMap::iterator it = areas_.begin();
124 while (it != areas_.end()) { 144 while (it != areas_.end()) {
125 const AreaHolder& holder = it->second; 145 const AreaHolder& holder = it->second;
126 146
127 // We can't purge if there are changes pending. 147 // We can't purge if there are changes pending.
128 if (holder.area_->HasUncommittedChanges()) { 148 if (holder.area_->HasUncommittedChanges()) {
129 if (holder.open_count_ == 0) { 149 if (holder.open_count_ == 0) {
130 // Schedule an immediate commit so the next time we're asked to purge, 150 // Schedule an immediate commit so the next time we're asked to purge,
131 // we can drop it from memory. 151 // we can drop it from memory.
132 holder.area_->ScheduleImmediateCommit(); 152 holder.area_->ScheduleImmediateCommit();
133 } 153 }
134 ++it; 154 it++;
135 continue; 155 continue;
136 } 156 }
137 157
138 // If not in use, we can shut it down and remove 158 // If not in use, we can shut it down and remove
139 // it from our collection entirely. 159 // it from our collection entirely.
140 if (holder.open_count_ == 0) { 160 if (holder.open_count_ == 0) {
141 holder.area_->Shutdown(); 161 holder.area_->Shutdown();
142 areas_.erase(it++); 162 areas_.erase(it++);
143 continue; 163 continue;
144 } 164 }
145 165
146 if (option == PURGE_AGGRESSIVE) { 166 if (option == PURGE_AGGRESSIVE) {
147 // If aggressive is true, we clear caches and such 167 // If aggressive is true, we clear caches and such
148 // for opened areas. 168 // for opened areas.
149 holder.area_->PurgeMemory(); 169 holder.area_->PurgeMemory();
150 } 170 }
151 171 it++;
152 ++it;
153 } 172 }
154 } 173 }
155 174
175 bool DOMStorageNamespace::ShouldPurgeMemory() {
176 // Purging is done based on the cache sizes without including the database
177 // size since it can be expensive trying to estimate the sqlite usage for all
178 // databases.
179 size_t total_cache_size = 0;
180 size_t total_area_count = 0;
181 unsigned inactive_area_count = 0;
182 for (AreaMap::const_iterator it = areas_.begin(); it != areas_.end(); ++it) {
183 if (it->second.area_->IsLoadedInMemory()) {
184 total_cache_size += it->second.area_->map_usage_in_bytes();
185 ++total_area_count;
186 if (it->second.open_count_ == 0)
187 ++inactive_area_count;
188 }
189 }
190
191 // Purge caches of closed databases on low end devices.
192 if (is_low_end_device_ && inactive_area_count)
193 return true;
194
195 if (total_cache_size > kMaxCacheSize ||
196 total_area_count > kMaxStorageAreaCount)
197 return true;
198
199 return false;
200 }
201
156 void DOMStorageNamespace::Shutdown() { 202 void DOMStorageNamespace::Shutdown() {
157 AreaMap::const_iterator it = areas_.begin(); 203 AreaMap::const_iterator it = areas_.begin();
158 for (; it != areas_.end(); ++it) 204 for (; it != areas_.end(); ++it)
159 it->second.area_->Shutdown(); 205 it->second.area_->Shutdown();
160 } 206 }
161 207
162 void DOMStorageNamespace::Flush() { 208 void DOMStorageNamespace::Flush() {
163 for (auto& entry : areas_) { 209 for (auto& entry : areas_) {
164 if (!entry.second.area_->HasUncommittedChanges()) 210 if (!entry.second.area_->HasUncommittedChanges())
165 continue; 211 continue;
166 entry.second.area_->ScheduleImmediateCommit(); 212 entry.second.area_->ScheduleImmediateCommit();
167 } 213 }
168 } 214 }
169 215
170 unsigned int DOMStorageNamespace::CountInMemoryAreas() const {
171 unsigned int area_count = 0;
172 for (AreaMap::const_iterator it = areas_.begin(); it != areas_.end(); ++it) {
173 if (it->second.area_->IsLoadedInMemory())
174 ++area_count;
175 }
176 return area_count;
177 }
178
179 void DOMStorageNamespace::OnMemoryDump( 216 void DOMStorageNamespace::OnMemoryDump(
180 base::trace_event::ProcessMemoryDump* pmd) { 217 base::trace_event::ProcessMemoryDump* pmd) {
181 DCHECK(task_runner_->IsRunningOnPrimarySequence()); 218 DCHECK(task_runner_->IsRunningOnPrimarySequence());
182 for (const auto& it : areas_) 219 for (const auto& it : areas_)
183 it.second.area_->OnMemoryDump(pmd); 220 it.second.area_->OnMemoryDump(pmd);
184 } 221 }
185 222
186 void DOMStorageNamespace::GetOriginsWithAreas( 223 void DOMStorageNamespace::GetOriginsWithAreas(
187 std::vector<GURL>* origins) const { 224 std::vector<GURL>* origins) const {
188 origins->clear(); 225 origins->clear();
(...skipping 19 matching lines...) Expand all
208 DOMStorageArea* area, int count) 245 DOMStorageArea* area, int count)
209 : area_(area), open_count_(count) { 246 : area_(area), open_count_(count) {
210 } 247 }
211 248
212 DOMStorageNamespace::AreaHolder::AreaHolder(const AreaHolder& other) = default; 249 DOMStorageNamespace::AreaHolder::AreaHolder(const AreaHolder& other) = default;
213 250
214 DOMStorageNamespace::AreaHolder::~AreaHolder() { 251 DOMStorageNamespace::AreaHolder::~AreaHolder() {
215 } 252 }
216 253
217 } // namespace content 254 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/dom_storage/dom_storage_namespace.h ('k') | content/browser/dom_storage/local_storage_database_adapter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698