chromium/net/disk_cache/blockfile/backend_impl.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
#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[] =;

// Seems like ~240 MB correspond to less than 50k entries for 99% of the people.
// Note that the actual target is to keep the index table load factor under 55%
// for most users.
const int k64kEntriesStore =;
const int kBaseTableLen =;

// Avoid trimming the cache for the first 5 minutes (10 timer ticks).
const int kTrimDelay =;

int DesiredIndexTableLen(int32_t storage_size) {}

int MaxStorageSizeForTable(int table_len) {}

size_t GetIndexSize(int table_len) {}

// ------------------------------------------------------------------------

// Sets group for the current experiment. Returns false if the files should be
// discarded.
bool InitExperiment(disk_cache::IndexHeader* header, bool cache_created) {}

// A callback to perform final cleanup on the background thread.
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

// ------------------------------------------------------------------------

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() {}

// We use OpenNextEntryImpl to retrieve elements from the cache, until we get
// entries that are too old.
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  // NET_BUILD_STRESS_CACHE

// An entry may be linked on the DELETED list for a while after being doomed.
// This function is called when we want to remove it.
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() {}

// Previously this method was used to determine when to report histograms, so
// the logic is surprisingly convoluted.
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) {}

// ------------------------------------------------------------------------

// We just created a new file so we're going to write the header and set the
// file length to include the hash table (zero filled).
bool BackendImpl::CreateBackingStore(disk_cache::File* file) {}

bool BackendImpl::InitBackingStore(bool* file_created) {}

// The maximum cache size will be either set explicitly by the caller, or
// calculated by this code.
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) {}

// static
int BackendImpl::MaxBuffersSize() {}

void BackendImpl::FlushForTesting() {}

void BackendImpl::FlushAsynchronouslyForTesting(base::OnceClosure callback) {}

}  // namespace disk_cache