blob: 9168f72764a91f410476c502145f2ff622250c19 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/network/shared_dictionary/shared_dictionary_storage_in_memory.h"
#include "base/containers/cxx20_erase_map.h"
#include "base/logging.h"
#include "base/strings/pattern.h"
#include "base/strings/string_util.h"
#include "net/base/io_buffer.h"
#include "services/network/shared_dictionary/shared_dictionary_in_memory.h"
#include "services/network/shared_dictionary/shared_dictionary_manager_in_memory.h"
#include "services/network/shared_dictionary/shared_dictionary_writer_in_memory.h"
#include "url/scheme_host_port.h"
namespace network {
SharedDictionaryStorageInMemory::SharedDictionaryStorageInMemory(
base::WeakPtr<SharedDictionaryManagerInMemory> manager,
base::ScopedClosureRunner on_deleted_closure_runner)
: manager_(manager),
on_deleted_closure_runner_(std::move(on_deleted_closure_runner)) {}
SharedDictionaryStorageInMemory::~SharedDictionaryStorageInMemory() = default;
std::unique_ptr<SharedDictionary>
SharedDictionaryStorageInMemory::GetDictionary(const GURL& url) {
DictionaryInfo* info =
GetMatchingDictionaryFromDictionaryInfoMap(dictionary_info_map_, url);
if (!info) {
return nullptr;
}
info->set_last_used_time(base::Time::Now());
return std::make_unique<SharedDictionaryInMemory>(info->data(), info->size(),
info->hash());
}
void SharedDictionaryStorageInMemory::DeleteDictionary(
const url::SchemeHostPort& host,
const std::string& match) {
auto it = dictionary_info_map_.find(host);
if (it != dictionary_info_map_.end()) {
it->second.erase(match);
if (it->second.empty()) {
dictionary_info_map_.erase(it);
}
}
}
void SharedDictionaryStorageInMemory::ClearData(
base::Time start_time,
base::Time end_time,
base::RepeatingCallback<bool(const GURL&)> url_matcher) {
for (auto& it : dictionary_info_map_) {
base::EraseIf(it.second, [start_time, end_time, url_matcher](auto& it2) {
const DictionaryInfo& dict = it2.second;
return (dict.response_time() >= start_time) &&
(dict.response_time() < end_time) &&
(!url_matcher || url_matcher.Run(dict.url().GetWithEmptyPath()));
});
}
base::EraseIf(dictionary_info_map_,
[](auto& it) { return it.second.empty(); });
}
scoped_refptr<SharedDictionaryWriter>
SharedDictionaryStorageInMemory::CreateWriter(const GURL& url,
base::Time response_time,
base::TimeDelta expiration,
const std::string& match) {
return base::MakeRefCounted<SharedDictionaryWriterInMemory>(base::BindOnce(
&SharedDictionaryStorageInMemory::OnDictionaryWritten,
weak_factory_.GetWeakPtr(), url, response_time, expiration, match));
}
void SharedDictionaryStorageInMemory::OnDictionaryWritten(
const GURL& url,
base::Time response_time,
base::TimeDelta expiration,
const std::string& match,
SharedDictionaryWriterInMemory::Result result,
scoped_refptr<net::IOBuffer> data,
size_t size,
const net::SHA256HashValue& hash) {
if (result != SharedDictionaryWriterInMemory::Result::kSuccess) {
return;
}
dictionary_info_map_[url::SchemeHostPort(url)].insert(std::make_pair(
match,
DictionaryInfo(url, response_time, expiration, match,
/*last_used_time=*/base::Time::Now(), data, size, hash)));
if (manager_) {
manager_->MaybeRunCacheEviction();
}
}
SharedDictionaryStorageInMemory::DictionaryInfo::DictionaryInfo(
const GURL& url,
base::Time response_time,
base::TimeDelta expiration,
const std::string& match,
base::Time last_used_time,
scoped_refptr<net::IOBuffer> data,
size_t size,
const net::SHA256HashValue& hash)
: url_(url),
response_time_(response_time),
expiration_(expiration),
match_(match),
last_used_time_(last_used_time),
data_(std::move(data)),
size_(size),
hash_(hash) {}
SharedDictionaryStorageInMemory::DictionaryInfo::DictionaryInfo(
DictionaryInfo&& other) = default;
SharedDictionaryStorageInMemory::DictionaryInfo&
SharedDictionaryStorageInMemory::DictionaryInfo::operator=(
SharedDictionaryStorageInMemory::DictionaryInfo&& other) = default;
SharedDictionaryStorageInMemory::DictionaryInfo::~DictionaryInfo() = default;
} // namespace network