blob: 6928c01bd718c60020fd3475fe354dd380379723 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_DISK_CACHE_SQL_SQL_PERSISTENT_STORE_H_
#define NET_DISK_CACHE_SQL_SQL_PERSISTENT_STORE_H_
#include <optional>
#include "base/functional/callback_forward.h"
#include "base/memory/scoped_refptr.h"
#include "base/time/time.h"
#include "base/types/expected.h"
#include "base/unguessable_token.h"
#include "net/base/cache_type.h"
#include "net/base/net_export.h"
#include "net/disk_cache/buildflags.h"
#include "net/disk_cache/sql/cache_entry_key.h"
// This backend is experimental and only available when the build flag is set.
static_assert(BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND));
namespace base {
class FilePath;
class SequencedTaskRunner;
} // namespace base
namespace net {
class GrowableIOBuffer;
} // namespace net
namespace disk_cache {
// This class manages the persistence layer for the SQL-based disk cache.
// It handles all database operations, including initialization, schema
// management, and data access. All database I/O is performed asynchronously on
// a provided background task runner.
class NET_EXPORT_PRIVATE SqlPersistentStore {
public:
// Represents the error of SqlPersistentStore operation.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// LINT.IfChange(SqlDiskCacheStoreError)
enum class Error {
kOk = 0,
kFailedToCreateDirectory = 1,
kFailedToOpenDatabase = 2,
kFailedToRazeIncompatibleDatabase = 3,
kFailedToStartTransaction = 4,
kFailedToCommitTransaction = 5,
kFailedToInitializeMetaTable = 6,
kFailedToInitializeSchema = 7,
kFailedToSetEntryCountMetadata = 8,
kFailedToSetTotalSizeMetadata = 9,
kFailedToExecute = 10,
kInvalidData = 11,
kAlreadyExists = 12,
kNotFound = 13,
kMaxValue = kNotFound
};
// LINT.ThenChange(//tools/metrics/histograms/metadata/net/enums.xml:SqlDiskCacheStoreError)
// Holds information about a specific cache entry.
struct NET_EXPORT_PRIVATE EntryInfo {
EntryInfo();
~EntryInfo();
EntryInfo(EntryInfo&&);
EntryInfo& operator=(EntryInfo&&);
// A unique identifier for this entry instance, used for safe data access.
base::UnguessableToken token;
// The last time this entry was used.
base::Time last_used;
// The total size of the entry's body (all data streams).
int64_t body_end = 0;
// The entry's header data (stream 0).
scoped_refptr<net::GrowableIOBuffer> head;
// True if the entry was opened, false if it was newly created.
bool opened = false;
};
using ErrorCallback = base::OnceCallback<void(Error)>;
using Int32Callback = base::OnceCallback<void(int32_t)>;
using Int64Callback = base::OnceCallback<void(int64_t)>;
using EntryInfoOrError = base::expected<EntryInfo, Error>;
using EntryInfoOrErrorCallback = base::OnceCallback<void(EntryInfoOrError)>;
using OptionalEntryInfoOrError =
base::expected<std::optional<EntryInfo>, Error>;
using OptionalEntryInfoOrErrorCallback =
base::OnceCallback<void(OptionalEntryInfoOrError)>;
// Creates a new instance of the persistent store. The returned object must be
// initialized by calling `Initialize()`. This function never returns a null
// pointer.
static std::unique_ptr<SqlPersistentStore> Create(
const base::FilePath& path,
int64_t max_bytes,
net::CacheType type,
const scoped_refptr<base::SequencedTaskRunner>& background_task_runner);
virtual ~SqlPersistentStore() = default;
SqlPersistentStore(const SqlPersistentStore&) = delete;
SqlPersistentStore& operator=(const SqlPersistentStore&) = delete;
// Initializes the store. `callback` will be invoked upon completion.
virtual void Initialize(ErrorCallback callback) = 0;
// Opens an entry with the given `key`. If the entry does not exist, it is
// created. `callback` is invoked with the entry information on success or
// an error code on failure.
virtual void OpenOrCreateEntry(const CacheEntryKey& key,
EntryInfoOrErrorCallback callback) = 0;
// Opens an existing entry with the given `key`.
// The `callback` is invoked with the entry's information on success. If the
// entry does not exist, the `callback` is invoked with a `kNotFound` error.
virtual void OpenEntry(const CacheEntryKey& key,
OptionalEntryInfoOrErrorCallback callback) = 0;
// Creates a new entry with the given `key`.
// The `callback` is invoked with the new entry's information on success. If
// an entry with this key already exists, the callback is invoked with a
// `kAlreadyExists` error.
virtual void CreateEntry(const CacheEntryKey& key,
EntryInfoOrErrorCallback callback) = 0;
// Marks an entry for future deletion. When an entry is "doomed", it is
// immediately removed from the cache's entry count and total size, but its
// data remains on disk until `DeleteDoomedEntry()` is called. The `token`
// ensures that only the correct instance of an entry is doomed.
virtual void DoomEntry(const CacheEntryKey& key,
const base::UnguessableToken& token,
ErrorCallback callback) = 0;
// Physically deletes an entry that has been previously marked as doomed. This
// operation completes the deletion process by removing the entry's data from
// the database. The `token` ensures that only a specific, doomed instance of
// the entry is deleted.
virtual void DeleteDoomedEntry(const CacheEntryKey& key,
const base::UnguessableToken& token,
ErrorCallback callback) = 0;
// Deletes a "live" entry, i.e., an entry whose `doomed` flag is not set.
// This is for use for entries which are not open; open entries should have
// `DoomEntry()` called, and then `DeleteDoomedEntry()` once they're no longer
// in used.
virtual void DeleteLiveEntry(const CacheEntryKey& key,
ErrorCallback callback) = 0;
// Deletes all entries from the cache. `callback` is invoked on completion.
virtual void DeleteAllEntries(ErrorCallback callback) = 0;
// The maximum size of an individual cache entry's data stream.
virtual int64_t MaxFileSize() const = 0;
// The maximum total size of the cache.
virtual int64_t MaxSize() const = 0;
// Asynchronously retrieves the count of entries.
virtual void GetEntryCount(Int32Callback callback) const = 0;
// Asynchronously retrieves the total size of all entries.
virtual void GetSizeOfAllEntries(Int64Callback callback) const = 0;
protected:
SqlPersistentStore() = default;
};
} // namespace disk_cache
#endif // NET_DISK_CACHE_SQL_SQL_PERSISTENT_STORE_H_