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
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_CONTENT_CACHE_CACHE_FILE_CONTEXT_H_
#define CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_CONTENT_CACHE_CACHE_FILE_CONTEXT_H_
#include <functional>
#include <map>
#include <utility>
#include "base/files/file_path.h"
#include "base/time/time.h"
#include "chrome/browser/ash/file_system_provider/content_cache/local_fd.h"
#include "chrome/browser/ash/file_system_provider/opened_cloud_file.h"
namespace ash::file_system_provider {
// Helper to explain the "-1" that is used to denote an unknown ID.
inline constexpr int kUnknownId = -1;
// Context relating to a file that is cached on disk. Used to make decisions
// around evicting files from the cache (e.g. until N bytes have been evicted)
// and guard against multiple writers to a single file.
class CacheFileContext {
public:
// When repopulating the context on session startup with the file information
// that is already cached on disk, use the `bytes_on_disk`, `id` and
// `path_on_disk` fields. Otherwise leave the default values.
explicit CacheFileContext(
const std::string& version_tag,
int64_t bytes_on_disk = 0,
int64_t id = kUnknownId,
const base::FilePath& path_on_disk = base::FilePath());
CacheFileContext(CacheFileContext&&);
CacheFileContext(const CacheFileContext&) = delete;
CacheFileContext& operator=(const CacheFileContext&) = delete;
~CacheFileContext();
bool HasLocalFDs() const { return !open_fds_.empty(); }
bool CanGetLocalFD(const OpenedCloudFile& file) const;
LocalFD& GetLocalFD(const OpenedCloudFile& file,
scoped_refptr<base::SequencedTaskRunner> io_task_runner);
bool CloseLocalFD(int request_id) { return open_fds_.erase(request_id) == 1; }
int64_t bytes_on_disk() const { return bytes_on_disk_; }
void set_bytes_on_disk(int64_t bytes_on_disk) {
bytes_on_disk_ = bytes_on_disk;
}
base::Time accessed_time() const { return accessed_time_; }
void set_accessed_time(base::Time accessed_time) {
accessed_time_ = accessed_time;
}
const std::string& version_tag() const { return version_tag_; }
int64_t id() const { return id_; }
void set_id(int64_t id) { id_ = id; }
const base::FilePath& path_on_disk() const { return path_on_disk_; }
void set_path_on_disk(const base::FilePath& path_on_disk) {
path_on_disk_ = path_on_disk;
}
bool has_writer() const { return has_writer_; }
void set_has_writer(bool has_writer) { has_writer_ = has_writer; }
bool evicted() const { return evicted_; }
void set_evicted(bool evicted) { evicted_ = evicted; }
bool removal_in_progress() const { return removal_in_progress_; }
void set_removal_in_progress(bool removal_in_progress) {
removal_in_progress_ = removal_in_progress;
}
private:
// The number of contiguous bytes that are written to this file currently. If
// a file write is in progress, this might not represent the entire size of
// the file on disk.
int64_t bytes_on_disk_;
// The latest access time, cryptohome is mounted with MS_NOATIME so we need to
// keep track of this separately.
base::Time accessed_time_ = base::Time::Now();
// The version tag for this specific file. This is read-only as the version
// can never be changed without deleting the context for the file and
// replacing it with an updated version.
const std::string version_tag_;
// A unique ID associated with this file that is used to write the file on
// disk.
int64_t id_;
// The path of the cached file on disk.
base::FilePath path_on_disk_;
// True if there is an open writer to this file, multiple writers at
// disjoint offset ranges is currently not supported.
bool has_writer_ = false;
// Evicted items are scheduled to be removed from disk and the database, so
// any further use should be disallowed.
bool evicted_ = false;
// True if the removal of this item has started.
bool removal_in_progress_ = false;
// A map (keyed by request ID) that represents any open file descriptors for
// this specific file.
std::map<int, LocalFD> open_fds_;
};
using PathContextPair = std::pair<base::FilePath, CacheFileContext>;
} // namespace ash::file_system_provider
template <>
struct std::hash<ash::file_system_provider::CacheFileContext> {
// Enables the key to be retrieved from the std::pair that represents the
// key-value pair in the LRU cache.
constexpr const base::FilePath& operator()(
const ash::file_system_provider::PathContextPair& pair) {
return pair.first;
}
// Returns a hash for the std::pair to enable O(1) lookup in the
// base::HashingLRUCache (hashes the std::string representation of the
// base::FilePath key).
constexpr size_t operator()(
const ash::file_system_provider::PathContextPair& pair) const {
return std::hash<std::string>{}(pair.first.value());
}
};
#endif // CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_CONTENT_CACHE_CACHE_FILE_CONTEXT_H_
|