OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "webkit/dom_storage/dom_storage_context.h" | 5 #include "webkit/dom_storage/dom_storage_context.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/guid.h" | 10 #include "base/guid.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/time.h" | 12 #include "base/time.h" |
13 #include "webkit/dom_storage/dom_storage_area.h" | 13 #include "webkit/dom_storage/dom_storage_area.h" |
14 #include "webkit/dom_storage/dom_storage_database.h" | 14 #include "webkit/dom_storage/dom_storage_database.h" |
15 #include "webkit/dom_storage/dom_storage_host.h" | |
15 #include "webkit/dom_storage/dom_storage_namespace.h" | 16 #include "webkit/dom_storage/dom_storage_namespace.h" |
16 #include "webkit/dom_storage/dom_storage_task_runner.h" | 17 #include "webkit/dom_storage/dom_storage_task_runner.h" |
17 #include "webkit/dom_storage/dom_storage_types.h" | 18 #include "webkit/dom_storage/dom_storage_types.h" |
18 #include "webkit/dom_storage/session_storage_database.h" | 19 #include "webkit/dom_storage/session_storage_database.h" |
19 #include "webkit/quota/special_storage_policy.h" | 20 #include "webkit/quota/special_storage_policy.h" |
20 | 21 |
21 using file_util::FileEnumerator; | 22 using file_util::FileEnumerator; |
22 | 23 |
23 namespace dom_storage { | 24 namespace dom_storage { |
24 | 25 |
25 static const int kSessionStoraceScavengingSeconds = 60; | 26 static const int kSessionStoraceScavengingSeconds = 60; |
26 | 27 |
27 DomStorageContext::DomStorageContext( | 28 DomStorageContext::DomStorageContext( |
28 const base::FilePath& localstorage_directory, | 29 const base::FilePath& localstorage_directory, |
29 const base::FilePath& sessionstorage_directory, | 30 const base::FilePath& sessionstorage_directory, |
30 quota::SpecialStoragePolicy* special_storage_policy, | 31 quota::SpecialStoragePolicy* special_storage_policy, |
31 DomStorageTaskRunner* task_runner) | 32 DomStorageTaskRunner* task_runner) |
32 : localstorage_directory_(localstorage_directory), | 33 : localstorage_directory_(localstorage_directory), |
33 sessionstorage_directory_(sessionstorage_directory), | 34 sessionstorage_directory_(sessionstorage_directory), |
34 task_runner_(task_runner), | 35 task_runner_(task_runner), |
35 is_shutdown_(false), | 36 is_shutdown_(false), |
36 force_keep_session_state_(false), | 37 force_keep_session_state_(false), |
37 special_storage_policy_(special_storage_policy), | 38 special_storage_policy_(special_storage_policy), |
38 scavenging_started_(false) { | 39 scavenging_started_(false), |
40 total_area_size_(-1) { | |
39 // AtomicSequenceNum starts at 0 but we want to start session | 41 // AtomicSequenceNum starts at 0 but we want to start session |
40 // namespace ids at one since zero is reserved for the | 42 // namespace ids at one since zero is reserved for the |
41 // kLocalStorageNamespaceId. | 43 // kLocalStorageNamespaceId. |
42 session_id_sequence_.GetNext(); | 44 session_id_sequence_.GetNext(); |
43 } | 45 } |
44 | 46 |
45 DomStorageContext::~DomStorageContext() { | 47 DomStorageContext::~DomStorageContext() { |
46 if (session_storage_database_.get()) { | 48 if (session_storage_database_.get()) { |
47 // SessionStorageDatabase shouldn't be deleted right away: deleting it will | 49 // SessionStorageDatabase shouldn't be deleted right away: deleting it will |
48 // potentially involve waiting in leveldb::DBImpl::~DBImpl, and waiting | 50 // potentially involve waiting in leveldb::DBImpl::~DBImpl, and waiting |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 void DomStorageContext::RemoveEventObserver(EventObserver* observer) { | 209 void DomStorageContext::RemoveEventObserver(EventObserver* observer) { |
208 event_observers_.RemoveObserver(observer); | 210 event_observers_.RemoveObserver(observer); |
209 } | 211 } |
210 | 212 |
211 void DomStorageContext::NotifyItemSet( | 213 void DomStorageContext::NotifyItemSet( |
212 const DomStorageArea* area, | 214 const DomStorageArea* area, |
213 const string16& key, | 215 const string16& key, |
214 const string16& new_value, | 216 const string16& new_value, |
215 const NullableString16& old_value, | 217 const NullableString16& old_value, |
216 const GURL& page_url) { | 218 const GURL& page_url) { |
219 InvalidateInMemoryAreaSize(); | |
217 FOR_EACH_OBSERVER( | 220 FOR_EACH_OBSERVER( |
218 EventObserver, event_observers_, | 221 EventObserver, event_observers_, |
219 OnDomStorageItemSet(area, key, new_value, old_value, page_url)); | 222 OnDomStorageItemSet(area, key, new_value, old_value, page_url)); |
220 } | 223 } |
221 | 224 |
222 void DomStorageContext::NotifyItemRemoved( | 225 void DomStorageContext::NotifyItemRemoved( |
223 const DomStorageArea* area, | 226 const DomStorageArea* area, |
224 const string16& key, | 227 const string16& key, |
225 const string16& old_value, | 228 const string16& old_value, |
226 const GURL& page_url) { | 229 const GURL& page_url) { |
230 InvalidateInMemoryAreaSize(); | |
227 FOR_EACH_OBSERVER( | 231 FOR_EACH_OBSERVER( |
228 EventObserver, event_observers_, | 232 EventObserver, event_observers_, |
229 OnDomStorageItemRemoved(area, key, old_value, page_url)); | 233 OnDomStorageItemRemoved(area, key, old_value, page_url)); |
230 } | 234 } |
231 | 235 |
232 void DomStorageContext::NotifyAreaCleared( | 236 void DomStorageContext::NotifyAreaCleared( |
233 const DomStorageArea* area, | 237 const DomStorageArea* area, |
234 const GURL& page_url) { | 238 const GURL& page_url) { |
239 InvalidateInMemoryAreaSize(); | |
235 FOR_EACH_OBSERVER( | 240 FOR_EACH_OBSERVER( |
236 EventObserver, event_observers_, | 241 EventObserver, event_observers_, |
237 OnDomStorageAreaCleared(area, page_url)); | 242 OnDomStorageAreaCleared(area, page_url)); |
238 } | 243 } |
239 | 244 |
240 std::string DomStorageContext::AllocatePersistentSessionId() { | 245 std::string DomStorageContext::AllocatePersistentSessionId() { |
241 std::string guid = base::GenerateGUID(); | 246 std::string guid = base::GenerateGUID(); |
242 std::replace(guid.begin(), guid.end(), '-', '_'); | 247 std::replace(guid.begin(), guid.end(), '-', '_'); |
243 return guid; | 248 return guid; |
244 } | 249 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
345 } | 350 } |
346 | 351 |
347 void DomStorageContext::StartScavengingUnusedSessionStorage() { | 352 void DomStorageContext::StartScavengingUnusedSessionStorage() { |
348 if (session_storage_database_.get()) { | 353 if (session_storage_database_.get()) { |
349 task_runner_->PostDelayedTask( | 354 task_runner_->PostDelayedTask( |
350 FROM_HERE, base::Bind(&DomStorageContext::FindUnusedNamespaces, this), | 355 FROM_HERE, base::Bind(&DomStorageContext::FindUnusedNamespaces, this), |
351 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); | 356 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); |
352 } | 357 } |
353 } | 358 } |
354 | 359 |
360 bool DomStorageContext::CanSetItem( | |
361 DomStorageHost* host, | |
362 int connection_id, | |
363 const string16& key, | |
364 const string16& value) { | |
365 DCHECK(host); | |
366 if (GetRemainingCacheSize() >= static_cast<int64>(kPerAreaQuota)) | |
367 return true; | |
368 // Go through the slower check only if the memory is getting tight. | |
369 // TODO(kinuko,michaeln): Purge cache memory if we're caching too many areas. | |
370 NullableString16 old_value = host->GetAreaItem(connection_id, key); | |
371 int64 increase = value.size(); | |
372 if (old_value.is_null()) | |
373 increase += key.size(); | |
374 else | |
375 increase -= old_value.string().size(); | |
376 return static_cast<int64>(increase * sizeof(char16)) <= | |
377 GetRemainingCacheSize(); | |
378 } | |
379 | |
355 void DomStorageContext::FindUnusedNamespaces() { | 380 void DomStorageContext::FindUnusedNamespaces() { |
356 DCHECK(session_storage_database_.get()); | 381 DCHECK(session_storage_database_.get()); |
357 if (scavenging_started_) | 382 if (scavenging_started_) |
358 return; | 383 return; |
359 scavenging_started_ = true; | 384 scavenging_started_ = true; |
360 std::set<std::string> namespace_ids_in_use; | 385 std::set<std::string> namespace_ids_in_use; |
361 for (StorageNamespaceMap::const_iterator it = namespaces_.begin(); | 386 for (StorageNamespaceMap::const_iterator it = namespaces_.begin(); |
362 it != namespaces_.end(); ++it) | 387 it != namespaces_.end(); ++it) |
363 namespace_ids_in_use.insert(it->second->persistent_namespace_id()); | 388 namespace_ids_in_use.insert(it->second->persistent_namespace_id()); |
364 std::set<std::string> protected_persistent_session_ids; | 389 std::set<std::string> protected_persistent_session_ids; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
414 deletable_persistent_namespace_ids_.pop_back(); | 439 deletable_persistent_namespace_ids_.pop_back(); |
415 if (!deletable_persistent_namespace_ids_.empty()) { | 440 if (!deletable_persistent_namespace_ids_.empty()) { |
416 task_runner_->PostDelayedTask( | 441 task_runner_->PostDelayedTask( |
417 FROM_HERE, base::Bind( | 442 FROM_HERE, base::Bind( |
418 &DomStorageContext::DeleteNextUnusedNamespace, | 443 &DomStorageContext::DeleteNextUnusedNamespace, |
419 this), | 444 this), |
420 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); | 445 base::TimeDelta::FromSeconds(kSessionStoraceScavengingSeconds)); |
421 } | 446 } |
422 } | 447 } |
423 | 448 |
449 int64 DomStorageContext::GetRemainingCacheSize() { | |
450 if (total_area_size_ < 0) { | |
Mike West
2013/03/06 13:41:11
I don't see where you're updating total_area_size_
| |
451 total_area_size_ = 0; | |
452 // Naively add-up the area size for each connection. | |
453 std::set<DomStorageArea*> visited_areas; | |
454 for (StorageNamespaceMap::const_iterator itr = namespaces_.begin(); | |
455 itr != namespaces_.end(); ++itr) { | |
456 const DomStorageNamespace::AreaMap& map = itr->second->GetAreaMap(); | |
457 for (DomStorageNamespace::AreaMap::const_iterator map_itr = map.begin(); | |
458 map_itr != map.end(); ++map_itr) { | |
459 // We don't care open_count_ here, since we don't purge memory (yet). | |
460 DomStorageArea* area = map_itr->second.area_; | |
461 DCHECK(area); | |
462 if (visited_areas.insert(area).second) | |
463 total_area_size_ += area->GetMapSize(); | |
464 } | |
465 } | |
466 } | |
467 return kMaxInMemoryAreaSize - total_area_size_; | |
468 } | |
469 | |
424 } // namespace dom_storage | 470 } // namespace dom_storage |
OLD | NEW |