blob: 5874104f6eedb915a76b68e760a8f9fa58293a6c [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/cache_storage/cache_storage_index.h"
#include <utility>
namespace content {
CacheStorageIndex::CacheStorageIndex()
: doomed_cache_metadata_("",
CacheStorage::kSizeUnknown,
CacheStorage::kSizeUnknown,
"") {
ClearDoomedCache();
}
CacheStorageIndex::~CacheStorageIndex() = default;
CacheStorageIndex& CacheStorageIndex::operator=(CacheStorageIndex&& rhs) {
DCHECK(!has_doomed_cache_);
ordered_cache_metadata_ = std::move(rhs.ordered_cache_metadata_);
cache_metadata_map_ = std::move(rhs.cache_metadata_map_);
storage_size_ = rhs.storage_size_;
storage_padding_ = rhs.storage_padding_;
rhs.storage_size_ = CacheStorage::kSizeUnknown;
rhs.storage_padding_ = CacheStorage::kSizeUnknown;
return *this;
}
void CacheStorageIndex::Insert(const CacheMetadata& cache_metadata) {
DCHECK(!has_doomed_cache_);
DCHECK(cache_metadata_map_.find(cache_metadata.name) ==
cache_metadata_map_.end());
ordered_cache_metadata_.push_back(cache_metadata);
cache_metadata_map_[cache_metadata.name] = --ordered_cache_metadata_.end();
storage_size_ = CacheStorage::kSizeUnknown;
storage_padding_ = CacheStorage::kSizeUnknown;
}
void CacheStorageIndex::Delete(const std::string& cache_name) {
DCHECK(!has_doomed_cache_);
auto it = cache_metadata_map_.find(cache_name);
DCHECK(it != cache_metadata_map_.end());
ordered_cache_metadata_.erase(it->second);
cache_metadata_map_.erase(it);
storage_size_ = CacheStorage::kSizeUnknown;
storage_padding_ = CacheStorage::kSizeUnknown;
}
bool CacheStorageIndex::SetCacheSize(const std::string& cache_name,
int64_t size) {
if (has_doomed_cache_)
DCHECK_NE(cache_name, doomed_cache_metadata_.name);
auto it = cache_metadata_map_.find(cache_name);
DCHECK(it != cache_metadata_map_.end());
if (it->second->size == size)
return false;
it->second->size = size;
storage_size_ = CacheStorage::kSizeUnknown;
return true;
}
const CacheStorageIndex::CacheMetadata* CacheStorageIndex::GetMetadata(
const std::string& cache_name) const {
const auto& it = cache_metadata_map_.find(cache_name);
if (it == cache_metadata_map_.end())
return nullptr;
return &*it->second;
}
int64_t CacheStorageIndex::GetCacheSizeForTesting(
const std::string& cache_name) const {
const auto& it = cache_metadata_map_.find(cache_name);
if (it == cache_metadata_map_.end())
return CacheStorage::kSizeUnknown;
return it->second->size;
}
bool CacheStorageIndex::SetCachePadding(const std::string& cache_name,
int64_t padding) {
DCHECK(!has_doomed_cache_ || cache_name != doomed_cache_metadata_.name)
<< "Setting padding of doomed cache: \"" << cache_name << '"';
auto it = cache_metadata_map_.find(cache_name);
DCHECK(it != cache_metadata_map_.end());
if (it->second->padding == padding)
return false;
it->second->padding = padding;
storage_padding_ = CacheStorage::kSizeUnknown;
return true;
}
int64_t CacheStorageIndex::GetCachePaddingForTesting(
const std::string& cache_name) const {
const auto& it = cache_metadata_map_.find(cache_name);
if (it == cache_metadata_map_.end())
return CacheStorage::kSizeUnknown;
return it->second->padding;
}
int64_t CacheStorageIndex::GetPaddedStorageSize() {
if (storage_size_ == CacheStorage::kSizeUnknown)
UpdateStorageSize();
if (storage_padding_ == CacheStorage::kSizeUnknown)
CalculateStoragePadding();
if (storage_size_ == CacheStorage::kSizeUnknown ||
storage_padding_ == CacheStorage::kSizeUnknown) {
return CacheStorage::kSizeUnknown;
}
return storage_size_ + storage_padding_;
}
void CacheStorageIndex::UpdateStorageSize() {
int64_t storage_size = 0;
storage_size_ = CacheStorage::kSizeUnknown;
for (const CacheMetadata& info : ordered_cache_metadata_) {
if (info.size == CacheStorage::kSizeUnknown)
return;
storage_size += info.size;
}
storage_size_ = storage_size;
}
void CacheStorageIndex::CalculateStoragePadding() {
int64_t storage_padding = 0;
storage_padding_ = CacheStorage::kSizeUnknown;
for (const CacheMetadata& info : ordered_cache_metadata_) {
if (info.padding == CacheStorage::kSizeUnknown)
return;
storage_padding += info.padding;
}
storage_padding_ = storage_padding;
}
void CacheStorageIndex::DoomCache(const std::string& cache_name) {
DCHECK(!has_doomed_cache_);
auto map_it = cache_metadata_map_.find(cache_name);
DCHECK(map_it != cache_metadata_map_.end());
doomed_cache_metadata_ = std::move(*(map_it->second));
after_doomed_cache_metadata_ = ordered_cache_metadata_.erase(map_it->second);
cache_metadata_map_.erase(map_it);
storage_size_ = CacheStorage::kSizeUnknown;
storage_padding_ = CacheStorage::kSizeUnknown;
has_doomed_cache_ = true;
}
void CacheStorageIndex::FinalizeDoomedCache() {
DCHECK(has_doomed_cache_);
ClearDoomedCache();
}
void CacheStorageIndex::RestoreDoomedCache() {
DCHECK(has_doomed_cache_);
const auto cache_name = doomed_cache_metadata_.name;
cache_metadata_map_[cache_name] = ordered_cache_metadata_.insert(
after_doomed_cache_metadata_, std::move(doomed_cache_metadata_));
after_doomed_cache_metadata_ = ordered_cache_metadata_.end();
storage_size_ = CacheStorage::kSizeUnknown;
storage_padding_ = CacheStorage::kSizeUnknown;
ClearDoomedCache();
}
void CacheStorageIndex::ClearDoomedCache() {
doomed_cache_metadata_.name.clear();
after_doomed_cache_metadata_ = ordered_cache_metadata_.end();
has_doomed_cache_ = false;
}
} // namespace content