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

Side by Side Diff: storage/browser/blob/blob_async_transport_strategy.cc

Issue 1528233004: [Blob] Blob paging to disk patch. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@blob-disk1
Patch Set: Created 5 years 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 6
7 #include "base/numerics/safe_math.h" 7 #include "base/numerics/safe_math.h"
8 #include "storage/browser/blob/blob_async_transport_strategy.h" 8 #include "storage/browser/blob/blob_async_transport_strategy.h"
9 #include "storage/common/blob_storage/blob_storage_constants.h" 9 #include "storage/common/blob_storage/blob_storage_constants.h"
10 10
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 segment_offset += memory_writing; 183 segment_offset += memory_writing;
184 element_offset += memory_writing; 184 element_offset += memory_writing;
185 } 185 }
186 } 186 }
187 visitor->Done(); 187 visitor->Done();
188 } 188 }
189 } // namespace 189 } // namespace
190 190
191 BlobAsyncTransportStrategy::RendererMemoryItemRequest:: 191 BlobAsyncTransportStrategy::RendererMemoryItemRequest::
192 RendererMemoryItemRequest() 192 RendererMemoryItemRequest()
193 : browser_item_index(0), browser_item_offset(0), received(false) {} 193 : browser_item_index(0), browser_item_offset(0) {}
194 194
195 BlobAsyncTransportStrategy::BlobAsyncTransportStrategy() 195 BlobAsyncTransportStrategy::BlobAsyncTransportStrategy()
196 : error_(BlobAsyncTransportStrategy::ERROR_NONE), total_bytes_size_(0) {} 196 : error_(BlobAsyncTransportStrategy::ERROR_NONE), total_bytes_size_(0) {}
197 197
198 BlobAsyncTransportStrategy::~BlobAsyncTransportStrategy() {} 198 BlobAsyncTransportStrategy::~BlobAsyncTransportStrategy() {}
199 199
200 // if total_blob_size > |memory_available| (say 400MB) 200 // Initializes the transport strategy for file requests.
201 // Request all data in files 201 void BlobAsyncTransportStrategy::InitializeForFileRequests(
202 // (Segment all of the existing data into 202 size_t max_file_size,
203 // file blocks, of <= |max_file_size|) 203 const std::string& uuid,
204 // else if total_blob_size > |max_ipc_memory_size| (say 150KB) 204 uint64_t blob_total_size,
205 // Request all data in shared memory 205 const std::vector<DataElement>& blob_item_infos,
206 // (Segment all of the existing data into 206 BlobDataBuilder* builder) {
207 // shared memory blocks, of <= |max_shared_memory_size|) 207 DCHECK(requests_.empty());
208 // else 208 total_bytes_size_ = blob_total_size;
209 // Request all data to be sent over IPC 209 ComputeHandleSizes(total_bytes_size_, max_file_size, &file_handle_sizes_);
210 void BlobAsyncTransportStrategy::Initialize( 210 FileStorageStrategy strategy(&requests_, builder);
211 ForEachWithSegment(blob_item_infos, static_cast<uint64_t>(max_file_size),
212 &strategy);
213 }
214
215 void BlobAsyncTransportStrategy::InitializeForSharedMemoryRequests(
216 size_t max_shared_memory_size,
217 const std::string& uuid,
218 uint64_t blob_total_size,
219 const std::vector<DataElement>& blob_item_infos,
220 BlobDataBuilder* builder) {
221 DCHECK(requests_.empty());
222 DCHECK(blob_total_size <= std::numeric_limits<size_t>::max());
223 total_bytes_size_ = blob_total_size;
224 ComputeHandleSizes(total_bytes_size_, max_shared_memory_size,
225 &shared_memory_handle_sizes_);
226 SharedMemoryStorageStrategy strategy(max_shared_memory_size, &requests_,
227 builder);
228 ForEachWithSegment(blob_item_infos,
229 static_cast<uint64_t>(max_shared_memory_size), &strategy);
230 }
231
232 void BlobAsyncTransportStrategy::InitializeForIPCTransportation(
211 size_t max_ipc_memory_size, 233 size_t max_ipc_memory_size,
212 size_t max_shared_memory_size,
213 size_t max_file_size,
214 uint64_t disk_space_left,
215 size_t memory_available,
216 const std::string& uuid, 234 const std::string& uuid,
217 const std::vector<DataElement>& blob_item_infos) { 235 uint64_t blob_total_size,
218 DCHECK(handle_sizes_.empty()); 236 const std::vector<DataElement>& blob_item_infos,
237 BlobDataBuilder* builder) {
219 DCHECK(requests_.empty()); 238 DCHECK(requests_.empty());
220 DCHECK(!builder_.get()); 239 // We don't ssegment anything, and just request the memory items directly
221 builder_.reset(new BlobDataBuilder(uuid)); 240 // in IPC.
222 error_ = BlobAsyncTransportStrategy::ERROR_NONE;
223
224 size_t memory_items = 0;
225 base::CheckedNumeric<uint64_t> total_size_checked = 0;
226 for (const auto& info : blob_item_infos) {
227 if (!IsBytes(info.type())) {
228 continue;
229 }
230 total_size_checked += info.length();
231 ++memory_items;
232 }
233
234 if (!total_size_checked.IsValid()) {
235 DVLOG(1) << "Impossible total size of all memory elements.";
236 error_ = BlobAsyncTransportStrategy::ERROR_INVALID_PARAMS;
237 return;
238 }
239
240 total_bytes_size_ = total_size_checked.ValueOrDie();
241
242 // See if we have enough memory.
243 if (total_bytes_size_ >
244 disk_space_left + static_cast<uint64_t>(memory_available)) {
245 error_ = BlobAsyncTransportStrategy::ERROR_TOO_LARGE;
246 return;
247 }
248
249 // If we're more than the available memory, then we're going straight to disk.
250 if (total_bytes_size_ > memory_available) {
251 if (total_bytes_size_ > disk_space_left) {
252 error_ = BlobAsyncTransportStrategy::ERROR_TOO_LARGE;
253 return;
254 }
255 ComputeHandleSizes(total_bytes_size_, max_file_size, &handle_sizes_);
256 FileStorageStrategy strategy(&requests_, builder_.get());
257 ForEachWithSegment(blob_item_infos, static_cast<uint64_t>(max_file_size),
258 &strategy);
259 return;
260 }
261
262 if (total_bytes_size_ > max_ipc_memory_size) {
263 // Note: The size must be <= std::numeric_limits<size_t>::max(). Otherwise
264 // we are guarenteed to be caught by the if statement above,
265 // |total_bytes_size_ > memory_available|.
266 ComputeHandleSizes(total_bytes_size_, max_shared_memory_size,
267 &handle_sizes_);
268 SharedMemoryStorageStrategy strategy(max_shared_memory_size, &requests_,
269 builder_.get());
270 ForEachWithSegment(blob_item_infos,
271 static_cast<uint64_t>(max_shared_memory_size),
272 &strategy);
273 return;
274 }
275
276 // Since they can all fit in IPC memory, we don't need to segment anything,
277 // and just request them straight in IPC.
278 size_t items_length = blob_item_infos.size(); 241 size_t items_length = blob_item_infos.size();
242 total_bytes_size_ = blob_total_size;
279 for (size_t i = 0; i < items_length; i++) { 243 for (size_t i = 0; i < items_length; i++) {
280 const auto& info = blob_item_infos.at(i); 244 const auto& info = blob_item_infos.at(i);
281 if (!IsBytes(info.type())) { 245 if (!IsBytes(info.type())) {
282 builder_->AppendIPCDataElement(info); 246 builder->AppendIPCDataElement(info);
283 continue; 247 continue;
284 } 248 }
285 BlobAsyncTransportStrategy::RendererMemoryItemRequest request; 249 BlobAsyncTransportStrategy::RendererMemoryItemRequest request;
286 request.browser_item_index = i; 250 request.browser_item_index = i;
287 request.browser_item_offset = 0; 251 request.browser_item_offset = 0;
288 request.message.request_number = requests_.size(); 252 request.message.request_number = requests_.size();
289 request.message.transport_strategy = IPCBlobItemRequestStrategy::IPC; 253 request.message.transport_strategy = IPCBlobItemRequestStrategy::IPC;
290 request.message.renderer_item_index = i; 254 request.message.renderer_item_index = i;
291 request.message.renderer_item_offset = 0; 255 request.message.renderer_item_offset = 0;
292 request.message.size = info.length(); 256 request.message.size = info.length();
293 requests_.push_back(request); 257 requests_.push_back(request);
294 builder_->AppendFutureData(info.length()); 258 builder->AppendFutureData(info.length());
295 } 259 }
296 } 260 }
297 261
298 /* static */ 262 /* static */
299 bool BlobAsyncTransportStrategy::ShouldBeShortcut( 263 bool BlobAsyncTransportStrategy::ShouldBeShortcut(
300 const std::vector<DataElement>& elements, 264 const std::vector<DataElement>& elements,
301 size_t memory_available) { 265 size_t memory_available) {
302 base::CheckedNumeric<size_t> shortcut_bytes = 0; 266 base::CheckedNumeric<size_t> shortcut_bytes = 0;
303 for (const auto& element : elements) { 267 for (const auto& element : elements) {
304 DataElement::Type type = element.type(); 268 DataElement::Type type = element.type();
(...skipping 20 matching lines...) Expand all
325 bool has_extra_segment = (total_memory_size % max_segment_size) > 0; 289 bool has_extra_segment = (total_memory_size % max_segment_size) > 0;
326 segment_sizes->reserve(total_max_segments + (has_extra_segment ? 1 : 0)); 290 segment_sizes->reserve(total_max_segments + (has_extra_segment ? 1 : 0));
327 segment_sizes->insert(segment_sizes->begin(), total_max_segments, 291 segment_sizes->insert(segment_sizes->begin(), total_max_segments,
328 max_segment_size); 292 max_segment_size);
329 if (has_extra_segment) { 293 if (has_extra_segment) {
330 segment_sizes->push_back(total_memory_size % max_segment_size); 294 segment_sizes->push_back(total_memory_size % max_segment_size);
331 } 295 }
332 } 296 }
333 297
334 } // namespace storage 298 } // namespace storage
OLDNEW
« no previous file with comments | « storage/browser/blob/blob_async_transport_strategy.h ('k') | storage/browser/blob/blob_data_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698