This source file includes following definitions.
- weak_factory_
- GetLength
- GetKey
- GetItem
- SetItem
- RemoveItem
- Clear
- ApplyMutation
- MemoryBytesUsedByCache
- Prime
- Reset
- OnLoadComplete
- OnSetItemComplete
- OnRemoveItemComplete
- OnClearComplete
#include "content/renderer/dom_storage/dom_storage_cached_area.h"
#include "base/basictypes.h"
#include "base/metrics/histogram.h"
#include "base/time/time.h"
#include "content/common/dom_storage/dom_storage_map.h"
#include "content/renderer/dom_storage/dom_storage_proxy.h"
namespace content {
namespace {
static const int kMaxLogGetMessagesToSend = 16 * 1024;
}
DOMStorageCachedArea::DOMStorageCachedArea(int64 namespace_id,
const GURL& origin,
DOMStorageProxy* proxy)
: ignore_all_mutations_(false),
namespace_id_(namespace_id),
origin_(origin),
proxy_(proxy),
remaining_log_get_messages_(0),
weak_factory_(this) {}
DOMStorageCachedArea::~DOMStorageCachedArea() {}
unsigned DOMStorageCachedArea::GetLength(int connection_id) {
PrimeIfNeeded(connection_id);
return map_->Length();
}
base::NullableString16 DOMStorageCachedArea::GetKey(int connection_id,
unsigned index) {
PrimeIfNeeded(connection_id);
return map_->Key(index);
}
base::NullableString16 DOMStorageCachedArea::GetItem(
int connection_id,
const base::string16& key) {
PrimeIfNeeded(connection_id);
base::NullableString16 result = map_->GetItem(key);
if (remaining_log_get_messages_ > 0) {
remaining_log_get_messages_--;
proxy_->LogGetItem(connection_id, key, result);
}
return result;
}
bool DOMStorageCachedArea::SetItem(int connection_id,
const base::string16& key,
const base::string16& value,
const GURL& page_url) {
if (key.length() + value.length() > kPerStorageAreaQuota)
return false;
PrimeIfNeeded(connection_id);
base::NullableString16 unused;
if (!map_->SetItem(key, value, &unused))
return false;
ignore_key_mutations_[key]++;
proxy_->SetItem(
connection_id, key, value, page_url,
base::Bind(&DOMStorageCachedArea::OnSetItemComplete,
weak_factory_.GetWeakPtr(), key));
return true;
}
void DOMStorageCachedArea::RemoveItem(int connection_id,
const base::string16& key,
const GURL& page_url) {
PrimeIfNeeded(connection_id);
base::string16 unused;
if (!map_->RemoveItem(key, &unused))
return;
ignore_key_mutations_[key]++;
proxy_->RemoveItem(
connection_id, key, page_url,
base::Bind(&DOMStorageCachedArea::OnRemoveItemComplete,
weak_factory_.GetWeakPtr(), key));
}
void DOMStorageCachedArea::Clear(int connection_id, const GURL& page_url) {
Reset();
map_ = new DOMStorageMap(kPerStorageAreaQuota);
ignore_all_mutations_ = true;
proxy_->ClearArea(connection_id,
page_url,
base::Bind(&DOMStorageCachedArea::OnClearComplete,
weak_factory_.GetWeakPtr()));
}
void DOMStorageCachedArea::ApplyMutation(
const base::NullableString16& key,
const base::NullableString16& new_value) {
if (!map_.get() || ignore_all_mutations_)
return;
if (key.is_null()) {
scoped_refptr<DOMStorageMap> old = map_;
map_ = new DOMStorageMap(kPerStorageAreaQuota);
std::map<base::string16, int>::iterator iter =
ignore_key_mutations_.begin();
while (iter != ignore_key_mutations_.end()) {
base::NullableString16 value = old->GetItem(iter->first);
if (!value.is_null()) {
base::NullableString16 unused;
map_->SetItem(iter->first, value.string(), &unused);
}
++iter;
}
return;
}
if (should_ignore_key_mutation(key.string()))
return;
if (new_value.is_null()) {
base::string16 unused;
map_->RemoveItem(key.string(), &unused);
return;
}
base::NullableString16 unused;
map_->set_quota(kint32max);
map_->SetItem(key.string(), new_value.string(), &unused);
map_->set_quota(kPerStorageAreaQuota);
}
size_t DOMStorageCachedArea::MemoryBytesUsedByCache() const {
return map_.get() ? map_->bytes_used() : 0;
}
void DOMStorageCachedArea::Prime(int connection_id) {
DCHECK(!map_.get());
ignore_all_mutations_ = true;
DOMStorageValuesMap values;
bool send_log_get_messages = false;
base::TimeTicks before = base::TimeTicks::Now();
proxy_->LoadArea(connection_id,
&values,
&send_log_get_messages,
base::Bind(&DOMStorageCachedArea::OnLoadComplete,
weak_factory_.GetWeakPtr()));
base::TimeDelta time_to_prime = base::TimeTicks::Now() - before;
UMA_HISTOGRAM_TIMES("LocalStorage.TimeToPrimeLocalStorage",
time_to_prime);
map_ = new DOMStorageMap(kPerStorageAreaQuota);
map_->SwapValues(&values);
if (send_log_get_messages)
remaining_log_get_messages_ = kMaxLogGetMessagesToSend;
size_t local_storage_size_kb = map_->bytes_used() / 1024;
UMA_HISTOGRAM_CUSTOM_COUNTS("LocalStorage.RendererLocalStorageSizeInKB",
local_storage_size_kb,
0, 6 * 1024, 50);
if (local_storage_size_kb < 100) {
UMA_HISTOGRAM_TIMES(
"LocalStorage.RendererTimeToPrimeLocalStorageUnder100KB",
time_to_prime);
} else if (local_storage_size_kb < 1000) {
UMA_HISTOGRAM_TIMES(
"LocalStorage.RendererTimeToPrimeLocalStorage100KBTo1MB",
time_to_prime);
} else {
UMA_HISTOGRAM_TIMES(
"LocalStorage.RendererTimeToPrimeLocalStorage1MBTo5MB",
time_to_prime);
}
}
void DOMStorageCachedArea::Reset() {
map_ = NULL;
weak_factory_.InvalidateWeakPtrs();
ignore_key_mutations_.clear();
ignore_all_mutations_ = false;
}
void DOMStorageCachedArea::OnLoadComplete(bool success) {
DCHECK(success);
DCHECK(ignore_all_mutations_);
ignore_all_mutations_ = false;
}
void DOMStorageCachedArea::OnSetItemComplete(const base::string16& key,
bool success) {
if (!success) {
Reset();
return;
}
std::map<base::string16, int>::iterator found =
ignore_key_mutations_.find(key);
DCHECK(found != ignore_key_mutations_.end());
if (--found->second == 0)
ignore_key_mutations_.erase(found);
}
void DOMStorageCachedArea::OnRemoveItemComplete(const base::string16& key,
bool success) {
DCHECK(success);
std::map<base::string16, int>::iterator found =
ignore_key_mutations_.find(key);
DCHECK(found != ignore_key_mutations_.end());
if (--found->second == 0)
ignore_key_mutations_.erase(found);
}
void DOMStorageCachedArea::OnClearComplete(bool success) {
DCHECK(success);
DCHECK(ignore_all_mutations_);
ignore_all_mutations_ = false;
}
}