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

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

Issue 2055053003: [BlobAsync] Disk support for blob storage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed layout tests, cleaned up test visibility Created 4 years, 5 months 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
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 <algorithm>
11 #include <list>
12 #include <map>
13 #include <string>
14 #include <utility>
15 #include <vector>
16
17 #include "base/callback.h"
18 #include "base/containers/mru_cache.h"
19 #include "base/files/file.h"
20 #include "base/files/file_path.h"
21 #include "base/macros.h"
22 #include "base/memory/ref_counted.h"
23 #include "base/memory/weak_ptr.h"
24 #include "base/optional.h"
25 #include "base/time/time.h"
26 #include "storage/browser/storage_browser_export.h"
27 #include "storage/common/blob_storage/blob_storage_constants.h"
28
29 namespace base {
30 class TaskRunner;
31 }
32
33 namespace storage {
34 class DataElement;
35 class ShareableBlobDataItem;
36 class ShareableFileReference;
37
38 // This class is responsible for:
39 // * keeping track of all memory quotas & limits,
40 // * notifying us when we can allocate 'X' amount of quota in memory,
41 // * creating temporary files for the blob system, and
42 // * paging old blob items to disk.
43 class STORAGE_EXPORT BlobMemoryController {
44 public:
45 enum class MemoryStrategyResult {
46 // We don't have enough memory for this blob.
47 TOO_LARGE,
48 // There isn't any memory that needs transporting.
49 NONE_NEEDED,
50 // Transportation strategies.
51 IPC,
52 SHARED_MEMORY,
53 FILE
54 };
55 using PendingBlobConstructionList =
56 std::list<std::pair<size_t, base::Callback<void(bool)>>>;
57 using PendingConstructionEntry = PendingBlobConstructionList::iterator;
58
59 struct FileCreationInfo {
60 FileCreationInfo();
61 ~FileCreationInfo();
62 FileCreationInfo(FileCreationInfo&& other);
63 FileCreationInfo& operator=(FileCreationInfo&&);
64
65 base::File::Error error = base::File::FILE_ERROR_FAILED;
66 scoped_refptr<ShareableFileReference> file_reference;
67 base::File file;
68 base::Time last_modified;
69 };
70
71 BlobMemoryController();
72 virtual ~BlobMemoryController();
73
74 void EnableDisk(const base::FilePath& storage_directory,
75 scoped_refptr<base::TaskRunner> file_runner);
76
77 // Disables the disk. This cancels all pending file creations and paging
78 // operations.
79 void DisableDisk();
80
81 bool disk_enabled() const { return disk_enabled_; }
82
83 // Returns if the data in the descriptions is good data (not a bad IPC).
84 bool DecideBlobTransportationMemoryStrategy(
85 const std::vector<DataElement>& descriptions,
86 uint64_t* total_bytes,
87 MemoryStrategyResult* result) const;
88
89 // Creates a temporary file that we store in our blob temporary directory. The
90 // lifetime of the file is tied to the file_reference. This method 'allocates'
91 // the disk memory right away.
92 // NOTE: We assume the user checked CanFitInSystem before this, as we don't
93 // inspect quotas.
94 void CreateTemporaryFile(
95 uint64_t size_bytes,
96 const base::Callback<void(FileCreationInfo)>& file_callback);
97
98 void FreeMemory(size_t memory_size_bytes);
99
100 // Checks to see if the given size can fit in the system.
101 bool CanFitInSystem(uint64_t size) const;
102
103 // This method 'allocates' memory for the user, and we notify the caller when
104 // a blob of the given size can be stored in our blob system. If the returned
105 // entry is not present, that means the blob can fit right away and the
106 // callback won't be called. If we return a pending entry, then the memory
107 // isn't 'allocated' until |can_request| is called with true. IF the argument
108 // is false then there was an error and the new blob needs to be broken.
109 // NOTE: We assume the user checked CanFitInSystem before this, as we don't
110 // inspect quotas.
111 base::Optional<PendingConstructionEntry> NotifyWhenMemoryCanPopulated(
112 size_t memory_size_bytes,
113 const base::Callback<void(bool)>& can_request);
114
115 // If we no longer need memory requsted from NotifyWhenMemoryCanPopulated
116 // before |can_request| has been called above, you can call this method to
117 // correctly free the requested memory.
118 void RemovePendingConstructionEntry(const PendingConstructionEntry& entry);
119
120 // This updates the given item in our LRU lookup table.
121 void UpdateBlobItemInRecents(ShareableBlobDataItem* item);
122
123 // This removes the given item from our LRU lookup table.
124 void RemoveBlobItemInRecents(const ShareableBlobDataItem& item);
125
126 size_t memory_usage() const {
127 return blob_memory_used_ + in_flight_memory_used_;
128 }
129 uint64_t disk_usage() const { return disk_used_; }
130
131 size_t max_ipc_memory_size() const { return max_ipc_memory_size_; }
132 size_t max_shared_memory_size() const { return max_shared_memory_size_; }
133 size_t max_blob_in_memory_size() const { return max_blob_in_memory_size_; }
134 uint64_t max_blob_disk_space() const { return max_blob_disk_space_; }
135 size_t in_flight_space() const { return in_flight_space_; }
136 uint64_t min_page_file_size() const { return min_page_file_size_; }
137 uint64_t max_file_size() const { return max_file_size_; }
138
139 void SetMemoryConstantsForTesting(size_t max_ipc_memory_size,
140 size_t max_shared_memory_size,
141 size_t max_blob_in_memory_size,
142 uint64_t max_blob_disk_space,
143 size_t in_flight_space,
144 uint64_t min_page_file_size,
145 uint64_t max_file_size) {
146 max_ipc_memory_size_ = max_ipc_memory_size;
147 max_shared_memory_size_ = max_shared_memory_size;
148 max_blob_in_memory_size_ = max_blob_in_memory_size;
149 max_blob_disk_space_ = max_blob_disk_space;
150 in_flight_space_ = in_flight_space;
151 min_page_file_size_ = min_page_file_size;
152 max_file_size_ = max_file_size;
153 }
154
155 private:
156 // We add a delete callback to the file reference to decrement our disk usage.
157 void OnCreateFile(uint64_t file_size,
158 const base::Callback<void(FileCreationInfo)>& done,
159 FileCreationInfo result);
160
161 void MaybeScheduleWaitingBlobs();
162
163 bool HasEnoughMemoryToPage() {
164 return recent_item_cache_bytes_ >= min_page_file_size_;
165 }
166
167 // We schedule paging for all memory over our in memory limit, including
168 // any memory waiting to be allocated. We appropriately increment/decrement
169 // the disk, memory, and in flight counts.
170 void MaybeSchedulePagingUntilSystemHealthy();
171
172 // Called when we've completed paging a list of items
173 void OnPagingComplete(
174 std::unique_ptr<std::vector<scoped_refptr<ShareableBlobDataItem>>> items,
175 size_t total_items_size,
176 FileCreationInfo result);
177
178 void RecordTracingCounters();
179
180 size_t GetAvailableMemoryForBlobs() const;
181 uint64_t GetAvailableDiskSpaceForBlobs() const;
182
183 // We decrement the disk space used.
184 void OnBlobFileDelete(uint64_t size, const base::FilePath& path);
185
186 // Memory bookkeeping. These numbers are all disjoint.
187 // This is the amount of memory we're using for blobs in RAM.
188 size_t blob_memory_used_ = 0;
189 // This is memory we're temporarily using while we try to write blob items to
190 // disk.
191 size_t in_flight_memory_used_ = 0;
192 // This is the amount of memory we're using on disk.
193 uint64_t disk_used_ = 0;
194
195 size_t pending_pagings_ = 0;
196 PendingBlobConstructionList blobs_waiting_for_paging_;
197 size_t blobs_waiting_for_paging_size_ = 0;
198
199 scoped_refptr<base::TaskRunner> file_runner_;
200
201 // Constants.
202 // TODO(dmurph): consolidate these into a struct.
203 // This is the maximum amount of memory we can send in an IPC.
204 size_t max_ipc_memory_size_ = kBlobStorageIPCThresholdBytes;
205 // This is the maximum size of a shared memory handle.
206 size_t max_shared_memory_size_ = kBlobStorageMaxSharedMemoryBytes;
207 // This is the memory we can allocated towards blobs stored in RAM.
208 size_t max_blob_in_memory_size_ = kBlobStorageMaxBlobMemorySpace;
209 // This is the maximum amount of disk space we can use.
210 uint64_t max_blob_disk_space_ = kBlobStorageMaxDiskSpace;
211 // This is the maximum amount of memory we can temporarily allocate towards
212 // blob items that we're currently writing to disk.
213 size_t in_flight_space_ = kBlobStorageInFlightSpace;
214 // This is the minimum file size we can use when paging blob items to disk.
215 // We combine items until we reach at least this size.
216 uint64_t min_page_file_size_ = kBlobStorageMinFileSizeBytes;
217 // This is the maximum file size we can create. We use this is
218 // BlobAsyncTransportHost to segment large blobs, and then we create the files
219 // using CreateTemporaryFile.
220 uint64_t max_file_size_ = kBlobStorageMaxFileSizeBytes;
221
222 bool disk_enabled_ = false;
223 base::FilePath blob_storage_dir_;
224 uint64_t current_file_num_ = 0;
225
226 // Lifetime of the ShareableBlobDataItem objects is handled externally in the
227 // BlobStorageContext class.
228 base::MRUCache<uint64_t, ShareableBlobDataItem*> recent_item_cache_;
229 size_t recent_item_cache_bytes_ = 0;
230
231 base::WeakPtrFactory<BlobMemoryController> ptr_factory_;
232
233 DISALLOW_COPY_AND_ASSIGN(BlobMemoryController);
234 };
235 } // namespace storage
236 #endif // STORAGE_BROWSER_BLOB_BLOB_MEMORY_CONTROLLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698