File: content_cache_impl.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (170 lines) | stat: -rw-r--r-- 7,473 bytes parent folder | download | duplicates (6)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// 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_CONTENT_CACHE_IMPL_H_
#define CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_CONTENT_CACHE_CONTENT_CACHE_IMPL_H_

#include "base/callback_list.h"
#include "base/files/file_error_or.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "base/threading/sequence_bound.h"
#include "chrome/browser/ash/file_system_provider/content_cache/content_cache.h"
#include "chrome/browser/ash/file_system_provider/content_cache/content_lru_cache.h"
#include "chrome/browser/ash/file_system_provider/content_cache/context_database.h"
#include "chrome/browser/ash/file_system_provider/content_cache/local_fd.h"
#include "chrome/browser/ash/file_system_provider/opened_cloud_file.h"
#include "chrome/browser/ash/file_system_provider/provided_file_system_interface.h"

namespace ash::file_system_provider {

// The content cache for every mounted FSP. This will serve as the single point
// of orchestration between the LRU cache and the disk persistence layer.
class ContentCacheImpl : public ContentCache {
 public:
  ContentCacheImpl(const base::FilePath& root_dir,
                   BoundContextDatabase context_db,
                   size_t max_cache_size);

  ContentCacheImpl(const ContentCacheImpl&) = delete;
  ContentCacheImpl& operator=(const ContentCacheImpl&) = delete;

  ~ContentCacheImpl() override;

  // Creates a `ContentCache` with the concrete implementation.
  static std::unique_ptr<ContentCache> Create(const base::FilePath& root_dir,
                                              BoundContextDatabase context_db,
                                              size_t max_cache_items = 500);

  void SetMaxCacheItems(size_t max_cache_items) override;

  void ReadBytes(
      const OpenedCloudFile& file,
      scoped_refptr<net::IOBuffer> buffer,
      int64_t offset,
      int length,
      ProvidedFileSystemInterface::ReadChunkReceivedCallback callback) override;

  void WriteBytes(const OpenedCloudFile& file,
                  scoped_refptr<net::IOBuffer> buffer,
                  int64_t offset,
                  int length,
                  FileErrorCallback callback) override;

  void CloseFile(const OpenedCloudFile& file) override;

  void LoadFromDisk(base::OnceClosure callback) override;

  std::vector<base::FilePath> GetCachedFilePaths() override;

  void Notify(ProvidedFileSystemObserver::Changes& changes) override;

  void ObservedVersionTag(const base::FilePath& entry_path,
                          const std::string& version_tag) override;

  void Evict(const base::FilePath& file_path) override;

  void AddObserver(ContentCache::Observer* observer) override;
  void RemoveObserver(ContentCache::Observer* observer) override;

 private:
  void OnBytesRead(
      const base::FilePath& file_path,
      ProvidedFileSystemInterface::ReadChunkReceivedCallback callback,
      FileErrorOrBytesRead error_or_bytes_read);

  // Called when the database returns an ID that will be used as the file name
  // to write the bytes to disk.
  void OnFileIdGenerated(const OpenedCloudFile& file,
                         scoped_refptr<net::IOBuffer> buffer,
                         int64_t offset,
                         int length,
                         FileErrorCallback callback,
                         std::unique_ptr<int64_t> inserted_id,
                         bool item_add_success);

  void WriteBytesToDisk(const OpenedCloudFile& file,
                        scoped_refptr<net::IOBuffer> buffer,
                        int64_t offset,
                        int length,
                        FileErrorCallback callback);

  void OnBytesWritten(const base::FilePath& file_path,
                      int64_t offset,
                      int length,
                      FileErrorCallback callback,
                      base::File::Error result);

  // Invoked in the flow of `LoadFromDisk` once all the files have been
  // discovered in the FSP content cache mount directory. The results are keyed
  // by the id (i.e. the file name on disk) with a corresponding
  // `CacheFileContext` containing the total bytes on disk populated.
  void GotFilesFromDisk(base::OnceClosure callback,
                        std::map<int, int64_t> files_on_disk);

  // Invoked in the flow of `LoadFromDisk` once all the items from the database
  // have been retrieved.
  void GotItemsFromContextDatabase(base::OnceClosure callback,
                                   std::map<int, int64_t> files_on_disk,
                                   ContextDatabase::IdToItemMap items);

  // Invoked in the flow of `LoadFromDisk` once all the orphaned files (from
  // disk OR in the DB) have been removed. The `success` vector contains 2 bools
  // indicating the success of the db removal and disk removal (respectively).
  void OnStaleItemsPruned(base::OnceClosure callback,
                          std::vector<bool> prune_success);

  // Removes items individually from the disk and the lru_cache. Removes items
  // in bulk from the database.
  void RemoveItems(const std::vector<base::FilePath>& fsp_paths);

  // Removes items in bulk from the database.
  void RemoveItemsFromDatabase(std::vector<int64_t>& item_ids);

  void OnItemsRemovedFromDatabase(size_t number_of_items, bool success);

  // Removes an item with `path_on_disk` from the disk. Upon success, removes
  // item with `fsp_path` from the lru cache.
  void RemoveItemFromDisk(const base::FilePath& path_on_disk,
                          const base::FilePath& fsp_path);

  void OnItemRemovedFromDisk(const base::FilePath& fsp_path, bool success);

  // Evict the items with `file_paths`. The items are still accessible to
  // current FSP requests but inaccessible to new FSP requests. All items that
  // aren't being accessed by current FSP requests will be removed from the disk
  // and the database. Each remaining item will be removed once the last FSP
  // request for the item completes with `CloseFile()`.
  void EvictItems(const std::vector<base::FilePath>& file_paths);

  // The cache has maximum bounds on the number of items available. In the event
  // this boundary is exceeded, excess items should be evicted. There may
  // already be evicted items still in the cache (yet to be removed). The
  // remaining items to evict will be the least-recently used items.
  // TODO(b/330602540): Update the logic to also evict items when the maximum
  // size threshold has been reached.
  void EvictExcessItems();

  // Generates the absolute path on disk from the supplied `item_id`.
  const base::FilePath GetPathOnDiskFromId(int64_t item_id);

  SEQUENCE_CHECKER(sequence_checker_);

  const base::FilePath root_dir_;
  ContentLRUCache lru_cache_ GUARDED_BY_CONTEXT(sequence_checker_);

  scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
  BoundContextDatabase context_db_;

  size_t max_cache_items_;
  // Number of evicted items that will be removed on the next removal cycle.
  size_t evicted_cache_items_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;

  base::ObserverList<ContentCache::Observer> observers_;
  base::WeakPtrFactory<ContentCacheImpl> weak_ptr_factory_{this};
};

}  // namespace ash::file_system_provider

#endif  // CHROME_BROWSER_ASH_FILE_SYSTEM_PROVIDER_CONTENT_CACHE_CONTENT_CACHE_IMPL_H_