1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// 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 COMPONENTS_PERSISTENT_CACHE_BACKEND_PARAMS_MANAGER_H_
#define COMPONENTS_PERSISTENT_CACHE_BACKEND_PARAMS_MANAGER_H_
#include <type_traits>
#include <unordered_map>
#include "base/component_export.h"
#include "base/containers/lru_cache.h"
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/hash/hash.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "components/persistent_cache/backend_params.h"
namespace persistent_cache {
struct FootprintReductionResult {
int64_t current_footprint = 0;
int64_t number_of_bytes_deleted = 0;
};
// Use to retrieve or create BackendParams to open a PersistentCache. Existing
// params are cached so that they can be retrieved synchronously when possible.
//
// Example:
// BackendParamsManager params_manager(GetPath());
// params_manager.GetParamsSyncOrCreateAsync(BackendType::kSqlite, "key",
// AccessRights::kReadOnly,
// std::move(callback));
// // `callback` called synchronously and result can be used right away.
// // ... or
// // `callback` will be invoked asynchronously to return result.
//
class COMPONENT_EXPORT(PERSISTENT_CACHE) BackendParamsManager {
public:
enum class AccessRights { kReadonly, kReadWrite };
// `top_directory` is the where BackendParamsManager will try to find existing
// files and create new ones.
explicit BackendParamsManager(base::FilePath top_directory);
~BackendParamsManager();
using CompletedCallback = base::OnceCallback<void(const BackendParams&)>;
// Use to get backend params matching parameters directly or through
// `callback`. An invalid BackendParams instance is returned if `key` does
// not respect restrictions. Keys used in this class should be as short as
// possible to minimize the risk of them being too long to be used in a file
// path. Not all characters are allowed. See
// `GetAllAllowedCharactersInKeysForTesting`.
void GetParamsSyncOrCreateAsync(BackendType backend_type,
const std::string& key,
AccessRights access_rights,
CompletedCallback callback);
BackendParams GetOrCreateParamsSync(BackendType backend_type,
const std::string& key,
AccessRights access_rights);
// Delete all managed files.
void DeleteAllFiles();
// Use to reduce the total size of files on disk until it's equal or smaller
// than `target_footprint`. Use when enforcing a quota or proactively saving
// space. If the goal is to get rid of all files use `DeleteAllFiles()`
// instead. Returns the number of bytes deleted.
FootprintReductionResult BringDownTotalFootprintOfFiles(
int64_t target_footprint);
// Use to get a string containing all characters supported in keys.
static std::string GetAllAllowedCharactersInKeysForTesting();
private:
FRIEND_TEST_ALL_PREFIXES(BackendParamsManager, InvalidCharactersHandled);
FRIEND_TEST_ALL_PREFIXES(BackendParamsManager, KeyToFileName);
FRIEND_TEST_ALL_PREFIXES(BackendParamsManager, KeyToFileNameIsReversible);
// Function that simplifies a key string into a form suitable to be used as a
// file name by this class. The function also takes care of lightly
// obfuscating the value. This is not a security measure but more a way to
// underline the fact that the files are not meant to be discovered and
// modified by third parties.
//
// On Windows some file names are reserved
// (https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#file-and-directory-names).
// As such the result of this function should always be used by appending a
// file extension as provided by this class to avoid using problems.
static std::string FileNameFromKey(const std::string& key);
// Inverse of `FileNameFromKey`. Will return an empty string on an invalid
// filename which needs to be handled.
static std::string KeyFromFileName(const std::string& key);
struct BackendParamsKey {
BackendType backend_type;
std::string key;
};
struct BackendParamsKeyHash {
BackendParamsKeyHash() = default;
~BackendParamsKeyHash() = default;
std::size_t operator()(const BackendParamsKey& k) const {
size_t hash = 0;
return base::HashCombine(hash, k.backend_type, k.key);
}
};
struct BackendParamsKeyEqual {
bool operator()(const BackendParamsKey& lhs,
const BackendParamsKey& rhs) const {
return lhs.backend_type == rhs.backend_type && lhs.key == rhs.key;
}
};
static BackendParams CreateParamsSync(base::FilePath directory,
BackendType backend_type,
const std::string& filename,
AccessRights access_rights);
// Saves params for later retrieval.
void SaveParams(const std::string& key,
CompletedCallback callback,
BackendParams backend_params);
base::HashingLRUCache<BackendParamsKey,
BackendParams,
BackendParamsKeyHash,
BackendParamsKeyEqual>
backend_params_map_ GUARDED_BY_CONTEXT(sequence_checker_);
const base::FilePath top_directory_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<BackendParamsManager> weak_factory_{this};
};
} // namespace persistent_cache
#endif // COMPONENTS_PERSISTENT_CACHE_BACKEND_PARAMS_MANAGER_H_
|