#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_
#include <stdint.h>
#include <memory>
#include <vector>
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/pickle.h"
#include "net/base/cache_type.h"
#include "net/base/net_export.h"
#include "net/disk_cache/simple/simple_backend_version.h"
#include "net/disk_cache/simple/simple_index.h"
namespace base {
class SequencedTaskRunner;
}
namespace disk_cache {
class BackendFileOperations;
class BackendFileOperationsFactory;
const uint64_t kSimpleIndexMagicNumber = UINT64_C(0x656e74657220796f);
struct NET_EXPORT_PRIVATE SimpleIndexLoadResult {
SimpleIndexLoadResult();
~SimpleIndexLoadResult();
void Reset();
bool did_load = false;
SimpleIndex::EntrySet entries;
SimpleIndex::IndexWriteToDiskReason index_write_reason =
SimpleIndex::INDEX_WRITE_REASON_MAX;
SimpleIndex::IndexInitMethod init_method;
bool flush_required = false;
};
class NET_EXPORT_PRIVATE SimpleIndexFile {
public:
class NET_EXPORT_PRIVATE IndexMetadata {
public:
IndexMetadata();
IndexMetadata(SimpleIndex::IndexWriteToDiskReason reason,
uint64_t entry_count,
uint64_t cache_size);
virtual void Serialize(base::Pickle* pickle) const;
bool Deserialize(base::PickleIterator* it);
bool CheckIndexMetadata();
SimpleIndex::IndexWriteToDiskReason reason() const { return reason_; }
uint64_t entry_count() const { return entry_count_; }
bool app_cache_has_trailer_prefetch_size() const { return version_ >= 9; }
private:
FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Basics);
FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Serialize);
FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8Format);
FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8FormatAppCache);
friend class V8IndexMetadataForTest;
uint64_t magic_number_ = kSimpleIndexMagicNumber;
uint32_t version_ = kSimpleIndexFileVersion;
SimpleIndex::IndexWriteToDiskReason reason_;
uint64_t entry_count_;
uint64_t cache_size_;
};
SimpleIndexFile(
scoped_refptr<base::SequencedTaskRunner> cache_runner,
scoped_refptr<BackendFileOperationsFactory> file_operations_factory,
net::CacheType cache_type,
const base::FilePath& cache_directory);
SimpleIndexFile(const SimpleIndexFile&) = delete;
SimpleIndexFile& operator=(const SimpleIndexFile&) = delete;
virtual ~SimpleIndexFile();
virtual void LoadIndexEntries(base::Time cache_last_modified,
base::OnceClosure callback,
SimpleIndexLoadResult* out_result);
virtual void WriteToDisk(net::CacheType cache_type,
SimpleIndex::IndexWriteToDiskReason reason,
const SimpleIndex::EntrySet& entry_set,
uint64_t cache_size,
base::OnceClosure callback);
private:
friend class WrappedSimpleIndexFile;
using EntryFileCallback =
base::RepeatingCallback<void(const base::FilePath&,
base::Time last_accessed,
base::Time last_modified,
int64_t size)>;
static const int kExtraSizeForMerge = 512;
static void SyncLoadIndexEntries(
std::unique_ptr<BackendFileOperations> file_operations,
net::CacheType cache_type,
base::Time cache_last_modified,
const base::FilePath& cache_directory,
const base::FilePath& index_file_path,
SimpleIndexLoadResult* out_result);
static void SyncLoadFromDisk(BackendFileOperations* file_operations,
net::CacheType cache_type,
const base::FilePath& index_filename,
base::Time* out_last_cache_seen_by_index,
SimpleIndexLoadResult* out_result);
static std::unique_ptr<base::Pickle> Serialize(
net::CacheType cache_type,
const SimpleIndexFile::IndexMetadata& index_metadata,
const SimpleIndex::EntrySet& entries);
static void SerializeFinalData(base::Time cache_modified,
base::Pickle* pickle);
static void Deserialize(net::CacheType cache_type,
base::span<const uint8_t> data,
base::Time* out_cache_last_modified,
SimpleIndexLoadResult* out_result);
static void SyncWriteToDisk(
std::unique_ptr<BackendFileOperations> file_operations,
net::CacheType cache_type,
const base::FilePath& cache_directory,
const base::FilePath& index_filename,
const base::FilePath& temp_index_filename,
std::unique_ptr<base::Pickle> pickle);
static void SyncRestoreFromDisk(BackendFileOperations* file_operations,
net::CacheType cache_type,
const base::FilePath& cache_directory,
const base::FilePath& index_file_path,
SimpleIndexLoadResult* out_result);
static bool LegacyIsIndexFileStale(BackendFileOperations* file_operations,
base::Time cache_last_modified,
const base::FilePath& index_file_path);
const scoped_refptr<base::SequencedTaskRunner> cache_runner_;
const scoped_refptr<BackendFileOperationsFactory> file_operations_factory_;
const net::CacheType cache_type_;
const base::FilePath cache_directory_;
const base::FilePath index_file_;
const base::FilePath temp_index_file_;
static const char kIndexDirectory[];
static const char kIndexFileName[];
static const char kTempIndexFileName[];
};
}
#endif