#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "net/disk_cache/blockfile/backend_impl.h"
#include <algorithm>
#include <limits>
#include <memory>
#include <utility>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/hash/hash.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/message_loop/message_pump_type.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/system/sys_info.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "net/base/net_errors.h"
#include "net/base/tracing.h"
#include "net/disk_cache/backend_cleanup_tracker.h"
#include "net/disk_cache/blockfile/disk_format.h"
#include "net/disk_cache/blockfile/entry_impl.h"
#include "net/disk_cache/blockfile/errors.h"
#include "net/disk_cache/blockfile/experiments.h"
#include "net/disk_cache/blockfile/file.h"
#include "net/disk_cache/cache_util.h"
Time;
TimeTicks;
namespace {
const char kIndexName[] = …;
const int k64kEntriesStore = …;
const int kBaseTableLen = …;
const int kTrimDelay = …;
int DesiredIndexTableLen(int32_t storage_size) { … }
int MaxStorageSizeForTable(int table_len) { … }
size_t GetIndexSize(int table_len) { … }
bool InitExperiment(disk_cache::IndexHeader* header, bool cache_created) { … }
void FinalCleanupCallback(disk_cache::BackendImpl* backend,
base::WaitableEvent* done) { … }
class CacheThread : public base::Thread { … };
static base::LazyInstance<CacheThread>::Leaky g_internal_cache_thread = …;
scoped_refptr<base::SingleThreadTaskRunner> InternalCacheThread() { … }
scoped_refptr<base::SingleThreadTaskRunner> FallbackToInternalIfNull(
const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread) { … }
}
namespace disk_cache {
BackendImpl::BackendImpl(
const base::FilePath& path,
scoped_refptr<BackendCleanupTracker> cleanup_tracker,
const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread,
net::CacheType cache_type,
net::NetLog* net_log)
: … { … }
BackendImpl::BackendImpl(
const base::FilePath& path,
uint32_t mask,
const scoped_refptr<base::SingleThreadTaskRunner>& cache_thread,
net::CacheType cache_type,
net::NetLog* net_log)
: … { … }
BackendImpl::~BackendImpl() { … }
void BackendImpl::Init(CompletionOnceCallback callback) { … }
int BackendImpl::SyncInit() { … }
void BackendImpl::CleanupCache() { … }
int BackendImpl::SyncOpenEntry(const std::string& key,
scoped_refptr<EntryImpl>* entry) { … }
int BackendImpl::SyncCreateEntry(const std::string& key,
scoped_refptr<EntryImpl>* entry) { … }
int BackendImpl::SyncDoomEntry(const std::string& key) { … }
int BackendImpl::SyncDoomAllEntries() { … }
int BackendImpl::SyncDoomEntriesBetween(const base::Time initial_time,
const base::Time end_time) { … }
int BackendImpl::SyncCalculateSizeOfAllEntries() { … }
int BackendImpl::SyncDoomEntriesSince(const base::Time initial_time) { … }
int BackendImpl::SyncOpenNextEntry(Rankings::Iterator* iterator,
scoped_refptr<EntryImpl>* next_entry) { … }
void BackendImpl::SyncEndEnumeration(
std::unique_ptr<Rankings::Iterator> iterator) { … }
void BackendImpl::SyncOnExternalCacheHit(const std::string& key) { … }
scoped_refptr<EntryImpl> BackendImpl::OpenEntryImpl(const std::string& key) { … }
scoped_refptr<EntryImpl> BackendImpl::CreateEntryImpl(const std::string& key) { … }
scoped_refptr<EntryImpl> BackendImpl::OpenNextEntryImpl(
Rankings::Iterator* iterator) { … }
bool BackendImpl::SetMaxSize(int64_t max_bytes) { … }
base::FilePath BackendImpl::GetFileName(Addr address) const { … }
MappedFile* BackendImpl::File(Addr address) { … }
base::WeakPtr<InFlightBackendIO> BackendImpl::GetBackgroundQueue() { … }
bool BackendImpl::CreateExternalFile(Addr* address) { … }
bool BackendImpl::CreateBlock(FileType block_type, int block_count,
Addr* block_address) { … }
void BackendImpl::DeleteBlock(Addr block_address, bool deep) { … }
LruData* BackendImpl::GetLruData() { … }
void BackendImpl::UpdateRank(EntryImpl* entry, bool modified) { … }
void BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) { … }
void BackendImpl::InternalDoomEntry(EntryImpl* entry) { … }
#if defined(NET_BUILD_STRESS_CACHE)
CacheAddr BackendImpl::GetNextAddr(Addr address) {
EntriesMap::iterator it = open_entries_.find(address.value());
if (it != open_entries_.end()) {
EntryImpl* this_entry = it->second;
return this_entry->GetNextAddress();
}
DCHECK(block_files_.IsValid(address));
DCHECK(!address.is_separate_file() && address.file_type() == BLOCK_256);
CacheEntryBlock entry(File(address), address);
CHECK(entry.Load());
return entry.Data()->next;
}
void BackendImpl::NotLinked(EntryImpl* entry) {
Addr entry_addr = entry->entry()->address();
uint32_t i = entry->GetHash() & mask_;
Addr address(data_->table[i]);
if (!address.is_initialized())
return;
for (;;) {
DCHECK(entry_addr.value() != address.value());
address.set_value(GetNextAddr(address));
if (!address.is_initialized())
break;
}
}
#endif
void BackendImpl::RemoveEntry(EntryImpl* entry) { … }
void BackendImpl::OnEntryDestroyBegin(Addr address) { … }
void BackendImpl::OnEntryDestroyEnd() { … }
void BackendImpl::OnSyncBackendOpComplete() { … }
EntryImpl* BackendImpl::GetOpenEntry(CacheRankingsBlock* rankings) const { … }
int32_t BackendImpl::GetCurrentEntryId() const { … }
int64_t BackendImpl::MaxFileSize() const { … }
void BackendImpl::ModifyStorageSize(int32_t old_size, int32_t new_size) { … }
void BackendImpl::TooMuchStorageRequested(int32_t size) { … }
bool BackendImpl::IsAllocAllowed(int current_size, int new_size) { … }
void BackendImpl::BufferDeleted(int size) { … }
bool BackendImpl::IsLoaded() const { … }
base::WeakPtr<BackendImpl> BackendImpl::GetWeakPtr() { … }
bool BackendImpl::ShouldUpdateStats() { … }
void BackendImpl::FirstEviction() { … }
void BackendImpl::CriticalError(int error) { … }
void BackendImpl::ReportError(int error) { … }
void BackendImpl::OnEvent(Stats::Counters an_event) { … }
void BackendImpl::OnRead(int32_t bytes) { … }
void BackendImpl::OnWrite(int32_t bytes) { … }
void BackendImpl::OnStatsTimer() { … }
void BackendImpl::IncrementIoCount() { … }
void BackendImpl::DecrementIoCount() { … }
void BackendImpl::SetUnitTestMode() { … }
void BackendImpl::SetUpgradeMode() { … }
void BackendImpl::SetNewEviction() { … }
void BackendImpl::SetFlags(uint32_t flags) { … }
void BackendImpl::ClearRefCountForTest() { … }
int BackendImpl::FlushQueueForTest(CompletionOnceCallback callback) { … }
int BackendImpl::RunTaskForTest(base::OnceClosure task,
CompletionOnceCallback callback) { … }
void BackendImpl::TrimForTest(bool empty) { … }
void BackendImpl::TrimDeletedListForTest(bool empty) { … }
base::RepeatingTimer* BackendImpl::GetTimerForTest() { … }
int BackendImpl::SelfCheck() { … }
void BackendImpl::FlushIndex() { … }
int32_t BackendImpl::GetEntryCount() const { … }
EntryResult BackendImpl::OpenOrCreateEntry(
const std::string& key,
net::RequestPriority request_priority,
EntryResultCallback callback) { … }
EntryResult BackendImpl::OpenEntry(const std::string& key,
net::RequestPriority request_priority,
EntryResultCallback callback) { … }
EntryResult BackendImpl::CreateEntry(const std::string& key,
net::RequestPriority request_priority,
EntryResultCallback callback) { … }
net::Error BackendImpl::DoomEntry(const std::string& key,
net::RequestPriority priority,
CompletionOnceCallback callback) { … }
net::Error BackendImpl::DoomAllEntries(CompletionOnceCallback callback) { … }
net::Error BackendImpl::DoomEntriesBetween(const base::Time initial_time,
const base::Time end_time,
CompletionOnceCallback callback) { … }
net::Error BackendImpl::DoomEntriesSince(const base::Time initial_time,
CompletionOnceCallback callback) { … }
int64_t BackendImpl::CalculateSizeOfAllEntries(
Int64CompletionOnceCallback callback) { … }
class BackendImpl::IteratorImpl : public Backend::Iterator { … };
std::unique_ptr<Backend::Iterator> BackendImpl::CreateIterator() { … }
void BackendImpl::GetStats(StatsItems* stats) { … }
void BackendImpl::OnExternalCacheHit(const std::string& key) { … }
bool BackendImpl::CreateBackingStore(disk_cache::File* file) { … }
bool BackendImpl::InitBackingStore(bool* file_created) { … }
void BackendImpl::AdjustMaxCacheSize(int table_len) { … }
bool BackendImpl::InitStats() { … }
void BackendImpl::StoreStats() { … }
void BackendImpl::RestartCache(bool failure) { … }
void BackendImpl::PrepareForRestart() { … }
int BackendImpl::NewEntry(Addr address, scoped_refptr<EntryImpl>* entry) { … }
scoped_refptr<EntryImpl> BackendImpl::MatchEntry(const std::string& key,
uint32_t hash,
bool find_parent,
Addr entry_addr,
bool* match_error) { … }
bool BackendImpl::OpenFollowingEntryFromList(
Rankings::List list,
CacheRankingsBlock** from_entry,
scoped_refptr<EntryImpl>* next_entry) { … }
scoped_refptr<EntryImpl> BackendImpl::GetEnumeratedEntry(
CacheRankingsBlock* next,
Rankings::List list) { … }
scoped_refptr<EntryImpl> BackendImpl::ResurrectEntry(
scoped_refptr<EntryImpl> deleted_entry) { … }
void BackendImpl::DestroyInvalidEntry(EntryImpl* entry) { … }
void BackendImpl::AddStorageSize(int32_t bytes) { … }
void BackendImpl::SubstractStorageSize(int32_t bytes) { … }
void BackendImpl::IncreaseNumRefs() { … }
void BackendImpl::DecreaseNumRefs() { … }
void BackendImpl::IncreaseNumEntries() { … }
void BackendImpl::DecreaseNumEntries() { … }
void BackendImpl::LogStats() { … }
void BackendImpl::UpdateStats() { … }
void BackendImpl::UpgradeTo2_1() { … }
void BackendImpl::UpgradeTo3_0() { … }
bool BackendImpl::CheckIndex() { … }
int BackendImpl::CheckAllEntries() { … }
bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { … }
int BackendImpl::MaxBuffersSize() { … }
void BackendImpl::FlushForTesting() { … }
void BackendImpl::FlushAsynchronouslyForTesting(base::OnceClosure callback) { … }
}