Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: storage/browser/blob/blob_memory_controller.h

Issue 2339933004: [BlobStorage] BlobMemoryController & tests (Closed)
Patch Set: Fixed windows bug! Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « storage/browser/blob/blob_data_item.h ('k') | storage/browser/blob/blob_memory_controller.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef STORAGE_BROWSER_BLOB_BLOB_MEMORY_CONTROLLER_H_
6 #define STORAGE_BROWSER_BLOB_BLOB_MEMORY_CONTROLLER_H_
7
8 #include <stdint.h>
9
10 #include <list>
11 #include <map>
12 #include <memory>
13 #include <string>
14 #include <unordered_map>
15 #include <unordered_set>
16 #include <utility>
17 #include <vector>
18
19 #include "base/callback.h"
20 #include "base/callback_helpers.h"
21 #include "base/containers/mru_cache.h"
22 #include "base/files/file.h"
23 #include "base/files/file_path.h"
24 #include "base/macros.h"
25 #include "base/memory/ref_counted.h"
26 #include "base/memory/weak_ptr.h"
27 #include "base/optional.h"
28 #include "base/time/time.h"
29 #include "storage/browser/storage_browser_export.h"
30 #include "storage/common/blob_storage/blob_storage_constants.h"
31
32 namespace base {
33 class TaskRunner;
34 }
35
36 namespace storage {
37 class DataElement;
38 class ShareableBlobDataItem;
39 class ShareableFileReference;
40
41 // This class's main responsibility is deciding how blob data gets stored.
42 // This encompasses:
43 // * Keeping track of memory & file quota,
44 // * How to transport the blob data from the renderer (DetermineStrategy),
45 // * Allocating memory & file quota (ReserveMemoryQuota, ReserveFileQuota)
46 // * Paging memory quota to disk when we're nearing our memory limit, and
47 // * Maintaining an LRU of memory items to choose candidates to page to disk
48 // (NotifyMemoryItemUsed).
49 // This class can only be interacted with on the IO thread.
50 class STORAGE_EXPORT BlobMemoryController {
51 public:
52 enum class Strategy {
53 // We don't have enough memory for this blob.
54 TOO_LARGE,
55 // There isn't any memory that needs transporting.
56 NONE_NEEDED,
57 // Transportation strategies.
58 IPC,
59 SHARED_MEMORY,
60 FILE
61 };
62
63 struct STORAGE_EXPORT FileCreationInfo {
64 FileCreationInfo();
65 ~FileCreationInfo();
66 FileCreationInfo(FileCreationInfo&& other);
67 FileCreationInfo& operator=(FileCreationInfo&&);
68
69 base::File::Error error = base::File::FILE_ERROR_FAILED;
70 base::File file;
71 scoped_refptr<base::TaskRunner> file_deletion_runner;
72 base::FilePath path;
73 scoped_refptr<ShareableFileReference> file_reference;
74 base::Time last_modified;
75 };
76
77 struct MemoryAllocation {
78 MemoryAllocation(base::WeakPtr<BlobMemoryController> controller,
79 uint64_t item_id,
80 size_t length);
81 ~MemoryAllocation();
82
83 private:
84 base::WeakPtr<BlobMemoryController> controller;
85 uint64_t item_id;
86 size_t length;
87
88 DISALLOW_COPY_AND_ASSIGN(MemoryAllocation);
89 };
90
91 class QuotaAllocationTask {
92 public:
93 // Operation is cancelled and the callback will NOT be called. This object
94 // will be destroyed by this call.
95 virtual void Cancel() = 0;
96
97 protected:
98 virtual ~QuotaAllocationTask();
99 };
100
101 // The bool argument is true if we successfully received memory quota.
102 using MemoryQuotaRequestCallback = base::Callback<void(bool)>;
103 // The bool argument is true if we successfully received file quota, and the
104 // vector argument provides the file info.
105 using FileQuotaRequestCallback =
106 base::Callback<void(bool, std::vector<FileCreationInfo>)>;
107
108 // We enable file paging if |file_runner| isn't a nullptr.
109 BlobMemoryController(const base::FilePath& storage_directory,
110 scoped_refptr<base::TaskRunner> file_runner);
111 ~BlobMemoryController();
112
113 // Disables file paging. This cancels all pending file creations and paging
114 // operations. Reason is recorded in UMA.
115 void DisableFilePaging(base::File::Error reason);
116
117 bool file_paging_enabled() const { return file_paging_enabled_; }
118
119 // Returns the strategy the transportation layer should use to transport the
120 // given memory. |preemptive_transported_bytes| are the number of transport
121 // bytes that are already populated for us, so we don't haved to request them
122 // from the renderer.
123 Strategy DetermineStrategy(size_t preemptive_transported_bytes,
124 uint64_t total_transportation_bytes) const;
125
126 // Checks to see if we can reserve quota (disk or memory) for the given size.
127 bool CanReserveQuota(uint64_t size) const;
128
129 // Reserves quota for the given |unreserved_memory_items|. The items must be
130 // bytes items in QUOTA_NEEDED state which we change to QUOTA_REQUESTED.
131 // After we reserve memory quota we change their state to QUOTA_GRANTED, set
132 // the 'memory_allocation' on the item, and call |done_callback|. This can
133 // happen synchronously.
134 // Returns a task handle if the request is asynchronous for cancellation.
135 // NOTE: We don't inspect quota limits and assume the user checked
136 // CanReserveQuota before calling this.
137 base::WeakPtr<QuotaAllocationTask> ReserveMemoryQuota(
138 std::vector<scoped_refptr<ShareableBlobDataItem>> unreserved_memory_items,
139 const MemoryQuotaRequestCallback& done_callback);
140
141 // Reserves quota for the given |unreserved_file_items|. The items must be
142 // temporary file items (BlobDataBuilder::IsTemporaryFileItem returns true) in
143 // QUOTA_NEEDED state, which we change to QUOTA_REQUESTED. After we reserve
144 // file quota we change their state to QUOTA_GRANTED and call
145 // |done_callback|.
146 // Returns a task handle for cancellation.
147 // NOTE: We don't inspect quota limits and assume the user checked
148 // CanReserveQuota before calling this.
149 base::WeakPtr<QuotaAllocationTask> ReserveFileQuota(
150 std::vector<scoped_refptr<ShareableBlobDataItem>> unreserved_file_items,
151 const FileQuotaRequestCallback& done_callback);
152
153 // Called when initially populated or upon later access.
154 void NotifyMemoryItemsUsed(
155 std::vector<scoped_refptr<ShareableBlobDataItem>>& items);
156
157 size_t memory_usage() const { return blob_memory_used_; }
158 uint64_t disk_usage() const { return disk_used_; }
159
160 const BlobStorageLimits& limits() const { return limits_; }
161 void set_limits_for_testing(const BlobStorageLimits& limits) {
162 limits_ = limits;
163 }
164
165 private:
166 class FileQuotaAllocationTask;
167 class MemoryQuotaAllocationTask;
168
169 using PendingMemoryQuotaTaskList =
170 std::list<std::unique_ptr<MemoryQuotaAllocationTask>>;
171 using PendingFileQuotaTaskList =
172 std::list<std::unique_ptr<FileQuotaAllocationTask>>;
173
174 base::WeakPtr<QuotaAllocationTask> AppendMemoryTask(
175 uint64_t total_bytes_needed,
176 std::vector<scoped_refptr<ShareableBlobDataItem>> unreserved_memory_items,
177 const MemoryQuotaRequestCallback& done_callback);
178
179 void MaybeGrantPendingMemoryRequests();
180
181 size_t CollectItemsForEviction(
182 std::vector<scoped_refptr<ShareableBlobDataItem>>* output);
183
184 // Schedule paging until our memory usage is below our memory limit.
185 void MaybeScheduleEvictionUntilSystemHealthy();
186
187 // Called when we've completed evicting a list of items to disk. This is where
188 // we swap the bytes items for file items, and update our bookkeeping.
189 void OnEvictionComplete(
190 scoped_refptr<ShareableFileReference> file_reference,
191 std::vector<scoped_refptr<ShareableBlobDataItem>> items,
192 size_t total_items_size,
193 FileCreationInfo result);
194
195 size_t GetAvailableMemoryForBlobs() const;
196 uint64_t GetAvailableFileSpaceForBlobs() const;
197
198 void GrantMemoryAllocations(
199 std::vector<scoped_refptr<ShareableBlobDataItem>>* items,
200 size_t total_bytes);
201 void RevokeMemoryAllocation(uint64_t item_id, size_t length);
202
203 // This is registered as a callback for file deletions on the file reference
204 // of our paging files. We decrement the disk space used.
205 void OnBlobFileDelete(uint64_t size, const base::FilePath& path);
206
207 base::FilePath GenerateNextPageFileName();
208
209 // This records diagnostic counters of our memory quotas. Called when usage
210 // changes.
211 void RecordTracingCounters() const;
212
213 BlobStorageLimits limits_;
214
215 // Memory bookkeeping. These numbers are all disjoint.
216 // This is the amount of memory we're using for blobs in RAM, including the
217 // in_flight_memory_used_.
218 size_t blob_memory_used_ = 0;
219 // This is memory we're temporarily using while we try to write blob items to
220 // disk.
221 size_t in_flight_memory_used_ = 0;
222 // This is the amount of memory we're using on disk.
223 uint64_t disk_used_ = 0;
224
225 // State for GenerateNextPageFileName.
226 uint64_t current_file_num_ = 0;
227
228 size_t pending_memory_quota_total_size_ = 0;
229 PendingMemoryQuotaTaskList pending_memory_quota_tasks_;
230 PendingFileQuotaTaskList pending_file_quota_tasks_;
231
232 int pending_evictions_ = 0;
233
234 bool file_paging_enabled_ = false;
235 base::FilePath blob_storage_dir_;
236 scoped_refptr<base::TaskRunner> file_runner_;
237
238 // Lifetime of the ShareableBlobDataItem objects is handled externally in the
239 // BlobStorageContext class.
240 base::MRUCache<uint64_t, ShareableBlobDataItem*> populated_memory_items_;
241 size_t populated_memory_items_bytes_ = 0;
242 // We need to keep track of items currently being paged to disk so that if
243 // another blob successfully grabs a ref, we can prevent it from adding the
244 // item to the recent_item_cache_ above.
245 std::unordered_set<uint64_t> items_paging_to_file_;
246
247 base::WeakPtrFactory<BlobMemoryController> weak_factory_;
248
249 DISALLOW_COPY_AND_ASSIGN(BlobMemoryController);
250 };
251 } // namespace storage
252 #endif // STORAGE_BROWSER_BLOB_BLOB_MEMORY_CONTROLLER_H_
OLDNEW
« no previous file with comments | « storage/browser/blob/blob_data_item.h ('k') | storage/browser/blob/blob_memory_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698